闲聊

2025年长城杯决赛渗透出现了一个pwn服务,然而并没有附件,经过测试发现是format string类型的漏洞,不禁想起Blind Pwn,但是打的又少,导致浪费了好几个小时…

期间对利用的一些思考,借此机会记录一下

问题的关键

问题的关键是无任何有效信息,即使栈溢出也不知道应该跳转到哪里

对此有两种思路

  1. 爆破地址观察程序相应情况,来判断是否进入了某些函数(如输出函数,main函数等),这种对应的手法应该是BROP(利用条件为纯栈溢出,NO PIE)
  2. 通过fmt漏洞直接leak elf数据(%s-%p等来确认),这种手法利用条件为format string漏洞

无论是哪种思路,第一大步的目的就是寻找到puts/printf/write这些函数,进一步泄露整个elf,当这一步完成的时候,就和普通pwn没有区别了

BROP

这种手法需要大量尝试/爆破,利用条件为栈溢出/NO PIE,在没有PIE保护的情况下,我们可以知道程序的elf base,然后在挟持执行流的时候,将返回地址遍历挟持整个elf代码段的每个地址,寻找对应gadgets

Stopping gadgets

Stopping gadgets指的是让程序卡住但不崩溃的gadget,比如main/_start,这几个函数的地址,它会让程序重启,但不会断开socket链接,通过这一现象就可以判断是否拿到Stopping gadgets。

Stopping gadgets会为下一步拿到其他gadgets作为一个依靠

register gadgets

下一步寻找register gadgets,这一步不确定性挺大的

如需要寻找pop rdi; ret 这个gadget,将payload设置为

flat([
	padding,
	pop_rdi, 0,
	Stopping gadget
])

这个payload会将设pop_rdi的地址满足它是一个pop xxx ; ret 结构,然后不能影响后面进入Stopping gadget

所以依赖这个Stopping gadget,我们可以根据程序如果挂了,那就这个地址不满足,否则应该是满足这个结构的