我正在尝试在 Debian i386 VM 上编译一个简单的缓冲区溢出示例。可执行文件构建正常,但 EIP 没有被正确覆盖,尽管提供了足够大的输入以溢出缓冲区并覆盖堆栈上的推送 EIP。以下是我以 root 身份执行的命令:
sysctl -w kernel.randomize_va_space=0
gcc test.c -z execstack -z norelro -fno-stack-protector -D_FORTIFY_SOURCE=0 -ggdb -o test
如您所见,我有:
- 使堆栈可执行
- 移除了堆栈金丝雀
- 禁用 ASLR 系统范围
- 删除了 relro 保护
- 禁用 gcc 的 FORTIFY_SOURCE 保护
这是test.c:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char buf[128];
if(argc < 2) return 1;
strcpy(buf, argv[1]);
printf("%s\n", buf);
return 0;
}
我已经尝试过长度为 128-256 的崩溃字符串(只是所有的 As)。在 gdb 中,推送的 EIP 永远不会被覆盖。实际上它应该只是一个 132 字节的字符串来覆盖 EIP,因为没有其他本地堆栈变量。
编译时我需要禁用其他一些保护吗?或者还有什么可以用 sysctl 禁用的?