Android 분석 중, .so파일은 보통 IDA를 이용해서 분석했는데 좋은 툴이 있어 소개드립니다
Radare2라는 툴인데 IDA CLI버전 느낌이네요. 가볍기도 하고 GDB + IDA느낌입니다.(오늘 처음 사용해봐서 잘모르지만 느낌은)
http://radare.org/r/ - Radare2공홈입니다
https://radare.gitbooks.io/radare2book/content/ - Radare2 가이드 페이지입니다
Windows 버전과 리눅스 버전이 있는데, 리눅스는 github에서 받으시면 됩니다
#git clone https://github.com/radare/radare2.git
#cd radare/sys
#./install.sh
앱 실행시 다음화면과 같습니다. 루팅 탐지 로직을 확인하기 위해 디컴파일 후에 소스코드를 확인하겠습니다
init()함수 후에 b.a , b.b , b.c함수를 이용해 루팅탐지를 합니다.
소스코드를 보니 init함수가 jni를 이용하여 작성된 so파일이니 r2를 이용해 분석하겠습니다
iE명령을 이용하여 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar, Java_sg_vantagepoint_uncrackable2_MainActivity_init 함수를 확인하였습니다
명령어를 이용해 MainActivity_init함수를 확인할 수 있습니다
fork()함수를 이용하여 다른 작업을 하는 것 같습니다
[]>s 0x000008b8
[]>pd $r @
ptrace를 이용한 anti-debug 로직인 것 같네요
Anti-Debugging 및 루팅탐지를 우회하기 위해 Frida를 이용하기로 합니다.
import sys
import frida
def on_message(message,data):
print "[%s] -> %s" % (message, data)
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");
}
});
"""
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() 함수를 후킹하여 앱 종료를 막는 스크립트입니다
스크립트 실행 시, 루팅탐지가 되지만 exit함수가 후킹되어 앱이 종료되지 않습니다
다시 복호화된 소스를 확인합니다
위 캡처화면의 분기문에서 스트링을 검사한 후에 Alert창을 띄우는 것을 확인하였으며, this.m.a의 로직을 살펴보면 다음과 같습니다
jni파일의 bar함수에서 스트링 검사를 진행하여 결과값을 리턴받아 판별하는 소스입니다
상단의 radare2를 이용하여 libfoo.so파일을 살펴본 결과 CodeCheck_bar를 확인할 수 있었고 해당 함수를 디스어셈블하면 다음과 같은 화면이 출력됩니다
0x00000c88부분에 strncmp함수를 확인할 수 있습니다
조금더 올라가서 0x00000c74부분을 살펴보면
cmp w0,0x17
b.ne 0xc90
를 확인할 수 있고 0x17글자수를 검증한 후 기존의 문자열과 입력된 문자열을 비교합니다
Frida를 이용해서 strncmp를 후킹하여 파라미터를 출력하는 방법으로 secret key를 확인하겠습니다
import sys
import frida
def on_message(message,data):
print "[%s] -> %s" % (message, data)
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 strcmp=undefined;
module=Module.enumerateImportsSync("libfoo.so");
for(i=0;i<module.length;i++){
if(module[i].name=="strncmp"){
strcmp=module[i].address;
break;
}
}
Interceptor.attach(strcmp, {
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));
}
},
});
});
"""
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)
코드 실행 시, secret key를 확인할 수 있습니다
※Radare2에서 Ida와 동일하게 스페이스 바를 이용하여 그래프 모드가 가능합니다
출처 : https://www.codemetrix.net/hacking-android-apps-with-frida-2/
'Mobile' 카테고리의 다른 글
Uncrackable1 - frida (4) | 2018.01.30 |
---|---|
Android에서 호출한 Class/Method 확인하기 - with Frida (0) | 2018.01.26 |
Android Anti-Debugging (1) | 2018.01.23 |
Instant Run(Split apk) (1) | 2018.01.10 |
Frida를 이용한 앱 실행 중 로드하는 클래스 확인 (2) | 2018.01.03 |