ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • FRIDA Hooking (OWASP - UnCrackable2)
    Mobile/Frida 2019. 12. 22. 01:30

    OWASP-mstg : https://github.com/OWASP/owasp-mstg/tree/master/Crackmes

     

    OWASP Mobile Crack 트레이닝 중 Level2 문제풀이이다.

    문제풀이는 FRIDA를 이용할 것이며, Level1 문제풀이는 여기에서 확인할 수 있다.

     


    UnCrackable2_exit( ) Hook

    adb install을 통해 App을 디바이스에 설치해주고 실행 시켜보도록 하자

     

    [그림 1] Root Detected!

    루팅된 디바이스일 경우, 위와 같이 "Root Detected!" 경고창이 팝업되면서 [OK]를 누르면 App이 종료된다.

    따라서, App이 종료되는 루틴을 먼저 확인하고 루팅된 디바이스에서도 App을 사용할 수 있게끔 해줘야 한다.

     

    [그림 2] exit( ) 루틴

    MainActivity를 보면, b.a( ) / b.b( ) / b.c( )에서 루팅 여부를 확인하고 결과적으로 exit( )로 App을 종료하고 있다.

    후킹포인트를 다양하게 잡을 수 있는데, exit( )이 동작하지 않도록 하는게 가장 효율적인 방법으로 보인다.

    Java.perform(function()
    {
        console.log("[*] HOOK START");
        
        var system = Java.use("java.lang.System");
        system.exit.implementation = function()
        {
            console.log("[+] exit() Hook!");
        }
        
    });

    exit( )는 java.lang.System클래스에 속한 메소드이기 때문에 Java.use( )로 System클래스를 로드해준다.

    그리고 exit( )가 실행되면 로그메시지만 찍어주고 종료되도록 재정의 해줬다.

     


    Secret String Leak

    [그림 3] Secret String 입력

    exit( )를 우회하면 App에서 Secret String을 입력받는다.

     

    [그림 4] verify( )

    우리가 입력한 값은 v4변수에 저장되고, m.a( )에서 Secret String인지 확인하는 절차를 거친다.

    만약 Secret String이 맞으면 "Success!", 틀리면 "Nope..."이 팝업된다.

     

    [그림 5] m.a( )

    m.a( )를 확인해보면 우리가 입력한 문자열을 bar( )로 전달해주는데, bar( )는 Native에 정의된 메소드이다.

    따라서, App에 로드된 라이브러리에서 bar( )가 어떻게 동작하는지 확인해야 한다.

     

    [그림 6] loadLibrary( )

    MainActivity에서 System.loadLibrary("foo")libfoo.so를 로드해주는 것을 확인할 수 있다.

     

    [그림 7] bar( )

    libfoo.so를 IDA로 열어보면 위와 같이 실제 bar( )를 확인할 수 있는데, 빨간박스에서 검증절차가 이루어지고 있다.

    먼저 입력한 길이 값이 23Byte가 맞는지 확인하고, strncmp( )로 v7과 일치하는지 검사한다.

     

    v7값은 BSS영역에 저장된 고정문자열이라 눈으로 확인이 가능하지만, FRIDA를 이용하는 것이 우리의 목적이니까

    한번 후킹을 통해서 Secret String을 추출해보도록 하자

     

    function bar_hook()
    {
        var strncmp = Module.findExportByName("libfoo.so","strncmp");
        
        Interceptor.attach(strncmp,
        {
            onEnter: function(args)
            {
                var input = args[0].readUtf8String();
                var str = args[1].readUtf8String();
                if(input == "12345678901234567890123")
                {
                    console.log("[+] strncmp() Hook IN");
                    console.log("[*]Input: " + input);
                    console.log("[*]Str: " + str);
                }
            },
            onLeave: function(retVal)
            {
            }
        });
    }

    후킹 포인트는 strncmp( )로 잡고 입력한 문자열이 "12345678901234567890123"(23Byte)일 경우, 인자들을 출력하도록 스크립트를 작성하였다.

     

    [그림 8] Secret String Leak!

    후킹 스크립트를 실행하고 "12345678901234567890123"를 입력하면 strncmp( )의 비교값인 Secret String이 출력된다.

     

    [그림 9] Success!


    Hooking Script

    import frida,sys
    
    def on_message(message, data):
        print("{} -> {}".format(message,data))
    
    hook_code = """
    Java.perform(function()
    {
        console.log("[*] HOOK START");
        
        var system = Java.use("java.lang.System");
        system.exit.implementation = function()
        {
            console.log("[+] exit() Hook!");
        }
        
        bar_hook();
    
    });
    
    function bar_hook()
    {
        var strncmp = Module.findExportByName("libfoo.so","strncmp");
        
        Interceptor.attach(strncmp,
        {
            onEnter: function(args)
            {
                var input = args[0].readUtf8String();
                var str = args[1].readUtf8String();
                
                if(input == "12345678901234567890123")
                {
                    console.log("[+] strncmp() Hook IN");
                    console.log("[*]Input: " + input);
                    console.log("[*]Str: " + str);
                }
            },
            onLeave: function(retVal)
            {
            }
        });
    } 
    """
    
    package = "owasp.mstg.uncrackable2"
    device = frida.get_usb_device(timeout=10)
    pid = device.spawn([package])
    process = device.attach(pid)
    device.resume(pid)
    
    script = process.create_script(hook_code)
    script.on("message",on_message)
    script.load()
    sys.stdin.read()

    'Mobile > Frida' 카테고리의 다른 글

    FRIDA Cheat Sheet  (8) 2020.03.02
    Anti-Debugging 우회 ( ptrace 선점 )  (1) 2020.02.29
    Fridump (메모리 덤프)  (1) 2019.12.19
    Unity Game App Hacking (궁수의 전설)  (14) 2019.12.18
    Runtime Memory Patch  (2) 2019.12.17

    댓글

Designed by Tistory.