App 진단 중 간단한 Anti-Debugging 기법을 알게되었습니다.


ptrace를 이용한 기법인데 ptrace에 대한 자세한 내용은


http://research.hackerschool.org/temp/ptrace.txt


위 주소에 더 잘나와있네요. 해커스쿨에서 작성된 내용을 보자면 


/*


ptrace의 특징은, 다양한 기능들을 함수 인자로 처리한다는 점입니다.


ptrace(PTRACE_ATTACH, ... ); // 이렇게 하면 process를 attach하겠다는 것이고요


ptrace(PTRACE_GETREGS, ... ); // 이건 대상 process의 레지스터 목록을 받아오라는 거죠


ptrace(PTRACE_PEEKDATA, ... ); // 이처럼 데이터를 쓰거나


ptrace(PTRACE_POPEDATA, ... ); // 가져올 수 있습니다.

*/ 등등인데 유명한 GDB, Frida도 ptrace를 이용해서 동작한다고 하네요


1. Ptrace Anti-Debugging 


Android Anti-Debugging 기본 예제는 다음과 같습니다.


void anti_debug() {

    child_pid = fork();

    if (child_pid == 0)
    {
        int ppid = getppid();
        int status;

        if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) == 0)
        {
            waitpid(ppid, &status, 0);

            ptrace(PTRACE_CONT, ppid, NULL, NULL);

            while (waitpid(ppid, &status, 0)) {

                if (WIFSTOPPED(status)) {
                    ptrace(PTRACE_CONT, ppid, NULL, NULL);
                } else {
                    // Process has exited for some reason
                    _exit(0);
                }
            }
        }
    }
}

출처 : www.vantagepoint.sg/blog/89-more-android-anti-debugging-fun



Anti-Debugging 기본 예제 소스는 위와 같습니다.


원리는 fork()를 이용해서 자식프로세스에서 부모프로세스를 ptrace하면 다른 프로세스에서 해당 프로세스로 ptrace 시도 시, 이미 점유되어 있어서 다른 디버거에서 attach가 불가능한 원리입니다.


2. Anti-Debugging 우회


2.1 With Frida

import sys
import frida
def on_message(message,data):
    print "[%s] -> %s" % (message, data)

PACKAGE_NAME = sys.argv[1]
jscode = """
/// Inject_Jscode
"""
   
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)


Frida의 spawn을 이용하여 앱 실행 전에 프리다가 먼저 후킹을 시도하여 Anti-Debugging을 우회하는 방법과


frida -U -f <Package_Name> --no-pause


명령어를 입력하는 방법이 있습니다.


2.2 Integrity 


이건 뭐 별달리 설명드릴 부분은 아니지만.. 해당 로직 Smali를 변조하여 앱 리빌드 후에 실행시키는 방법인데, 이를 이용하려면 무결성 체크로직이 없거나 무결성 체크로직도 우회해야 합니다.



출처 : http://www.vantagepoint.sg/blog/89-more-android-anti-debugging-fun

+ Recent posts