我正在尝试利用我可以访问源代码的二进制文件。
int flag = 0;
int main() {
char buf[0x50];
puts("Who are you? ");
printf("> ");
fgets(buf, 0x50, stdin);
printf(buf);
if (flag == 1337) {
puts("Enjoy your shell!");
system("/bin/sh");}
else {
puts("Not allowed");
}
return 0;
}
正如你从源代码中看到的,如果标志是 1377,我会得到一个 shell。我也可以用 gdb 看到这一点。
0x4007ec <main+175> mov eax, DWORD PTR [rip+0x200892] # 0x601084 <flag>
0x4007f2 <main+181> cmp eax, 0x539
安全措施设置如下:
Canary : Yes
NX : Yes
PIE : No
Fortify : No
RelRO : Partial
所以,首先我不能做经典的缓冲区溢出,因为程序fgets用来收集输入。当然金丝雀也在那里,但不会造成伤害,因为如果我能够更改标志的值(在金丝雀检查之前),我将成功获得该外壳。我不知道我的想法是否正确,所以如果我错了,请纠正我。
我对此的第一个结论是,我无法利用buf来重写标志的值。(我假设buf并且flag将在堆栈上彼此相邻放置)。我想我是对的,因为当我查看$rsp寄存器时发现只有允许数量的“A”被放置在堆栈上。因此,即使将标志放在其正下方,标志的值也不会被覆盖。到目前为止我是对的吗?那将是我的第一个问题
0x7fffffffdaf0: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffdb00: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffdb10: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffdb20: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffdb30: 0x41414141 0x41414141 0x41414141 0x00414141
0x7fffffffdb40: 0x00400840 0x00000000 0x96703f00 0x948afed7
0x7fffffffdb50: 0xffffdc40 0x00007fff 0x00000000 0x00000000
那么,我如何才能确定该值的范围呢?我认为漏洞利用必须来自恶意用户提供的有效负载,但这buf是将该有效负载放入堆栈的唯一方法。因为我不能通过溢出来覆盖寄存器,buf所以我有点迷失了。