天天看點

嘗試繞過ptrace保護 不知道算不算成功

源碼如下

 #include <sys/ptrace.h>

 int main()

 {

     int i=0;

     if(ptrace(PTRACE_TRACEME,0,0,0)<0)

     {

         printf("failed\n");

         return 0;

     }

     printf("succ\n");

     i=1;

     return 0;

 }

 gcc -g -o ptrace ptrace.c

 一般情況下隻能使用一次ptrace[PTRACE_TRACEME]。是以如果調試器在這之前使用ptrace,那麼我們的調用就會傳回false,于是就能知道還有其他東西在控制程式了。以前做注入程序的時候遇到程序已被注入,隻能放棄嘗試,現在受到這篇連接配接的啟發

​​​http://blog.jobbole.com/77311/​​​和同僚 曾xb 的提示,嘗試繞過ptrace保護。

 預設情況如下:


 [root@promote Desktop]# gdb ptrace

 (gdb) start 

 Temporary breakpoint 1 at 0x40050c: file ptrace.c, line 5.

 Starting program: /root/Desktop/ptrace 

 Temporary breakpoint 1, main () at ptrace.c:5

 5        int i=0;

 Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6_5.3.x86_64

 (gdb) n

 6        if(ptrace(PTRACE_TRACEME,0,0,0)<0)

 (gdb) n

 8            printf("failed\n");

 (gdb) n

 failed

 9            return 0;

 (gdb) q

 A debugging session is active.


 在ptrace調用處失敗傳回。如果做點簡單的反動态調式,至此已經成功。

 ========================================================================

 開始繞過:

 過程如下,在本文連接配接中,作者使用.gdbinit腳本設定捕捉事件catch syscall ptrace。 當觸發ptrace調用時,程式停下。作者同時修改寄存器set ($eax)=1 繞過了if判斷,but,我一直沒有成功。反正gdbinit中的指令和gdb本身一緻,我就搓一點手動修改吧:

 L6下斷點,運作/啟動程式,斷下來後,disassemble


 gdb ptrace

 (gdb) b 6

 Breakpoint 1 at 0x400513: file ptrace.c, line 6.

 (gdb) start 

 Temporary breakpoint 2 at 0x40050c: file ptrace.c, line 5.

 Starting program: /root/Desktop/ptrace 

 Temporary breakpoint 2, main () at ptrace.c:5

 5        int i=0;

 Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6_5.3.x86_64

 (gdb) c

 Continuing.

 Breakpoint 1, main () at ptrace.c:6

 6        if(ptrace(PTRACE_TRACEME,0,0,0)<0)

 (gdb) disassemble 

 Dump of assembler code for function main:

    0x0000000000400504 <+0>:    push   %rbp

    0x0000000000400505 <+1>:    mov    %rsp,%rbp

    0x0000000000400508 <+4>:    sub    $0x10,%rsp

    0x000000000040050c <+8>:    movl   $0x0,-0x4(%rbp)

 => 0x0000000000400513 <+15>:    mov    $0x0,%ecx

    0x0000000000400518 <+20>:    mov    $0x0,%edx

    0x000000000040051d <+25>:    mov    $0x0,%esi

    0x0000000000400522 <+30>:    mov    $0x0,%edi

    0x0000000000400527 <+35>:    mov    $0x0,%eax

    0x000000000040052c <+40>:    callq  0x400410 <ptrace@plt>

    0x0000000000400531 <+45>:    test   %rax,%rax

    0x0000000000400534 <+48>:    jns    0x400547 <main+67>

    0x0000000000400536 <+50>:    mov    $0x400658,%edi

    0x000000000040053b <+55>:    callq  0x4003f0 <puts@plt>

    0x0000000000400540 <+60>:    mov    $0x0,%eax

 End of assembler dump.

 然後在 0x000000000040052c <+40>:    callq  0x400410 <ptrace@plt> 處下斷點,

 b * 0x000000000040052c

 執行到0x0000000000400531時,開始比較rax,此時rax值-1


 (gdb) ni

 0x0000000000400531    6        if(ptrace(PTRACE_TRACEME,0,0,0)<0)

 (gdb) info registers rax

 rax            0xffffffffffffffff    -1


 此處手動修改rax讓程式跳轉到成功傳回即L11:set ($rax)=1


 (gdb) set ($rax)=1

 (gdb) ni

 0x0000000000400534    6        if(ptrace(PTRACE_TRACEME,0,0,0)<0)

 (gdb) n

 11        printf("succ\n");


 程式已經繞過ptrace。

 不知道這算不算成功繞過,為此驗證gdb是否仍工作,嘗試讀寫記憶體變量i:


 (gdb) p i

 $1 = 0

 (gdb) p &i

 $2 = (int *) 0x7fffffffe23c

 (gdb) x /8xb 0x7fffffffe23c

 0x7fffffffe23c:    0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00


 變量i的值還能讀到,再試試寫


 (gdb) set *(0x7fffffffe23c)=1

 (gdb) x /8xb 0x7fffffffe23c

 0x7fffffffe23c:    0x01    0x00    0x00    0x00    0x00    0x00    0x00    0x00

 (gdb) p i

 $3 = 1


 i的值由開始時0變為1,由此判斷gdb應該有效,初步認為算是繞過了ptrace