SEED Labs – Format String Attack Lab
相关链接
-
Lab 网址:https://seedsecuritylabs.org/Labs_20.04/Software/Format_String/
-
任务书:https://seedsecuritylabs.org/Labs_20.04/Files/Format_String/Format_String.pdf
-
VM 手册:https://github.com/seed-labs/seed-labs/blob/master/manuals/vm/seedvm-manual.md
-
Docker 手册:https://github.com/seed-labs/seed-labs/blob/master/manuals/docker/SEEDManual-Container.md
Environment Setup
关闭地址随机化:
|
|
在 server-code
目录下编译:
|
|
Task 1
启动容器并发送信息:
|
|
提供输入使程序崩溃:
|
|
Task 2
Task 2.A
修改 build_string.py:
|
|
需要 64 个 %x 才能让服务器程序打印出输入的前 4 个字节。
Task 2.B
修改 build_string.py:
打印出秘密信息:
Task 3
Task 3.A
修改 build_string.py:
成功修改目标值:
Task 3.B
0x5000 = 20480,20480 - 4 = 62 * 330 + 16。修改 build_string.py:
成功修改目标值为 0x5000:
Task 3.C
0xAABB = 43707,43707 - 12 = 62 * 704 + 47,0xCCDD - 0xAABB = 8738。修改 build_string.py:
成功修改目标值为 0xAABBCCDD:
Task 4
由下图可知,②标记的地址为 0xffffcff8 + 4 = 0xffffcffc,③标记的地址为 0xffffd0d0。由 Task 2 可知,需要 63 个 %x 才能将格式化字符串参数指针移至③。
这里格式化字符串的长度通常小于 512。因此在 buf 的地址再加 512 容易到达 NOP 指令区域。0xffffd0d0 + 512 = 0xffffd2d0,0xd2d0 = 53968,53968 - 12 = 53956 = 62 * 870 + 16,0xffff - 0xd2d0 = 11567。修改 exploit.py:
恶意代码的起始地址如图所示:
成功让服务器运行 shellcode:
再次修改 exploit.py,使服务器的标准输入、输出和错误设备重定向到 TCP 连接:
攻击方启动 TCP 服务器,监听 9090 端口上的连接,成功获取反向 shell:
|
|
Task 5
向服务器发送问候信息:
|
|
可以得到 buf 地址为 0x00007fffffffe000,返回地址所在地址为 0x00007fffffffdf40 + 8 = 0x00007fffffffdf48。
修改 build_string.py:
|
|
需要 34 个 %lx 才能让服务器程序打印出输入的前 8 个字节。
修改 exploit.py,使服务器的标准输入、输出和错误设备重定向到 TCP 连接:
先选用 64 位的 shellcode。因为使用了 %k$hn(可以快速地选择第 k 个可变参数),这里格式化字符串的长度通常比较小。修改返回地址时,确保能落到 NOP 指令即可。 这里将返回地址 0x00007fffffffdf48 的值修改为 &buf + 512 = 0x00007fffffffe200。需要注意的是,这里不能再像攻击 32 位服务器程序那样把目标地址字节放在格式化字符的前面,因为 64 位地址高 2 个字节为 0,printf()
遇 0 停止打印。因此需要把格式化字符放在目标地址字节之前,于是,这样目的地址对应的可变参数也会比 34 更加靠后。另外,这里的可变参数指针是 8 字节移动的,所以需要确保目标地址字节在内存中的首地址为 8 的倍数。由 0x7fff = 32767,0xe200 - 0x7fff = 25089,0xffff - 0xe200 = 7679,可构造如下格式化字符串。
攻击方启动 TCP 服务器,监听 9090 端口上的连接,成功获取反向 shell:
|
|
Task 6
回顾之前编译的警告信息:
格式不是字符串文字,也没有格式化参数,因此程序有格式化字符串漏洞。
修复如下:
重新编译,警告消失:
重新构建 docker 容器:
|
|
以 Task 2.A 为例,尝试利用格式化字符串漏洞失败: