567 字
3 分钟

PWN 格式化漏洞

2026-03-22
2026-04-16
浏览量 加载中...

image-20260322185918295

image-20260322191104783

简单贴个图,作为参考。

说实话,格式化字符串漏洞的原理就是:

通过输入%p之类的格式化字符串,让printf这个函数执行命令,它会去stack寻找参数来打印。

image-20260322191839709

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

image-20260322192024117

这就是格式化字符串产生的漏洞。

%x也能做到一样效果,只不过%x读取的是4字节长度的数据而%p读取的是8字节,在64位程序中最好用%p。

怎么运用呢?

同样以这题来讲解,根据ida里面的源代码,当num的数据为16时,就能返回一个系统执行命令的结果(cat flag)。

直接在程序中寻找

image-20260322192730823

可以看见num在程序里面的地址为0x804a030。

payload = p32(0x804a030)+b'%12c%7$n'

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

image-20260323202713090

这边还有一个%a也常常适用于格式化字符漏洞。

格式化字符串小表格:#

控制符功能在漏洞利用中的作用
%p以十六进制打印指针泄露栈上的地址。
%s打印地址指向的字符串读取内存中特定地址的内容。
%x以十六进制打印数值查看内存原始数据。
%n写入已打印字符的数量修改内存变量的值(核心杀招)。
%k$p打印第 k 个参数定位特定偏移位置,不用手打一长串 %p

  • 版权声明:本文由 余林阳 创作,转载请注明出处。

喜欢这篇文章吗?

点击右侧按钮为文章点赞,让更多人看到!

PWN 格式化漏洞
https://sliver-yu.cc/posts/pwn/pwn-格式化漏洞/
作者
余林阳
发布于
2026-03-22
许可协议
CC BY-NC-SA 4.0

评论区

目录