PHP loadXML()で脆弱性を作り込む

XXE

PHPのloadXMLの使い方を間違えるとXXEの脆弱性を作ってしまうことになります。
HackTheBox AcademyのFileUploadAttacksの一部を例に脆弱性のソースコードを見ていきたいと思います。

これからやること

HackTheBox AcademyのFileUploadAttacksでXXEを使い取得したPHPのソースコードを見てみたいと思います。

今回学べること

  • PHPのloadXML()を使う時のセキュリティー上の注意点

脆弱性の箇所を確認

下記が問題のソースコードです。
displayHTMLImage()というメソッドでは引数で指定したImageFileのパスを読み込みHTMLに表示するタグを生成しています。
表示はmine_content_type()により処理が別れており、svgとxmlのときはloadXMLを使っています。

動作の解説

$doc->loadXML(file_get_contents($imageFile), LIBXML_NOENT | LIBXML_DTDLOAD);
  • $imageFile に指定されたファイルを 文字列 として取得。
  • loadXML() で解析。
  • LIBXML_NOENT により、 エンティティが展開 される。
  • LIBXML_DTDLOAD により、 外部 DTD が読み込まれる

直接的にはLIBXML_DTDLOADの部分により外部ファイルを読み込めてしまいXXEとなります。

XXE動作例

例えば、下記のように/etc/passwdファイルを読み込むsvgファイルを作成したとします。

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

すると作成されたHTML上は下記のようにファイルの内容が表示されています。

解決策

外部エンティティを無効化して、DTDLOAD を外すことでXXEを防ぐことは可能です。

libxml_disable_entity_loader(true);
$doc = new DOMDocument();
$doc->loadXML(file_get_contents($imageFile), LIBXML_NOENT);

または、そもそも LIBXML_NOENT 自体を使わず、安全な方法で XML を処理することを推奨します。

Hack The Box AcademyのFile Upload Attacks

今回の記事はHackTheBoxAcademyのFileUploadAttacksで学べることの一部です。
興味を持った方はHackTheBoxAcademyをやってみてください。

Best Online Cybersecurity Courses & Certifications | HTB Academy
Master cybersecurity with guided and interactive cybersecurity training courses and certifications (created by real hack...
タイトルとURLをコピーしました