Frida 자료를 찾던 중 좋은 실습앱이 있어 Frida를 통해 Uncrackable1 앱 우회를 하겠습니다



앱 실행 시, 루팅탐지 후 종료하게 됩니다


디컴파일 후에 루팅 탐지 로직을 확인하면 다음과 같습니다



sg.vantagepoint.a.c.class에서 루팅을 확인하는데 총 3번에 걸쳐서 탐지를 합니다


해당 실습앱이 올라와 있는 사이트에서는 exit 함수를 후킹하여 exit함수 호출 시 아무런 동작도 하지 않도록 하는데, activity가 떠있는 상태에서는 굳이 루팅체크로직을 일일히 후킹하지 않더라도 이런 방법으로도 우회가 가능하네요 :)


그럼 exit를 후킹하여 앱종료 명령 시, 무시하는 코드를 작성하도록 합니다


import sys
import frida

def on_message(message,data):
    print "[%s] -> %s" % (message, data)


PACKAGE_NAME = "sg.vantagepoint.uncrackable1"

jscode = """
    Java.perform(function() {
        console.log("[*] Hooking calls to System.exit");
        exitClass = Java.use("java.lang.System");
        exitClass.exit.implementation = function() {
            console.log("[*] System.exit called");
        }

     
    });
"""
   
try:
    device = frida.get_usb_device(timeout=10)
    pid = device.spawn([PACKAGE_NAME]) 
    print("App is starting ... pid : {}".format(pid))
    process = device.attach(pid)
    device.resume(pid)
    script = process.create_script(jscode)
    script.on('message',on_message)
    print('[*] Running Frida')
    script.load()
    sys.stdin.read()
except Exception as e:
    print(e)


exit호출 시 콘솔에 로그 출력만 하도록 후킹을 걸고 String을 입력 후 버튼을 눌러보겠습니다




문자열 비교 후 알람을 출력합니다 다시 디컴파일 된 소스코드를 확인해보면



분기문이 보입니다 sg.vantagepoint.a.a.class에서 문자열을 비교하는 것 같습니다



arrayOfByte2에 찾아야할 문자열이 암호화 후 저장되어 있고, sg.vantagepoint.a.a.a를 호출하여 arrayOfByte2를 복호화하여 입력값과 비교하는 것 같습니다


위 화면의 네모박스에 있는 스트링은 AES복호화할 때 사용하는 키값인 것 같네요


sg.vantagepoint.a.a.class를 확인해보니 맞는 것 같습니다 


이 class에서 복호화된 문자열을 return하므로 해당 함수를 후킹하여 복호화된 문자열을 추출하도록 하겠습니다


import sys
import frida
def on_message(message,data):
    print "[%s] -> %s" % (message, data)

PACKAGE_NAME = "sg.vantagepoint.uncrackable1"
jscode = """
    Java.perform(function() {
        console.log("[*] Hooking calls to System.exit");
        exitClass = Java.use("java.lang.System");
        exitClass.exit.implementation = function() {
            console.log("[*] System.exit called");
        }
     
  a = Java.use("sg.vantagepoint.a.a");
        a.a.implementation = function(a,b){
            console.log("[*]Hooking in a.Class");
            retVal = this.a(a,b);
            passcode='';
            for(i=0;i<retVal.length;i++){
                passcode+=String.fromCharCode(retVal[i]);
            }
            console.log("Secret key :"+passcode);
            return retVal;
        }
    });
"""
   
try:
    device = frida.get_usb_device(timeout=10)
    pid = device.spawn([PACKAGE_NAME]) 
    print("App is starting ... pid : {}".format(pid))
    process = device.attach(pid)
    device.resume(pid)
    script = process.create_script(jscode)
    script.on('message',on_message)
    print('[*] Running Frida')
    script.load()
    sys.stdin.read()
except Exception as e:
    print(e)


위에서 작성한 exit()함수 후킹 소스에 덧붙여 sg.vantagepoint.a.a.a를 후킹하는 스크립트를 추가합니다


단순하게 기존 함수의 리턴값을 받아 출력하는 함수입니다


실행시켜 보면 복호화된 문자열이 출력되는 것을 볼 수 있습니다 :)




'Mobile' 카테고리의 다른 글

INSTALL FAILED TEST_ONLY  (1) 2018.02.06
Uncrackable3 - frida  (0) 2018.01.30
Android에서 호출한 Class/Method 확인하기 - with Frida  (0) 2018.01.26
Uncrackable2 - Radare2  (0) 2018.01.23
Android Anti-Debugging  (1) 2018.01.23

+ Recent posts