1. 실습 환경
(1) 삼성 갤럭시 S7 : 버전(안드로이드 8.0), 루팅상태, frida-server 실행,
(2) windows 10 pro : frida 설치, python 3.8(64bit)
(3) APP 파일 : Uncrackable-Level1.apk
2. 코드 분석
앱을 실행결과 루팅 탐지 및 차단을 하고 있다.
루팅 탐지 우회 방법은 bling-son.tistory.com/82 참고
루팅 탐지 우회 소스 :
import frida, sys
def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message)
PACKAGE_NAME = "owasp.mstg.uncrackable2"
jscode= """
setImmediate(function(){
Java.perform(function(){
console.log("[*] Hooking System.exit");
var exitBypass = Java.use("java.lang.System");
exitBypass.exit.implementation = function() {
console.log("[*] System.exit Success");
}
})
});
"""
try:
print('[*] By Daze !!!')
print('')
device = frida.get_usb_device(timeout=5)
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 Hook')
script.load()
sys.stdin.read()
except Exception as e:
print(e)
Enter the Secret String에 임의의 글자 및 문자 입력 후 VERIFY 버튼 클릭해 보았다.
JEB 도구를 이용하여 apk 파일을 분석하여 Secret String 실행 함수 부분을 확인하였다.
함수 확인 결과 성공 할 시에는 Success! This is the correct secret. 알림이 뜬다는 것을 확인하였다.
CodeCheck 클래스 확인 결과 bar 함수에 Secret String에 입력한 문자가 전달되어 유효성을 체크하는걸 확인할 수 있다.
실제 해당 함수는 foo라는 so파일에 있는것을 확인
apk tool 도구를 이용하여 UnCrackable-Level2.apk를 디컴파일 한다.
디컴파일하여 생성된 폴더 내 lib 폴더에 접근시 여러 버전의 폴더를 확인할 수 있다.
휴대폰에서 실행되는 폴더로 접근한다.
휴대폰 버전과 맞는 폴더에 접근하면 so 파일을 확인할 수 있다.
현재 앱은 테스트 앱이라 so파일이 libfoo.so 파일 하나지만 실제 앱에서는 더 많은 so 파일이 존재한다.
IDA pro 도구를 이용하여 라이브러리를 정적 분석을 한다.
Exports 탭을 클릭 후 CodeCheck 클래스에 접근하여 bar 함수를 확인한다.
클래스 클릭후 F5 버튼 눌러서 코드 화면으로 이동한다.
분석중 W0, #0x17에서 플래그가 0이 아니면 there로 분기한다. 아니면 다음 명령어를 수행한다.
※ ARM 어셈블리어 명령어 참고 URL : egloos.zum.com/orangetigger/v/359478
0x17은 십진수로 23이고 문자열의 길이가 23이면 strncmp함수를 호출하는 영역으로 넘어가도록 동작합니다.
※ strcmp 함수 참고 URL : blockdmask.tistory.com/391
strncmp 함수 : 문자열 비교 후 결과값 반환
#include <string.h>
int strncmp(const char *string1, const char *string2, size_t count);
// Return 값
// string1 < string2 인 경우 0보다 작은 수
// string1 = string2 인 경우 0
// string1 > string2 인 경우 0보다 큰 수
3. Frida Hooking 코드 작성
strcmp함수의 인수를 출력하여 Secret String을 확인한다.
strncmp함수 후킹 후 실제 Secret String을 출력하는 코드 작성하겠다.
import frida, sys
def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message)
PACKAGE_NAME = "owasp.mstg.uncrackable2"
jscode= """
console.log("[*] Start Hooking");
Java.perform(function() {
console.log("[*] Hooking calls to System.exit");
var exitClass = Java.use("java.lang.System");
exitClass.exit.implementation = function() {
console.log("[*] System.exit called");
}
var strncmp = undefined;
var func = Module.enumerateImportsSync("libfoo.so");
for(var 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) == "12345678901234567890123") {
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])
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 Hook')
script.load()
sys.stdin.read()
except Exception as e:
print(e)
4. Frida Hooking 코드 실행
후킹 코드가 설치된 폴더경로에서 CMD를 이용하여 실행한다.
실행 명령어 : python [실행파일 명].py
코드에 입력한 23자리 string 값을 그대로 Secret String에 입력하면 CMD 화면에 "[*] Secret string at 0x7fc9f5da70: Thanks for all the fish" 출력된다.
Secret String 입력에 CMD에 출력된 "Thanks for all the fish" 입력시 정상 알림 확인한다.
'보안 > Mobile_APP' 카테고리의 다른 글
[APP Hooking] Android 모바일 앱(Uncrackable-Level1.apk) 후킹_Level1 (0) | 2020.12.02 |
---|---|
[앱 진단] 모바일 애플리케이션 보안 취약점 점검(디바이스 진단) (0) | 2020.08.11 |