0
点赞
收藏
分享

微信扫一扫

尝试绕过ptrace保护 不知道算不算成功

三次方 2022-11-07 阅读 132

源码如下

#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

举报

相关推荐

0 条评论