我无法让这个缓冲区溢出漏洞在我的生活中发挥作用。源代码在这里。它来自这本书, Hacking the Art of Exploitation。这里的主题是以下结构:
struct user {
int uid;
int credits;
int highscore;
char name[100];
int (*current_game) ();
};
这个想法是溢出 name[100] 使得在 100 个字母 A之后提供的地址将覆盖名为 current_game 的函数指针的地址。
但是,请参阅下面的 gdb 读数:
[Name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA��048e2c]
56 printf("[You have %u credits] -> ", player.credits);
(gdb) x/40x player.name
0x804c08c <player+12>: 0x41414141 0x41414141 0x41414141 0x41414141
0x804c09c <player+28>: 0x41414141 0x41414141 0x41414141 0x41414141
0x804c0ac <player+44>: 0x41414141 0x41414141 0x41414141 0x41414141
0x804c0bc <player+60>: 0x41414141 0x41414141 0x41414141 0x41414141
0x804c0cc <player+76>: 0x41414141 0x41414141 0x41414141 0x41414141
0x804c0dc <player+92>: 0x41414141 0x41414141 0x41414141 0x41414141
0x804c0ec <player+108>: 0x41414141 0x080490bb 0x65383430 0x00006332
0x804c0fc: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c10c: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c11c: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb) x/5x player.current_game
0x80490bb <pick_a_number>: 0x83e58955 0xec8318ec 0x9d2e680c 0xa2e80804
0x80490cb <pick_a_number+16>: 0x83fffff4
(gdb) print 6*16
$2 = 96
我已将另一个函数的地址放入 player.name 中,如该[Name: A*100 ...行所示。在此下方,您可以看到内存布局,内存中确实有 100 个 A。然而,在最后一个 A 之后,我们看到下一个内存点被0x080490bb并且还没有被覆盖,即使我们看到 player.name 缓冲区确实包含之前的溢出。之后我显示了 player.current_game 的打印输出,以显示它确实在地址0x80490bb,这就是我们在最后一个 0x41414141 之后直接在转储中看到的地址。我在这里很困惑。
我试过的:
- 通过设置
/proc/sys/kernel/randomize_va_space为 0在我的 Fedora 25 上禁用 ASLR 。 - 在 gcc 中启用可执行堆栈。
- 在 gcc 中关闭堆栈保护。
- 关闭 PIE
- 您可以使用此命令确认我用于制作二进制文件:
gcc -z execstack game_of_chance.c -fno-stack-protector -no-pie -m32 -o goc - 我试过将地址写为 \x2c\x8e\x04\08 并且只是直接的 0x08048e2c,两者都不起作用。这是我试图运行的函数的地址。
- 观察到 paddr 和 vaddr 在程序的多次执行中是相同的。
如您所见,在 gdb 和 Radare2 中都进行了调试。您可以在下面看到我的 rabin2 打印输出:
havecode true pic false canary false nx false crypto false va true intrp /lib/ld-linux.so.2 bintype elf class ELF32 lang c arch x86 bits 32 machine Intel 80386 os linux minopsz 1 maxopsz 16 pcalign 0 subsys linux endian little stripped false static false linenum true lsyms true relocs true rpath NONE binsz 20471
谢谢。
更新
我能够成功地使用字符(例如“A”或“B”)导致分段错误,但是,当我执行 A*100 后跟我试图跳转执行的 08048e2c 内存地址时,会发生段错误,但是 player.current_game 函数指针地址(如上图所示就在 player.name 缓冲区之后)很奇怪,[DEBUG] current_game pointer @ 0x34303830而不是地址 08048e2c,这会导致分段错误,因为它无法执行 0x34303830。此外,我在 0x804c0ec 上放置了读/写监视,以查看是否可以找到任何正在写入的内容,但没有成功找到其他任何内容。

