格式化字符串的极限
Thir0th 发表于 浙江 CTF 337浏览 · 2025-05-08 13:11

极限fmt利用🧐

2024Moectf的一道题目,十分有趣的格式化字符串利用😊,最终效果是完成了一次格式化字符串修改两个地方,也就是打一次非栈上fmt的指针跳板。这波属实有点极限

题目附件

夸克链接:https://pan.quark.cn/s/3ad0ae74c376

题目分析

图片加载失败


图片加载失败


开局给了一个栈地址,后边给了一次非栈上fmt的机会,同时题目给出后门,保护是全开的

返回地址和后门之间只差一个字节

ret:

图片加载失败


backdoor:

图片加载失败


按照正常的思路,需要构造一次指针跳板,造成a->b->ret->main,再去修改b地址偏移main的最后一个字节,但是%n是将前边的字节数写入对应偏移的位置,这里就有一个小tips

不管你输入的字节数是多少,%hhn只会去将总字节数的最后一个字节写入对应偏移处

例:

前提是比前边全部输入的总字节数要多

错误思路

按照我们之前指针跳板的思路,应该是这样构造payload

实际只修改了第一个地址,第二个没有修改

图片加载失败


引用

猜测:任意地址写用 <font style="color:rgb(68, 68, 68);">$</font> 指定写入和按参数顺序写入的操作是先后分开的,先按参数顺序写入指针后,再用 <font style="color:rgb(68, 68, 68);">$</font> 去在刚刚的指针基础上进行修改。注意:这仅仅是个猜测,真相应该去源码中找到答案 (以后有机会的话,我应该会去分析 <font style="color:rgb(68, 68, 68);">printf</font> 函数的源码,来探究出这个答案,但可惜不是现在🤔

正确思路

paylaod

payload=b'%p'*13+b'%'+str((stack&0xffff)-138).encode()+b'c%hn'+b'%'+str(0x10008-(stack&0xffff)).encode()+b'c%45$hhn'

printf 解析参数会根据 % 进行判断,在 hn 前面一共有 15% ,所以这个 %xxxc%hn 会将 xxx 数据加上 %p 泄露的字符个数写入第十五个参数

13+1+1=15

图片加载失败


stack&0xffff 这个是返回地址的最后两个字节

-138 前边的%p泄露的东西,需要减去这些字符数,这里需要手动调试计算,不同版本对应也不同

0x8b是139,多接受了一个\n,听别的师傅才发现这个用法

图片加载失败


一开始是直接ai生成的脚本

0x10008只是将最后一个字节改为0x08,只要比前边字节大得多就可以实现

完成利用

图片加载失败


第六届强网拟态线下赛-pwn

也是这个的点的利用,但这道题目更难一些,解题思路也更加新颖,感觉格式化字符串的思路更极限了

题目分析

图片加载失败


libc版本是2.31的

给了一个栈地址的最后两个字节,同时有一次非栈上fmt的机会,保护除了canary都是开着的,最后是调用_exit退出。

第一步肯定是想如何去控制返回地址,达到多次利用fmt的效果,这里我们就劫持printf的返回地址为main

后续补全0x100字节是为了避免read把两次读入的payload一次读入

这里再强调一下,一个%代表一个偏移,payload += b'%'+str(printf_ret - 90).encode()+b'c%hn'#11本身是有两个%的,所以算两个偏移

计算%p*9的字节数还可以用,-1是因为\n

之后再去执行printf的时候返回地址还是没有更改,这就需要我们每一次先将返回地址修改,因为跳板指针不会变,所以我们这里可以直接修改,这是是打算将返回地址(rbp+8)修改为one_gadget,但这样却没办法执行,参考大佬的思路,是将printf的返回地址改为ret,再将此时栈顶改为one_gadget,就可以跳转到one_gagdet,getshell

exp

好抽象,需要把这一部分去了才成功,调试发现是改错数字了,可能是我本地关闭arls的原因🧐,这里也不重要,前边改好之后后续改one_gadget就是一个板子题

图片加载失败


参考

https://qfbsz.github.io/2024/10/02/onechance-%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%B8%B2/

https://zikh26.github.io/posts/a523e26a.html#%E5%89%8D%E8%A8%80



2 条评论
某人
表情
可输入 255