Android App Hooking with Frida(2)
- Mobile/Android
- 2018. 4. 6. 17:58
이번 포스팅에서는지난시간에 이어서 Frida를 사용한 android app hooking에 대하여 다루도록 하겠습니다.
(도구 설치와 같은 기초 지식은 다루지 않습니다.)
문제파일은 아래 경로를 통하여 다운받을 수 있습니다.
https://github.com/OWASP/owasp-mstg/tree/master/Crackmes
분석환경
OS: Windows10
Tools: Frida, Frida-server, adb, Python3.6, Genymotion
문제파일(UnCrackable-Level2.apk)을 다운로드하여 설치합니다.
[그림 1 apk설치]
앱 설치 후 실행 시 루팅 탐지가 동작하며 ok버튼을 클릭하면 앱이 강제로 종료됩니다.
[그림 2 루팅탐지]
루팅탐지는 Level1 문제풀이때 설명하였으니 넘어가도록 하겠습니다.
문제파일의 MainActivity 살펴보면 Secret String입력 값에 따른 성공 및 실패 로직을 확인할 수 있습니다.
[그림 3 verify 함수 분석]
실제 CodeCheck 클래스를 살펴보면 bar함수에 Secret String이 전달되어 유효성을 체크하는 것을 확인할 수 있습니다.
[그림 4 CodeCheck bar 분석]
실제 해당 함수는 libfoo.so 라이브러리에서 찾을 수 있습니다.
[그림 5 libfoo.so 라이브러리 load 확인]
그럼 실제 해당 라이브러리 파일을 디스어셈블러(ida)를 사용하여 분석해보도록 하겠습니다.
genymotion의 경우 Intel x86으로 동작하게됩니다. 따라서 라이브러리 파일 분석 시 x86폴더 아래에 존재하는 libfoo.so 파일을 분석하도록 하겠습니다.
[그림 6 libfoo.so 분석]
함수를 분석하다보면 eax, 17h 를 비교하여 strncmp함수를 호출하는 영역으로 분기하는 구간을 확인할 수 있습니다.
17h는 십진수로 23이고 문자열의 길이가 23이면 strncmp함수를 호출하는 영역으로 넘어가도록 동작합니다.
우리는 여기서 Secret String의 길이가 23이라는 것을 파악할 수 있습니다.
[그림 7 b함수 분석]
strncmp함수는 문자열을 비교하여 그 결과를 반환하는 함수입니다.
Secret String을 입력받아 비교하여 결과를 반환하는 동작을 수행합니다.
그럼 우리는 strncmp함수의 인수를 출력하여 Secret String을 확인할 수 있을것입니다.
그럼 strncmp 함수를 후킹하여 실제 Secret String을 출력하는 코드를 작성하도록 하겠습니다.
Module.enumerateImportsSync() 를 이용하여 libfoo.so 라이브러리에 존재하는 함수 중 strncmp함수의 주소값을 얻어내고 hooking을 수행하여 Secret String을 얻어냅니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | import frida, sys def on_message(message, data): if message['type'] == 'send': print("[*] {0}".format(message['payload'])) else: print(message) PACKAGE_NAME = "sg.vantagepoint.uncrackable2" 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"); } var strncmp = undefined; func = Module.enumerateImportsSync("libfoo.so"); for(i = 0; i < func.length; i++) { if(func[i].name == "strncmp") { strncmp = func[i].address; break; } } Interceptor.attach(strncmp, { onEnter: function (args) { if(args[2].toInt32() == 23 && Memory.readUtf8String(args[0],23) == "01234567890123456789012") { console.log("[*] Secret string at " + args[1] + ": " + Memory.readUtf8String(args[1],23)); } }, }); console.log("[*] Intercepting strncmp"); }); """ try: device = frida.get_usb_device(timeout=10) pid = device.spawn([PACKAGE_NAME]) process = device.attach(pid) device.resume(pid) script = process.create_script(jscode) script.on('message',on_message) print('[*] Running Hook') script.load() sys.stdin.read() except Exception as e: print(e) | cs |
[그림 8 hooking code]
참고 : https://www.codemetrix.net/hacking-android-apps-with-frida-3/
'Mobile > Android' 카테고리의 다른 글
Android App Hooking with Frida(3) (1) | 2019.01.07 |
---|---|
Android App Hooking with Frida(1) (0) | 2018.02.26 |
이 글을 공유하기