567 字
3 分钟
PWN 格式化漏洞


简单贴个图,作为参考。
说实话,格式化字符串漏洞的原理就是:
通过输入%p之类的格式化字符串,让printf这个函数执行命令,它会去stack寻找参数来打印。

以一个题目做辅助讲解,这边有个printf(format),如果我们输入的是AAAA,那程序就自动打印AAAA,可是如果我们输入AAAA.%p.%p.%p.%p.%p.%p.%p.%p.%p,程序就会因为格式化字符串的缘故,在栈帧中依次寻找参数来打印。

这就是格式化字符串产生的漏洞。
%x也能做到一样效果,只不过%x读取的是4字节长度的数据而%p读取的是8字节,在64位程序中最好用%p。
怎么运用呢?
同样以这题来讲解,根据ida里面的源代码,当num的数据为16时,就能返回一个系统执行命令的结果(cat flag)。
直接在程序中寻找

可以看见num在程序里面的地址为0x804a030。
payload = p32(0x804a030)+b'%12c%7$n'通过格式化字符串,以及动态测试,可以知道程序打印出来的第七个参数是我们的输入值,我们让num函数的地址作为打印出来的第一个参数,而后面用 %12c 补齐数值,地址占4字节加上这个 %12c 占的12字节,正好是16字节,而后面 %7$n 的作用就出来,它会让程序去第七个参数,将我们前面的16字节的16读取入第七个参数,这样就完成了num==16。

这边还有一个%a也常常适用于格式化字符漏洞。
格式化字符串小表格:
| 控制符 | 功能 | 在漏洞利用中的作用 |
|---|---|---|
%p | 以十六进制打印指针 | 泄露栈上的地址。 |
%s | 打印地址指向的字符串 | 读取内存中特定地址的内容。 |
%x | 以十六进制打印数值 | 查看内存原始数据。 |
%n | 写入已打印字符的数量 | 修改内存变量的值(核心杀招)。 |
%k$p | 打印第 k 个参数 | 定位特定偏移位置,不用手打一长串 %p。 |
- 版权声明:本文由 余林阳 创作,转载请注明出处。
喜欢这篇文章吗?
点击右侧按钮为文章点赞,让更多人看到!
在下余林阳