2011-12-17 20 views
0

我想通过控制堆栈来利用C代码的漏洞进行教育目的。一个简单的基于堆栈的缓冲区溢出,用应该执行shellcode的地址覆盖返回地址。该代码是一个简单的函数,它将缓冲区作为参数,并尝试将缓冲区设置为固定大小。从main给出的参数是argv[1]。所以我认为,如果我找到了必须覆盖的确切内存量,那么我可以简单地给出一个由\x90(NOP指令)组成的字符串,后面跟着shellcode,最后是这个缓冲区的地址。由于这是第一个参数,所以它的地址是$ebp+8,你可以通过运行gdb来找到它,在函数的开头设置一个断点,只需输入i args即可得到作为参数传递的字符串地址。所以我发现如果我覆盖n字节,然后给出地址的值,那么这将完全覆盖返回地址。所以我有这样的输入:为什么函数参数给出的字符串地址在溢出ret地址后发生了变化?

perl -e print(\x90 x n-sizeof(shellcode) . shellcode . address)' 

它没有工作,我试图理解为什么。用gdb我运行程序。我在strcpy()函数之前放置了一个断点。在那一点上,我有一个参数,它是一个指向我的输入的字符串指针,其地址与我的字符串输入结尾的地址相同,我向前走了1条指令。我检查了堆栈。我现在保存的eip$ebp + 4)与argv[1]末尾给出的地址的值,这是预期的行为(这意味着它不会覆盖ret地址上方的其他地址,即第一个参数的值)。奇怪的是,现在$ebp+8的内容不是“地址”,而是其他内容?但保存的eip的内容是指向我的字符串利用漏洞的地址。但似乎ret addr执行该地址的内容。

+1

当然你也需要知道编译器在哪里放置'buf'? – 2011-12-17 12:29:39

+0

为什么我需要知道这个地方?这与它的大小有什么关系? – curious 2011-12-17 12:41:17

+0

因为您需要知道堆栈上的哪个位置开始写入。 – 2011-12-17 12:53:56

回答

1

如何组织堆栈框架是ABI的一部分。 Linux在x86-64上使用的ABI的描述是here。你会发现你需要的一切(然后更可能)。有关堆栈帧组织,请参见3.2节。