Study/App

[App]Uncrackable3

seomj 2022. 10. 30. 13:05

해당 앱을 실행하면 경고와 함께 OK를 누르면 앱이 종료된다.

 

기존 uncrackable1과 2와 동일하게 exit() 후킹을 시도했으나 다음과 같은 결과가 나온다.


분석

MainActivity를 확인해보자.

해당 부분을 보면 106번째 줄에서 init()함수에 xorkey 값으로 "pizzapizzapizzapizz"를 인자로 가지고 간다.

그리고 104번째 줄에서는 verifyLibs()함수가 실행된다.

 

verifyLibs()라는 함수가 있고 해당 함수에서 libfoo.so 파일을 불러오는 것을 확인할 수 있다.

해당 함수는 무결성 검증 로직이다.

libfoo.so 파일의 crc를 저장하고, apk가 실행되는 실제 환경에서 llibfoo.so 파일을 찾아 crc 값을 비교한다.

여기서 값이 다르다면 tampered 값을 31337로 지정한다.

 

다시 onCreate()함수로 돌아가서 더 살펴보자.

위에서 잠깐 언급한 부분인 120번째 줄에서는 디버깅을 탐지하고 있다.

126번째 RootDetection과 IntergrityCheck, tampered를 통해 루팅과 변조 검사를 하고 있다.

 

onCreate() 138번째 줄에서 CodeCheck()를 하고 있다.

여기서는 native 메소드인 bar()의 결과값을 반환한다.


libfoo.so

libfoo.so 파일을 확인해보자.

adb shell getprop ro.product.cpu.abi 를 입력하면 알 수 있다.

나는 기존에 uncrackable2에서 실행하였고 x86인 것을 알고 있기에 생략하겠다.

 

x86

이로 시도했으나 삽질만 함....

알고보니 섹션 정보들이 잘 파싱이 되어 있지 않고 라이브러리 또한 ....

 

그래서 x86_64로 분석을 진행했다.

 

x86_64

ctrl + s 를 누르면 .init_array가 있다.

.init_array 섹션은 프로그램 시작 전 호출할 함수 주소를 담고 있다.

sub_38A0이 entry point로 실행된다.

 

sub_38A0에서 start_routine을 스레드로 실행시킨다.

 

start_routine에서는 strstr함수에서 'frida'나 'xposed'가 v3에 존재할 경우, 즉 /proc/self/maps 메모리에 로드된 문자열에 'frida'나 'xposed'가 있을 경우에 "Tampering detected! Treminating..."을 출력한다.

그 후 goodbye()를 실행한다.

 

goodbye()는 exit()를 호출한다.

 

native 메소드인 init도 확인해보자.

sub_3910()을 실행하고 있다.

 

sub_3910()에서는 ptrace()를 이용해 프로세스의 상태값을 가져와서 비교하며, 현재 프로그램이 디버깅 중인지 탐지한다.

아직 모두 이해하지 못 함

 

CodeCheck의 native bar()

해당 부분이 xorkey로 뭔가 하는 부분이라고 하던데 잘 모르겠음...


풀이

strstr 후킹

여기서는 strstr을 후킹하여 탐지를 우회할 수 있다.

 

첫 번째는 'frida'가 있을 경우, 다른 문자열로 바꾸는 코드이다.

Java.perform(function() {
    console.error('\n')

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

    Interceptor.attach(Module.findExportByName(null, 'strstr'), {
        onEnter: function(args) {
            var str = Memory.readUtf8String(args[0])
            if(str.indexOf('frida') !== -1) {
                Memory.writeUtf8String(args[0], "seomj")
            }
        },
        onLeave: function(retval){
        }
    })
})

 

두 번째는 반환 값을 변경하는 방식이다.

Java.perform(function() {
    console.error('\n')

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

    Interceptor.attach(Module.findExportByName(null, 'strstr'), {
        onEnter: function(args) {
            this.arg1 = Memory.readUtf8String(args[1])
        },
        onLeave: function(retval){
            if(this.arg1.indexOf('frida') !== -1){
                retval.replace(0);
            }
            return retval
        }
    })
})

 

 

 

 

 

https://hand-over.tistory.com/57

https://repilria.tistory.com/228

https://chp747.tistory.com/362

https://velog.io/@woounnan/ANDROID-Frida%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-OWASP-mstg-Level-3-%ED%92%80%EC%9D%B4#libfooso-%EB%B6%84%EC%84%9D

'Study > App' 카테고리의 다른 글

[App]Uncrackable2  (0) 2022.10.22
[App]Fridalab 7  (0) 2022.10.20
[App]Fridalab 5  (0) 2022.10.20
[App]Fridalab 4  (0) 2022.10.20
[App]Fridalab 3  (0) 2022.10.20