You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

printf风格格式化字符串字符含义咨询(picoCTF格式字符串漏洞场景)

拆解格式字符串漏洞脚本中的特殊Python语法

嘿,我来帮你把这个奇怪的语法拆明白!你在picoCTF格式字符串漏洞的脚本里看到的这种写法,其实是把Python自身的字符串格式化和漏洞利用的payload构造结合起来了,咱们一步步捋清楚:

首先先还原一个你大概率看到的典型代码片段(完全符合你描述的“多个%符号+%2493在外部”的特征):

from pwn import *

target_addr = 0xdeadbeef  # 要覆盖的目标内存地址
target_value = 2493       # 要写入的数值

# 第一种你困惑的写法
payload = p64(target_addr)  # 先把目标地址放到payload开头
# 计算需要填充的长度:目标值减去地址的长度(8字节)再减去%hn部分的长度
padding = target_value - len(payload) - len("%10$hn")
# 生成格式字符串部分:这里就是你说的多个%+外部%的写法
fmt_part = ("%%%dx%%10$hn" % padding)
payload += fmt_part.encode()

1. 多个%符号的含义

这里的%%是Python字符串的转义写法——因为Python本身的%是格式化运算符,如果你想在字符串里输出一个真实的%字符,就必须写两个%来转义,避免被当成Python的格式化占位符。

拿"%%%dx%%10$hn"这个字符串来说:

  • 前两个%% → 会被Python转换成一个单独的%字符
  • %d是Python的格式化占位符,用来填充后面的padding数值
  • 后面的%%同样转义成一个%,然后跟着10$hn就是你已经熟悉的格式字符串漏洞写法:指定第10个参数的位置,用hn写入2字节的数值(也就是我们要的2493)

2. 外部的%和2493的作用

这里的%是Python的字符串格式化运算符,和漏洞里的格式符完全是两回事!它的作用是把右边的padding值(这个值是从2493计算而来的)填充到左边字符串的%d占位符里。

举个具体的计算例子:假设target_addr占8字节,"%10$hn"是5字节,那么padding = 2493 - 8 -5 = 2480。这时候("%%%dx%%10$hn" % 2480)就会生成字符串:
"%2480x%10$hn"
这个字符串就是最终payload的一部分,它会让程序的printf类函数打印2480字节的十六进制填充内容,加上前面的8字节地址,总输出字节数刚好是2493,然后%10$hn就会把这个字节数写入到target_addr指向的内存里,完美实现用2493覆盖目标地址的目的。

为什么要这么写?

对比你熟悉的直接写死%2493x%10$hn的写法,这种动态生成的方式更灵活:如果payload前面的内容长度变化(比如目标地址是4字节而不是8字节),你不需要手动重新计算填充数值,Python会帮你自动算出正确的padding值,避免手动计算出错。


内容的提问来源于stack exchange,提问作者Zapho Oxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:33:05