非栈上的格式化字符串漏洞利用
引言
对于常规的栈上格式化字符串漏洞,可以直接构造(%c %n 指针)的方式来实现任意地址写,但是对于非栈上变量来说,就无法直接给出目的地址的指针,因为printf的参数保存在寄存器和栈上面。
对于非栈上变量,格式化字符串漏洞依然存在,可以考虑借助已有的栈上指针来实现间接地利用。
原理
0 | esp |
1 | ? |
2 | ? |
3 | ? |
4 | ? |
5 | saved_ebp |
6 | ret_addr |
7 | ? |
8 | ? |
9 | last saved_ebp |
假设 栈的结构如图所示,
我们知道,根据栈帧的结构,保存的ebp会构成一个链条
体现在表中,即是 *5 = &9
要解决 非栈上格式化字符串实现任意写 的功能,即我们需要在栈上有一个保存目标地址的指针。
虽然我们无法直接在栈上写入指针,但是我们可以利用已有的指针。
例如 此时栈上的 &5是一个指针, 它的内容为 &9
我们可以通过 %5&hn 来使用 &5
此时它作为指针,先它保存的地址写入数据
所以数据会被写入到&9
也就是说,我们可以通过 &5 来控制 &9 的内容。
此时我们选择 将 &9 的内容改为 &6
0 | esp |
1 | ? |
2 | ? |
3 | ? |
4 | ? |
5 | saved_ebp |
6 | ret_addr |
7 | ? |
8 | ? |
9 | &6 |
这个时候,我们可以通过 %9$hn 来利用 &9
&9保存了 &6
因此,可以修改&6的内容
而 &6 是 函数的返回地址,将它改成 后门函数 等,即可实现劫持控制流的效果。
例子 xman_2019_format
观察ebp链条
ebp 0xfff154e8 —▸ 0xfff15508 —▸ 0xfff15538 —▸ 0xfff15548 —▸ 0xfff15558 ◂— ...
可以发现只有最后一个字节不同
更具体点,只有半个字节不同
按照上面所说的原理,可以利用 &0a 把 &12 的内容改为 &0b, 再通过 &12 将 &0b改为后门函数的地址。
由于 ASLR 的存在,事实上&0b的地址并不确定,但是由于只有 半个字节 与原值的差异,所以可以爆破 &0b,完成利用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理