我想通过控制堆栈来利用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执行该地址的内容。
当然你也需要知道编译器在哪里放置'buf'? – 2011-12-17 12:29:39
为什么我需要知道这个地方?这与它的大小有什么关系? – curious 2011-12-17 12:41:17
因为您需要知道堆栈上的哪个位置开始写入。 – 2011-12-17 12:53:56