본문 바로가기

보안/Mobile_APP

[APP Hooking] Android 모바일 앱(UnCrackable-Level2.apk) 후킹_Level2

반응형

1. 실습 환경

(1) 삼성 갤럭시 S7 : 버전(안드로이드 8.0), 루팅상태, frida-server 실행, 

(2) windows 10 pro : frida 설치, python 3.8(64bit)

(3) APP 파일 : Uncrackable-Level1.apk

 

OWASP/owasp-mstg

The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering. - OWASP/owasp-mstg

github.com

2. 코드 분석

앱을 실행결과 루팅 탐지 및 차단을 하고 있다.

Uncrackable Level 2 앱 클릭
실행 결과 루팅 탐지 확인

 

루팅 탐지 우회 방법은 bling-son.tistory.com/82 참고

 

[APP Hooking] Android 모바일 앱(Uncrackable-Level1.apk) 후킹_Level1

1. 실습 환경 (1) 삼성 갤럭시 S7 : 버전(안드로이드 8.0), 루팅상태, frida-server 실행, (2) windows 10 pro : frida 설치, python 3.8(64bit) (3) APP 파일 : Uncrackable-Level1.apk OWASP/owasp-mstg The Mob..

bling-son.tistory.com

루팅 탐지 우회 소스 : 

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)

Rooting_Bypass2.py
0.00MB

 

Enter the Secret String에 임의의 글자 및 문자 입력 후 VERIFY 버튼 클릭해 보았다.

Secret String 입력 틀렸을 때 알림

JEB 도구를 이용하여 apk 파일을 분석하여 Secret String 실행 함수 부분을 확인하였다.

Secret String 실행 함수

함수 확인 결과 성공 할 시에는 Success! This is the correct secret. 알림이 뜬다는 것을 확인하였다.

CodeCheck 클래스 확인 결과 bar 함수에 Secret String에 입력한 문자가 전달되어 유효성을 체크하는걸 확인할 수 있다.

CodeCheck 클래스
CodeCheck 클래스에서 입력받은 구문을 verify에서 유효성 체크

실제 해당 함수는 foo라는 so파일에 있는것을 확인

loadLibrary는 foo라는 so 파일

apk tool 도구를 이용하여 UnCrackable-Level2.apk를 디컴파일 한다.

디컴파일하여 생성된 폴더 내 lib 폴더에 접근시 여러 버전의 폴더를 확인할 수 있다.

휴대폰에서 실행되는 폴더로 접근한다. 

lib 폴더 내 여러버전의 폴더

휴대폰 버전과 맞는 폴더에 접근하면 so 파일을 확인할 수 있다.

현재 앱은 테스트 앱이라 so파일이 libfoo.so 파일 하나지만 실제 앱에서는 더 많은 so 파일이 존재한다.

loadLibrary인 libfoo.so 파일 확인

IDA pro 도구를 이용하여 라이브러리를 정적 분석을 한다.

CodeCheck_bar 부분 확인

Exports 탭을 클릭 후 CodeCheck 클래스에 접근하여 bar 함수를 확인한다.

클래스 클릭후 F5 버튼 눌러서 코드 화면으로 이동한다.

Exports 화면

 

 분석중 W0, #0x17에서 플래그가 0이 아니면 there로 분기한다. 아니면 다음 명령어를 수행한다. 

※ ARM 어셈블리어 명령어 참고 URL : egloos.zum.com/orangetigger/v/359478

0x17은 십진수로 23이고 문자열의 길이가 23이면 strncmp함수를 호출하는 영역으로 넘어가도록 동작합니다.

※ strcmp 함수 참고 URL : blockdmask.tistory.com/391

.strncmp 함수 부분

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)

SecretStringKEY.py
0.00MB

 

4. Frida Hooking 코드 실행 

후킹 코드가 설치된 폴더경로에서 CMD를 이용하여 실행한다.

실행 명령어 : python [실행파일 명].py

코드에 입력한 23자리 string 값을 그대로 Secret String에 입력하면 CMD 화면에 "[*] Secret string at 0x7fc9f5da70: Thanks for all the fish" 출력된다.

모바일에 코드에 입력한 23자리 입력
코드에 입력한 23자리 입력시 Secret String값 출력

Secret String 입력에 CMD에 출력된 "Thanks for all the fish" 입력시 정상 알림 확인한다.

Success! 알림 확인

 

반응형