본문 바로가기
HACKING/mobile_IOS

iOS Analysis#1 CydiaSubstrate Hooking

by asdf12345 2020. 7. 4.

[ CydiaSubstrate를 이용한 탈옥 우회 앱 분석 ]

                                                                                           \

1. CydiaSubstrate?

=code modification platform, hooking하여 Application 로직을 변경하는 라이브러리이다. (iOS 에서 find / -name libsubstrate*를 통해 바이너리 경로 확인가능.)

2. Analyzing Application using CydiaSubstrate(FlyJB)

iOS 앱 중 CydiaSubstrate를 이용하여 Hooking시도하는 Application Binary File Logic 확인 시, libsubstrate.dylib 이용하는 것을 확인할 수 있다. libsubstrate 라이브러리 내 CydiaSubstrate 주요 로직들이 존재한다.

 

API 후킹을 위해 MSHookMessageEx() 호출

MSHookMessageEx(hooking Target class, hooking Target method명, hooking 후 실행 코드 주소, null);

3번째 인자 함수 파악을 통해 변조된 코드 확인 가능

http://www.cydiasubstrate.com/api/c/MSHookMessageEx/

API 후킹을 위해 MSHookFunction() 호출

MSHookFunction(symbol 주소, hooking 후 실행 코드 주소, null);

2번째 인자 함수 파악을 통해 변조된 코드 확인 가능

http://www.cydiasubstrate.com/api/c/MSHookFunction/

 

 

 

3.  Analyzing by using Frida

CydiaStrate를 이용하는 FlyJB 외 난독화된 악성 앱일경우, CydiaSubstrate 후킹을 통한 영역, 변조된 코드 확인이 필요하다. Frida를 이용하면 손쉽게 해결된다. 획득한 주소를 이용하여 함수의 return 값, 인자를 확인하여 동적 분석이 가능하다.

 

 

#!/usr/local/bin/python3
#-*- coding:utf-8 -*-

import sys
import os
import base64
import frida
def on_message(message, data):
    try:
        if message:
            print("[JSBACH] {0}".format(message["payload"]))
    except Exception as e:
        print(message)
        print(e)
 

def main():
    host = frida.get_usb_device()
    package_name=""
    pid=host.spawn([package_name])
    session = host.attach(pid)
    host.resume(pid)
    script = session.create_script('''
    
    function logtrace(ctx) {
        var content = Thread.backtrace(ctx.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\\n') + '\\n';
        return true;
    }   

    var count=0;
    var substrate_base=Module.findBaseAddress("libsubstrate.dylib");
    console.log("[+] libsubstrate.dylib base address : ");
    console.log(substrate_base);
    
    
    Interceptor.attach(Module.findExportByName("libsubstrate.dylib", "MSHookFunction"), {
    onEnter: function(args) {
            count=count+1;
            console.log("[+] _MSHOOkFunction onEnter COUNT"+count);
            var symbol=DebugSymbol.fromAddress(args[0]);
            var symbol2=DebugSymbol.fromAddress(args[1]);
            console.log("\\t1) hooked address");
            console.log("\\t\\t"+symbol);
            console.log("\\t2) hooking code address");
            console.log("\\t\\t"+symbol2);

        }
    });
    Interceptor.attach(Module.findExportByName("libsubstrate.dylib", "MSFindSymbol"), {
    onEnter: function(args) {
        count=count+1;
        console.log("[+] MSFindSymbol onEnter");
        }
    });

    Interceptor.attach(Module.findExportByName("libsubstrate.dylib", "MSHookMessageEx"), {
        onEnter: function(args){
            count=count+1;
            console.log("[+] MSHookMessageEx onEnter COUNT"+count);
            var symbol=DebugSymbol.fromAddress(args[2]);
            console.log("\\t1) hooked method name");
            console.log("\\t\\t"+args[1].readUtf8String());
            console.log("\\t2) hooking code address");
            console.log("\\t\\t"+symbol); 
        }
    });


    ''')
    script.on('message', on_message)
    script.load()
    sys.stdin.read()



        
if __name__ == '__main__':
    main()

RESULT