티스토리 뷰

1. lldb 설치하기

linforum.kr/bbs/board.php?bo_table=ios&wr_id=51 참고하여 lldb 설치를 진행하였음

 

1) /Developer/usr/bin 경로에 있는 debugserver를 /usr/bin으로 복사

2) python과 lldb 설치

- deb 파일을 Bitvise SFTP를 이용하여 /usr/bin 경로에 넣어준다.

+) python, lldb dev 다운로드: github.com/Proteas/native-lldb-for-ios

 

- python 설치 시 libffi와 sqlite3 이 필요하다는 에러가 발생하여 추가적으로 설치를 해주었다.

libffi, sqlite3 필요

- libffi, sqlite3 dev 파일도 Bitvise SFTP를 이용하여 /usr/bin 경로로 옮긴 뒤 설치한다.

+) sqlite3 deb 다운로드: apt.saurik.com/debs/

sqlite3 설치

+) libffi deb 다운로드: www.cycript.org/debs/

libffi 설치

 

- sqlite3과 libffi를 설치하면 python이 정상적으로 설치된다.

python, lldb 설치

 

3) spawn으로 debugserver 열어주기

spawn으로 debugserver를 열어주려고 했으나 spawn 명령어 사용이 되지않았다.

python을 확인해보니 'dyld: Library not loaded: /usr/lib/libpython2.7.dylib'가 뜨는 것을 볼 수 있다.

해당 문제를 해결하기 위해 찾아보다가 lldb 사용 시 위와 같은 에러가 발생하여 해결한 글을 볼 수 있었고

따라해보니 바로 lldb 사용이 가능해짐;;

iPhone: ldid -S /usr/lib/libpython2.7.dylib
iPhone: cd /usr/lib/python2.7
iPhone: for i in *; do ldid -S $i; done
iPhone: lldb -n binname

참고: iosgods.com/topic/65161-new-lldb-tool/

 

 

2. lldb 사용하여 프로세스 attach

1) 실행중인 프로세스 attach

- 디버깅인지 확인하는 기능을 이용하여 정상적으로 디버깅이 되고 있는지 확인해본다.

- 테스트앱: SwiftSecurity

3. 디버깅 탐지 우회하기

이제 lldb로 디버깅 중일때도 'Debugger not detected'가 되도록 우회를 해볼 것이다.

 

1) 디버깅 탐지 우회 스크립트 작성

Interceptor.attach(Module.findExportByName(null, "ptrace"), {

  onEnter: function(args) {
    var content = Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\\n') + '\\n';
    console.log("[ptrace]"+args[0]);
    console.log(content);

    if(args[0] == 0x1f){
      args[0]=ptr("0x0");
      console.log("Changed Argument value! Bypassing ptrace");
    }
  },
  onLeave: function(retval) {
    if (this.flag) // passed from onEnter
      console.log("\\nretval: " + retval);
  }
});

Interceptor.attach(Module.findExportByName(null, "sysctl"), {

  onEnter: function(args) {
    //this.a = Memory.readInt(args[0]);
    //this.b = Memory.readInt(args[0].add(ptr(4)));
    //this.c = Memory.readInt(args[0].add(ptr(8)));
    this.d = Memory.readInt(args[0].add(ptr(12))); // get pid

    var pid = Process.id;
    //console.log("pid: "+pid);
    
    if(this.d == pid){
      this.kp_proc = args[2];
      console.log("[sysctl] pid: "+this.d);
    }
    else
      this.kp_proc = null;
  },
  onLeave: function(retval){

    if(this.kp_proc != null){
      console.log(Memory.readByteArray(this.kp_proc.add(30), 16));
      Memory.writeByteArray(this.kp_proc.add(33), [0x40]);
      console.log(Memory.readByteArray(this.kp_proc.add(30), 16));
      console.log('Changed Memory value! Bypassing sysctl');
    }
  }
});

Interceptor.attach(Module.findExportByName(null, "getppid"), {

  onEnter: function(args) {
    var content = Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\\n') + '\\n';
    console.log("[getppid]");
    console.log(content);
  },
  onLeave: function(retval){
    if(retval!=0x01){
      var new_retval = prt("0x01");
      retval.replace(new_retval);
      console.log("Changed return value! Bypassing getppid")
    }
  }
});

 

2) frida로 스크립트 실행 후 lldb로 디버깅한다.

디버깅 탐지시 사용되는 sysctl의 값이 변조되어 탐지를 우회하는 것을 확인할 수 있다.

 

4. sysctl 디버깅 탐지 우회 원리 (작성필요)

P_TRACED 플래그(0x800) 변조

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday