XXE - XEE - XML External Entity
XMLの基礎
XMLは、データの保存と転送を目的としたマークアップ言語であり、記述的な名前付きタグの使用を可能にする柔軟な構造を特徴としています。HTMLとは異なり、事前定義されたタグに制限されていない点が異なります。JSONの台頭に伴い、XMLの重要性は低下していますが、初期のAJAX技術での役割は大きかったです。
エンティティを通じたデータ表現: XMLのエンティティは、
<
や>
のような特殊文字を含むデータの表現を可能にし、これらは<
や>
に対応してXMLのタグシステムとの競合を避けます。XML要素の定義: XMLは要素タイプの定義を許可し、要素がどのように構造化され、どのようなコンテンツを含むかを明確にします。任意の種類のコンテンツから特定の子要素まで含めることができます。
Document Type Definition (DTD): DTDは、文書の構造とそれが含むデータの種類を定義するためにXMLで重要です。内部、外部、または組み合わせのDTDは、文書のフォーマットと検証方法を案内します。
カスタムおよび外部エンティティ: XMLは、柔軟なデータ表現のためにDTD内でカスタムエンティティの作成をサポートします。URLで定義された外部エンティティは、特にXML External Entity (XXE) 攻撃の文脈でセキュリティ上の懸念を引き起こします。これらはXMLパーサーが外部データソースを処理する方法を悪用する攻撃です:
<!DOCTYPE foo [ <!ENTITY myentity "value" > ]>
パラメータエンティティを使用したXXEの検出: 通常の方法が失敗する場合、XMLパラメータエンティティを利用してXXEの脆弱性を検出することができます。これらのエンティティを使用すると、DNSルックアップのトリガーや制御されたドメインへのHTTPリクエストなどの帯域外検出技術を使用して脆弱性を確認できます。
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///etc/passwd" > ]>
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://attacker.com" > ]>
主な攻撃
これらの攻撃のほとんどは、素晴らしいPortswiggers XEEラボを使用してテストされました: https://portswigger.net/web-security/xxe
新しいエンティティのテスト
この攻撃では、単純な新しいエンティティ宣言が機能するかどうかをテストします。
ファイルの読み取り
さまざまな方法で /etc/passwd
を読み取ってみましょう。Windows の場合は、C:\windows\system32\drivers\etc\hosts
を読み取ることができます。
最初のケースでは、SYSTEM "**file:///**etc/passwd" も機能することに注意してください。
この2番目のケースは、ウェブサーバーがPHPを使用している場合にファイルを抽出するのに役立ちます(Portswiggers labsの場合ではありません)
第3のケースでは、Element stockCheck
を ANY として宣言していることに注意してください。
ディレクトリリスト
Javaベースのアプリケーションでは、次のようなペイロードを使用してXXEを介してディレクトリの内容をリストアップすることができるかもしれません(ファイルではなくディレクトリを要求するだけです):
SSRF
XXEを使用してクラウド内でSSRFを悪用することができます
Blind SSRF
以前にコメントされたテクニックを使用すると、サーバーにアクセスして脆弱性を表示することができます。しかし、それがうまくいかない場合は、おそらくXMLエンティティが許可されていないためです。その場合は、XMLパラメータエンティティを使用してみることができます。
"Blind" SSRF - データの外部バンドへの持ち出し
この場合、サーバーに新しい悪意のあるペイロードを含むDTDを読み込ませ、ファイルの内容をHTTPリクエスト経由で送信することにより、データを持ち出します(複数行のファイルの場合は、例えばxxe-ftp-server.rbを使用して_ftp://_経由で持ち出すことができます)。この説明は、こちらのPortswiggerのラボに基づいています。
悪意のあるDTDが与えられた場合、データを持ち出すために以下の手順が実行されます:
悪意のあるDTDの例:
構造は以下の通りです:
以下は、このDTDによって実行される手順です:
パラメータエンティティの定義:
XMLパラメータエンティティ
%file
が作成され、/etc/hostname
ファイルの内容を読み込みます。別のXMLパラメータエンティティ
%eval
が定義されます。これは新しいXMLパラメータエンティティ%exfiltrate
を動的に宣言します。%exfiltrate
エンティティは、%file
エンティティの内容をURLのクエリ文字列内で攻撃者のサーバーにHTTPリクエストするように設定されます。
エンティティの実行:
%eval
エンティティが使用され、%exfiltrate
エンティティの動的宣言が実行されます。%exfiltrate
エンティティが使用され、ファイルの内容を含む指定されたURLにHTTPリクエストがトリガーされます。
攻撃者は、この悪意のあるDTDを通常 http://web-attacker.com/malicious.dtd
のようなURLで自分の管理下のサーバーにホストします。
XXEペイロード: 脆弱なアプリケーションを悪用するために、攻撃者はXXEペイロードを送信します:
このペイロードはXMLパラメータエンティティ%xxe
を定義し、それをDTD内で組み込んでいます。XMLパーサーによって処理されると、このペイロードは攻撃者のサーバーから外部DTDを取得します。その後、パーサーはDTDをインラインで解釈し、悪意のあるDTDに記載された手順を実行し、/etc/hostname
ファイルの情報漏洩が攻撃者のサーバーにリードされます。
エラーベース(外部DTD)
この場合、サーバーに悪意のあるDTDを読み込ませ、エラーメッセージ内にファイルの内容を表示させます(エラーメッセージを見ることができる場合のみ有効です)。 こちらの例から。
悪意のある外部Document Type Definition(DTD)を使用して、XMLパースエラーメッセージをトリガーし、/etc/passwd
ファイルの内容を明らかにすることができます。これは以下の手順によって達成されます:
/etc/passwd
ファイルの内容を含むfile
という名前のXMLパラメータエンティティが定義されます。別のXMLパラメータエンティティ
error
のための動的宣言を組み込んだeval
という名前のXMLパラメータエンティティが定義されます。このerror
エンティティは評価されると、存在しないファイルを読み込もうとし、その名前としてfile
エンティティの内容を組み込みます。eval
エンティティが呼び出され、error
エンティティが動的に宣言されます。error
エンティティの呼び出しにより、存在しないファイルを読み込もうとする試みが行われ、/etc/passwd
ファイルの内容がファイル名の一部として含まれたエラーメッセージが生成されます。
悪意のある外部DTDは、以下のXMLで呼び出すことができます:
エラーベース(system DTD)
では、アウトオブバンドインタラクションがブロックされている(外部接続が利用できない)場合の盲目的なXXE脆弱性はどうなるでしょうか?。
XML言語仕様の抜け穴により、ドキュメントのDTDが内部および外部の宣言を混在させたときにエラーメッセージを通じて機密データが公開される可能性があります。この問題により、外部で宣言されたエンティティを内部で再定義することが可能となり、エラーベースのXXE攻撃を実行できます。このような攻撃は、外部DTDで元々宣言されたXMLパラメータエンティティを内部DTD内から再定義することを利用します。サーバーによってアウトオブバンド接続がブロックされている場合、攻撃者は攻撃を実行するためにローカルDTDファイルに依存する必要があり、パーシングエラーを誘発して機密情報を公開することを目指します。
サーバーのファイルシステムに/usr/local/app/schema.dtd
にあるDTDファイルが存在し、custom_entity
という名前のエンティティが定義されているとします。攻撃者は、次のようにハイブリッドDTDを送信することで、/etc/passwd
ファイルの内容を公開するXMLパーシングエラーを誘発することができます:
以下の手順は、このDTDによって実行されます:
local_dtd
という名前のXMLパラメータエンティティの定義に、サーバーのファイルシステムにある外部DTDファイルが含まれています。外部DTDで元々定義されていた
custom_entity
XMLパラメータエンティティの再定義が行われ、エラーベースのXXE攻撃をカプセル化するように設計されています。この再定義は、/etc/passwd
ファイルの内容を公開するためにパースエラーを引き起こすようになっています。local_dtd
エンティティを使用することで、外部DTDが参照され、新たに定義されたcustom_entity
が含まれます。これらのアクションの連続により、攻撃によって狙われるエラーメッセージが発生します。
実際の例: GNOMEデスクトップ環境を使用しているシステムでは、/usr/share/yelp/dtd/docbookx.dtd
に ISOamso
というエンティティが含まれています。
このテクニックでは、内部DTDを使用するため、まず有効なDTDを見つける必要があります。これを行うには、サーバーが使用しているOS/ソフトウェアをインストールして、いくつかのデフォルトDTDを検索するか、システム内のデフォルトDTDのリストを取得して、存在するかどうかを確認することができます。
詳細についてはhttps://portswigger.net/web-security/xxe/blindをチェックしてください。
システム内のDTDの検出
次の素晴らしいgithubリポジトリでは、システム内に存在する可能性のあるDTDのパスを見つけることができます:
さらに、被害者システムのDockerイメージを持っている場合、同じリポジトリのツールを使用してイメージをスキャンし、システム内に存在するDTDのパスを見つけることができます。詳細についてはgithubのReadmeを参照してください。
Office Open XMLパーサーを介したXXE
この攻撃の詳細については、この素晴らしい投稿の2番目のセクションをチェックしてください。
多くのWebアプリケーションがMicrosoft Officeドキュメントのアップロード機能を提供し、その後これらのドキュメントから特定の詳細を抽出します。たとえば、Webアプリケーションは、ユーザーがXLSX形式のスプレッドシートをアップロードしてデータをインポートすることを許可するかもしれません。パーサーがスプレッドシートからデータを抽出するためには、少なくとも1つのXMLファイルを解析する必要があります。
この脆弱性をテストするためには、XXEペイロードを含むMicrosoft Officeファイルを作成する必要があります。最初のステップは、ドキュメントを解凍できる空のディレクトリを作成することです。
ドキュメントを解凍した後、./unzipped/word/document.xml
にあるXMLファイルを好みのテキストエディタ(たとえばvim)で開いて編集する必要があります。 XMLを変更して、通常はHTTPリクエストで始まる所望のXXEペイロードを含める必要があります。
変更されたXML行は、2つのルートXMLオブジェクトの間に挿入する必要があります。リクエスト用の監視可能なURLでURLを置換することが重要です。
最後に、ファイルをzip化して悪意のあるpoc.docxファイルを作成できます。以前に作成した「unzipped」ディレクトリから、次のコマンドを実行する必要があります:
これで、作成したファイルを潜在的に脆弱なWebアプリケーションにアップロードし、Burp Collaboratorログにリクエストが表示されることを期待できます。
Jar: プロトコル
jarプロトコルは、Javaアプリケーション内でのみアクセス可能です。これは、PKZIPアーカイブ(例:.zip
、.jar
など)内のファイルアクセスを可能にするよう設計されており、ローカルおよびリモートファイルの両方に対応しています。
PKZIPファイル内のファイルにアクセスできると、system DTDファイルを経由してXXEを悪用するのに非常に便利です。こちらのセクションをチェックして、system DTDファイルを悪用する方法を学んでください。
PKZIPアーカイブ内のファイルにアクセスするプロセスは、jarプロトコルを介していくつかのステップが関与します:
指定された場所からzipアーカイブをダウンロードするためにHTTPリクエストが行われます。例:
https://download.website.com/archive.zip
。アーカイブを含むHTTPレスポンスは一時的にシステムに保存され、通常は
/tmp/...
のような場所に保存されます。アーカイブはその内容にアクセスするために展開されます。
アーカイブ内の特定のファイル、
file.zip
が読み取られます。このプロセス中に作成された一時ファイルは、操作の後に削除されます。
このプロセスを第2ステップで中断させる興味深いテクニックは、アーカイブファイルを提供する際にサーバー接続を無期限にオープンに保つことです。この目的のために利用できるツールには、Pythonサーバー(slow_http_server.py
)やJavaサーバー(slowserver.jar
)などが含まれています。このリポジトリで利用可能です。
一時ディレクトリにファイルを書き込むことは、ローカルファイルのインクルード、テンプレートインジェクション、XSLT RCE、逆シリアル化などの脆弱性をエスカレートさせるのに役立ちます。
XSS
DoS
ビリオン・ラフ攻撃
Yaml攻撃
二次の膨張攻撃
NTMLの取得
Windowsホストでは、responder.pyハンドラを設定することで、ウェブサーバーユーザーのNTMLハッシュを取得することが可能です。
そして、次のリクエストを送信することによって
隠されたXXEサーフェス
XInclude
サーバーサイドのXMLドキュメントにクライアントデータを統合する際、バックエンドのSOAPリクエストなどで、XML構造に対する直接的な制御がしばしば制限されるため、DOCTYPE
要素の変更に制限がある場合、従来のXXE攻撃が妨げられることがあります。しかし、XInclude
攻撃は、XMLドキュメントの任意のデータ要素内に外部エンティティを挿入することを可能にするため、解決策を提供します。この方法は、サーバーが生成したXMLドキュメント内のデータの一部のみを制御できる場合でも効果的です。
XInclude
攻撃を実行するには、XInclude
名前空間を宣言し、意図した外部エンティティのファイルパスを指定する必要があります。以下は、そのような攻撃をどのように構築できるかを簡潔に示した例です:
Check https://portswigger.net/web-security/xxe for more info!
SVG - ファイルのアップロード
ユーザーが特定のアプリケーションにアップロードしたファイルは、サーバーで処理されることがあり、XMLまたはXMLを含むファイル形式の処理方法に脆弱性を悪用する可能性があります。オフィスドキュメント(DOCX)や画像(SVG)などの一般的なファイル形式は、XMLに基づいています。
ユーザーが画像をアップロードすると、これらの画像はサーバーサイドで処理または検証されます。PNGやJPEGなどの形式を期待しているアプリケーションでも、サーバーの画像処理ライブラリはSVG画像もサポートしているかもしれません。XMLベースのフォーマットであるSVGは、攻撃者が悪意のあるSVG画像を送信して、サーバーをXXE(XML External Entity)の脆弱性にさらすことができます。
以下は、悪意のあるSVG画像がシステムファイルを読み取ろうとする例です:
別の方法は、PHPの「expect」ラッパーを介してコマンドを実行しようとすることです:
両方のインスタンスで、SVG形式が使用され、サーバーソフトウェアのXML処理機能を悪用する攻撃が発生するため、堅牢な入力検証とセキュリティ対策の必要性が強調されます。
詳細については、https://portswigger.net/web-security/xxe をチェックしてください!
注:ファイルの最初の行または実行結果の最初の行は、作成された画像の内部に表示されます。したがって、SVGが作成した画像にアクセスできる必要があります。
PDF - ファイルのアップロード
次の投稿を読んで、PDFファイルをアップロードしてXXEを悪用する方法を学んでください:
pagePDF Upload - XXE and CORS bypassContent-Type: x-www-urlencodedからXMLへ
POSTリクエストがXML形式のデータを受け入れる場合、そのリクエストでXXEを悪用しようとすることができます。たとえば、通常のリクエストに次の内容が含まれている場合:
その後、同じ結果を得るために、次のリクエストを送信できるかもしれません:
Content-Type: JSON から XEE へ
リクエストを変更するには、Content Type Converter という Burp 拡張機能を使用できます。こちら にこの例があります。
別の例はこちらにあります。
WAF & Protections Bypasses
Base64
これは、XMLサーバーがdata://
プロトコルを受け入れる場合にのみ機能します。
UTF-7
["Encode Recipe" of cyberchef here ]([https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)to]([https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to)) でUTF-7に変換できます。
ファイル:/ プロトコル バイパス
Web が PHP を使用している場合、file:/
の代わりに php wrappersphp://filter/convert.base64-encode/resource=
を使用して 内部ファイルにアクセス できます。
Web が Java を使用している場合は、jar: プロトコル をチェックできます。
HTML エンティティ
https://github.com/Ambrotd/XXE-Notes からのトリック エンティティ内にエンティティ を作成し、html エンティティ でエンコードしてから dtd を読み込む ことができます。 使用される HTML エンティティ は 数値 である必要があることに注意してください(この例のように [in this example](https://gchq.github.io/CyberChef/#recipe=To_HTML_Entity%28true,'Numeric entities'%29&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\)。
DTDの例:
PHP ラッパー
Base64
抽出 index.php
外部リソースの抽出
リモートコード実行
PHPの"expect"モジュールがロードされている場合
SOAP - XEE
XLIFF - XXE
この例は、https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxeを参考にしています。
XLIFF(XML Localization Interchange File Format)は、ローカライゼーションプロセスでのデータ交換を標準化するために使用されます。これは、主にローカライゼーション中にツール間でローカライズ可能なデータを転送するために使用されるXMLベースの形式であり、CAT(Computer-Aided Translation)ツールの共通の交換形式としても使用されます。
Blind Request Analysis
次の内容でサーバーにリクエストが行われます:
しかし、このリクエストは内部サーバーエラーを引き起こし、具体的にはマークアップ宣言に問題があると言及しています:
エラーが発生したにもかかわらず、外部エンティティとのある程度のやり取りがあることを示すBurp Collaboratorにヒットが記録されます。
データの帰送外部バンドデータを帰送するために、修正されたリクエストが送信されます:
このアプローチにより、User AgentがJava 1.8の使用を示していることが明らかになります。このJavaのバージョンの注目すべき制限事項は、改行文字を含むファイル(例:/etc/passwd)をOut of Bandテクニックを使用して取得できないことです。
エラーベースのデータエクスフィルトレーション この制限を克服するために、エラーベースのアプローチが採用されます。次のようにDTDファイルが構造化され、ターゲットファイルからデータを含むエラーがトリガーされます:
サーバーはエラーで応答し、重要なのは存在しないファイルを反映しており、サーバーが指定されたファイルにアクセスしようとしていることを示しています。
ファイルの内容をエラーメッセージに含めるために、DTDファイルを調整します:
この変更により、ファイルの内容が成功裏に外部流出され、HTTP経由で送信されるエラー出力に反映されます。これは、感
ファイルの読み取り
ソースコードを読む
PHPのbase64フィルターを使用
Java XMLDecoder XEE to RCE
XMLDecoderは、XMLメッセージに基づいてオブジェクトを作成するJavaクラスです。悪意のあるユーザーがアプリケーションに任意のデータを使用させてreadObjectメソッドを呼び出すことができれば、サーバーでコードを実行できます。
Runtime().exec()を使用
ProcessBuilder
ProcessBuilder
ツール
参考文献
独自の外部DTDを使用してHTTP経由で情報を抽出する: https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/\
Last updated