我想通过控制堆栈来利用 C 代码段的漏洞用于教育目的。一个简单的基于堆栈的缓冲区溢出,用应该执行 shellcode 的地址覆盖返回地址。该代码是一个简单的函数,它将缓冲区作为参数并尝试strcpy()
将缓冲区调整为固定大小。从 main 给出的参数是argv[1]
. 所以我认为,如果我找到了我必须覆盖的确切内存量,那么我可以简单地将一个由\x90
(NOP 指令)组成的字符串作为输入,然后是 shellcode,最后是这个缓冲区的地址。由于这是第一个参数,它的地址是$ebp+8
,你可以通过运行找到它gdb
,在函数的开头设置一个断点,然后输入i args
为您提供作为参数传递的字符串的地址。所以我发现如果我覆盖n
字节然后给出地址的值,那么这将完全覆盖返回地址。所以我有这样的输入:
perl -e print(\x90 x n-sizeof(shellcode) . shellcode . address)'
它没有用,我试图理解为什么。与gdb
我一起运行程序。strcpy()
我在函数之前放了一个断点。那时我有一个参数,它是一个指向我的输入的字符串指针,它的地址与我的字符串输入末尾给出的地址相同,我向前推进了 1 条指令。我检查了堆栈。我现在有了保存的eip
( $ebp + 4
),其末尾给出了地址的值argv[1]
,这是预期的行为(这意味着它不会覆盖 ret 地址之上的其他地址,即第一个参数的值)。奇怪的是,现在的内容$ebp+8
不是“地址”而是别的什么?但是保存的内容eip
是指向我的利用漏洞的字符串的地址。但似乎 ret addr 并没有执行该地址的内容。