【发布时间】:2011-12-17 12:16:38
【问题描述】:
我想通过控制堆栈来利用 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 并没有执行该地址的内容。
【问题讨论】:
-
当然你还需要知道编译器将
buf放在哪里? -
为什么我需要知道这个地方?这与它的大小有什么关系?
-
因为您需要知道您开始写入堆栈的哪个位置。
标签: c stack callstack buffer-overflow shellcode