JWT Vulnerabilities (Json Web Tokens)
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
If you are interested in hacking career and hack the unhackable - we are hiring! (απαιτείται άριστη γνώση πολωνικών, γραπτά και προφορικά).
Part of this post is based in the awesome post: https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology Author of the great tool to pentest JWTs https://github.com/ticarpi/jwt_tool
Run jwt_tool with mode All Tests!
and wait for green lines
Αν είστε τυχεροί, το εργαλείο θα βρει κάποια περίπτωση όπου η διαδικτυακή εφαρμογή ελέγχει λανθασμένα το JWT:
Τότε, μπορείτε να αναζητήσετε το αίτημα στον μεσολαβητή σας ή να εξάγετε το χρησιμοποιούμενο JWT για εκείνο το αίτημα χρησιμοποιώντας το jwt_ tool:
Μπορείτε επίσης να χρησιμοποιήσετε την Burp Extension SignSaboteur για να εκτελέσετε επιθέσεις JWT από το Burp.
Μπορείτε απλώς να τροποποιήσετε τα δεδομένα αφήνοντας την υπογραφή ως έχει και να ελέγξετε αν ο διακομιστής ελέγχει την υπογραφή. Δοκιμάστε να αλλάξετε το όνομα χρήστη σας σε "admin" για παράδειγμα.
Για να ελέγξετε αν η υπογραφή ενός JWT επαληθεύεται:
Ένα μήνυμα σφάλματος υποδηλώνει ότι η επαλήθευση είναι σε εξέλιξη; ευαίσθητες λεπτομέρειες σε εκτενή σφάλματα θα πρέπει να εξεταστούν.
Μια αλλαγή στη σελίδα που επιστρέφεται υποδηλώνει επίσης επαλήθευση.
Καμία αλλαγή υποδηλώνει ότι δεν υπάρχει επαλήθευση; αυτό είναι το σημείο για να πειραματιστείτε με την τροποποίηση των αξιώσεων του payload.
Είναι σημαντικό να προσδιορίσετε αν το token δημιουργήθηκε από τον διακομιστή ή από τον πελάτη εξετάζοντας το ιστορικό αιτημάτων του proxy.
Τα tokens που παρατηρούνται πρώτα από την πλευρά του πελάτη υποδηλώνουν ότι το κλειδί μπορεί να είναι εκτεθειμένο σε κώδικα πελάτη, απαιτώντας περαιτέρω έρευνα.
Τα tokens που προέρχονται από τον διακομιστή υποδεικνύουν μια ασφαλή διαδικασία.
Ελέγξτε αν το token διαρκεί περισσότερο από 24 ώρες... ίσως να μην λήξει ποτέ. Αν υπάρχει ένα πεδίο "exp", ελέγξτε αν ο διακομιστής το χειρίζεται σωστά.
Ορίστε τον αλγόριθμο που χρησιμοποιείται ως "None" και αφαιρέστε το μέρος της υπογραφής.
Χρησιμοποιήστε την επέκταση Burp που ονομάζεται "JSON Web Token" για να δοκιμάσετε αυτήν την ευπάθεια και να αλλάξετε διάφορες τιμές μέσα στο JWT (στείλτε το αίτημα στο Repeater και στην καρτέλα "JSON Web Token" μπορείτε να τροποποιήσετε τις τιμές του token. Μπορείτε επίσης να επιλέξετε να ορίσετε την τιμή του πεδίου "Alg" σε "None").
Ο αλγόριθμος HS256 χρησιμοποιεί το μυστικό κλειδί για να υπογράψει και να επαληθεύσει κάθε μήνυμα. Ο αλγόριθμος RS256 χρησιμοποιεί το ιδιωτικό κλειδί για να υπογράψει το μήνυμα και χρησιμοποιεί το δημόσιο κλειδί για την αυθεντικοποίηση.
Αν αλλάξετε τον αλγόριθμο από RS256 σε HS256, ο κωδικός του back end χρησιμοποιεί το δημόσιο κλειδί ως το μυστικό κλειδί και στη συνέχεια χρησιμοποιεί τον αλγόριθμο HS256 για να επαληθεύσει την υπογραφή.
Στη συνέχεια, χρησιμοποιώντας το δημόσιο κλειδί και αλλάζοντας το RS256 σε HS256, θα μπορούσαμε να δημιουργήσουμε μια έγκυρη υπογραφή. Μπορείτε να ανακτήσετε το πιστοποιητικό του διακομιστή ιστού εκτελώντας αυτό:
Ένας επιτιθέμενος ενσωματώνει ένα νέο κλειδί στην κεφαλίδα του token και ο διακομιστής χρησιμοποιεί αυτό το νέο κλειδί για να επαληθεύσει την υπογραφή (CVE-2018-0114).
Αυτό μπορεί να γίνει με την επέκταση "JSON Web Tokens" του Burp. (Στείλτε το αίτημα στον Repeater, μέσα στην καρτέλα JSON Web Token επιλέξτε "CVE-2018-0114" και στείλτε το αίτημα).
Οι οδηγίες περιγράφουν μια μέθοδο για την αξιολόγηση της ασφάλειας των JWT tokens, ιδιαίτερα αυτών που χρησιμοποιούν μια δήλωση κεφαλίδας "jku". Αυτή η δήλωση θα πρέπει να συνδέεται με ένα αρχείο JWKS (JSON Web Key Set) που περιέχει το δημόσιο κλειδί που είναι απαραίτητο για την επαλήθευση του token.
Αξιολόγηση Tokens με "jku" Κεφαλίδα:
Επαληθεύστε το URL της δήλωσης "jku" για να διασφαλίσετε ότι οδηγεί στο κατάλληλο αρχείο JWKS.
Τροποποιήστε την τιμή "jku" του token για να κατευθυνθεί προς μια ελεγχόμενη διαδικτυακή υπηρεσία, επιτρέποντας την παρακολούθηση της κίνησης.
Παρακολούθηση για HTTP Αλληλεπίδραση:
Η παρακολούθηση των HTTP αιτημάτων προς το καθορισμένο URL σας υποδεικνύει τις προσπάθειες του διακομιστή να ανακτήσει κλειδιά από τον παρεχόμενο σύνδεσμο.
Όταν χρησιμοποιείτε το jwt_tool
για αυτή τη διαδικασία, είναι κρίσιμο να ενημερώσετε το αρχείο jwtconf.ini
με την προσωπική σας τοποθεσία JWKS για να διευκολύνετε τη δοκιμή.
Εντολή για jwt_tool
:
Εκτελέστε την παρακάτω εντολή για να προσομοιώσετε το σενάριο με το jwt_tool
:
Μια προαιρετική δήλωση κεφαλίδας γνωστή ως kid
χρησιμοποιείται για την αναγνώριση ενός συγκεκριμένου κλειδιού, το οποίο γίνεται ιδιαίτερα ζωτικής σημασίας σε περιβάλλοντα όπου υπάρχουν πολλαπλά κλειδιά για την επαλήθευση υπογραφής token. Αυτή η δήλωση βοηθά στην επιλογή του κατάλληλου κλειδιού για την επαλήθευση της υπογραφής ενός token.
Όταν η δήλωση kid
είναι παρούσα στην κεφαλίδα, συνιστάται να αναζητήσετε τον διαδικτυακό κατάλογο για το αντίστοιχο αρχείο ή τις παραλλαγές του. Για παράδειγμα, αν καθοριστεί "kid":"key/12345"
, θα πρέπει να αναζητηθούν τα αρχεία /key/12345 και /key/12345.pem στη ρίζα του διαδικτύου.
Η δήλωση kid
μπορεί επίσης να εκμεταλλευτεί για να πλοηγηθεί μέσα στο σύστημα αρχείων, επιτρέποντας ενδεχομένως την επιλογή ενός αυθαίρετου αρχείου. Είναι εφικτό να δοκιμάσετε τη συνδεσιμότητα ή να εκτελέσετε επιθέσεις Server-Side Request Forgery (SSRF) τροποποιώντας την τιμή kid
για να στοχεύσετε συγκεκριμένα αρχεία ή υπηρεσίες. Η παραποίηση του JWT για να αλλάξετε την τιμή kid
ενώ διατηρείτε την αρχική υπογραφή μπορεί να επιτευχθεί χρησιμοποιώντας την επιλογή -T
στο jwt_tool, όπως φαίνεται παρακάτω:
Με την στόχευση αρχείων με προβλέψιμο περιεχόμενο, είναι δυνατόν να παραχαραχθεί ένα έγκυρο JWT. Για παράδειγμα, το αρχείο /proc/sys/kernel/randomize_va_space
σε συστήματα Linux, γνωστό ότι περιέχει την τιμή 2, μπορεί να χρησιμοποιηθεί στην παράμετρο kid
με 2 ως το συμμετρικό κλειδί για τη δημιουργία JWT.
Εάν το περιεχόμενο της δήλωσης kid
χρησιμοποιείται για την ανάκτηση ενός κωδικού πρόσβασης από μια βάση δεδομένων, μπορεί να διευκολυνθεί μια SQL injection τροποποιώντας το payload του kid
. Ένα παράδειγμα payload που χρησιμοποιεί SQL injection για να αλλάξει τη διαδικασία υπογραφής JWT περιλαμβάνει:
non-existent-index' UNION SELECT 'ATTACKER';-- -
Αυτή η τροποποίηση αναγκάζει τη χρήση ενός γνωστού μυστικού κλειδιού, ATTACKER
, για την υπογραφή JWT.
Ένα σενάριο όπου η παράμετρος kid
καθορίζει μια διαδρομή αρχείου που χρησιμοποιείται σε ένα πλαίσιο εκτέλεσης εντολών θα μπορούσε να οδηγήσει σε ευπάθειες Remote Code Execution (RCE). Με την έγχυση εντολών στην παράμετρο kid
, είναι δυνατόν να εκτεθούν ιδιωτικά κλειδιά. Ένα παράδειγμα payload για την επίτευξη RCE και έκθεσης κλειδιών είναι:
/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&
jku σημαίνει JWK Set URL. Εάν το token χρησιμοποιεί μια δήλωση “jku” Header, τότε ελέγξτε τη διεύθυνση URL που παρέχεται. Αυτή θα πρέπει να δείχνει σε μια διεύθυνση URL που περιέχει το αρχείο JWKS που κρατά το Δημόσιο Κλειδί για την επαλήθευση του token. Τροποποιήστε το token ώστε να δείχνει την τιμή jku σε μια διαδικτυακή υπηρεσία που μπορείτε να παρακολουθείτε την κίνηση.
Πρώτα πρέπει να δημιουργήσετε ένα νέο πιστοποιητικό με νέα ιδιωτικά & δημόσια κλειδιά.
Στη συνέχεια, μπορείτε να χρησιμοποιήσετε για παράδειγμα jwt.io για να δημιουργήσετε το νέο JWT με τα δημιουργημένα δημόσια και ιδιωτικά κλειδιά και να δείξετε την παράμετρο jku στο πιστοποιητικό που δημιουργήθηκε. Για να δημιουργήσετε ένα έγκυρο πιστοποιητικό jku, μπορείτε να κατεβάσετε το αρχικό και να αλλάξετε τις απαραίτητες παραμέτρους.
Μπορείτε να αποκτήσετε τις παραμέτρους "e" και "n" από ένα δημόσιο πιστοποιητικό χρησιμοποιώντας:
X.509 URL. Ένα URI που δείχνει σε ένα σύνολο δημόσιων πιστοποιητικών X.509 (ένα πρότυπο μορφής πιστοποιητικού) κωδικοποιημένων σε μορφή PEM. Το πρώτο πιστοποιητικό στο σύνολο πρέπει να είναι αυτό που χρησιμοποιείται για την υπογραφή αυτού του JWT. Τα επόμενα πιστοποιητικά υπογράφουν το προηγούμενο, ολοκληρώνοντας έτσι την αλυσίδα πιστοποιητικών. Το X.509 ορίζεται στο RFC 52807. Η μεταφορά ασφάλειας απαιτείται για τη μεταφορά των πιστοποιητικών.
Δοκιμάστε να αλλάξετε αυτή την κεφαλίδα σε μια URL υπό τον έλεγχό σας και ελέγξτε αν ληφθεί κάποια αίτηση. Σε αυτή την περίπτωση, θα μπορούσατε να παραποιήσετε το JWT.
Για να κατασκευάσετε ένα νέο διακριτικό χρησιμοποιώντας ένα πιστοποιητικό που ελέγχετε, πρέπει να δημιουργήσετε το πιστοποιητικό και να εξαγάγετε τα δημόσια και ιδιωτικά κλειδιά:
Τότε μπορείτε να χρησιμοποιήσετε για παράδειγμα jwt.io για να δημιουργήσετε το νέο JWT με τα δημιουργημένα δημόσια και ιδιωτικά κλειδιά και να δείξετε την παράμετρο x5u στο πιστοποιητικό .crt που δημιουργήθηκε.
Μπορείτε επίσης να εκμεταλλευτείτε και τις δύο αυτές ευπάθειες για SSRFs.
Αυτή η παράμετρος μπορεί να περιέχει το πιστοποιητικό σε base64:
Εάν ο επιτιθέμενος δημιουργήσει ένα αυτο-υπογεγραμμένο πιστοποιητικό και δημιουργήσει ένα πλαστό token χρησιμοποιώντας το αντίστοιχο ιδιωτικό κλειδί και αντικαταστήσει την τιμή της παραμέτρου "x5c" με το νεοδημιουργηθέν πιστοποιητικό και τροποποιήσει τις άλλες παραμέτρους, δηλαδή n, e και x5t, τότε ουσιαστικά το πλαστό token θα γινόταν αποδεκτό από τον διακομιστή.
Αν το JWT έχει ενσωματωμένο ένα δημόσιο κλειδί όπως στο παρακάτω σενάριο:
Χρησιμοποιώντας το παρακάτω script nodejs είναι δυνατόν να παραχθεί ένα δημόσιο κλειδί από αυτά τα δεδομένα:
Είναι δυνατόν να δημιουργήσετε ένα νέο ιδιωτικό/δημόσιο κλειδί, να ενσωματώσετε το νέο δημόσιο κλειδί μέσα στο διακριτικό και να το χρησιμοποιήσετε για να δημιουργήσετε μια νέα υπογραφή:
Μπορείτε να αποκτήσετε το "n" και το "e" χρησιμοποιώντας αυτό το σενάριο nodejs:
Τελικά, χρησιμοποιώντας το δημόσιο και ιδιωτικό κλειδί και τις νέες τιμές "n" και "e", μπορείτε να χρησιμοποιήσετε το jwt.io για να πλαστογραφήσετε ένα νέο έγκυρο JWT με οποιαδήποτε πληροφορία.
Εάν ορισμένες εφαρμογές χρησιμοποιούν ES256 και χρησιμοποιούν τον ίδιο nonce για να δημιουργήσουν δύο jwts, το ιδιωτικό κλειδί μπορεί να αποκατασταθεί.
Εδώ είναι ένα παράδειγμα: ECDSA: Αποκάλυψη του ιδιωτικού κλειδιού, εάν χρησιμοποιηθεί ο ίδιος nonce (με SECP256k1)
Η αξίωση JTI (JWT ID) παρέχει έναν μοναδικό αναγνωριστικό για ένα JWT Token. Μπορεί να χρησιμοποιηθεί για να αποτρέψει την επανάληψη του token. Ωστόσο, φανταστείτε μια κατάσταση όπου το μέγιστο μήκος του ID είναι 4 (0001-9999). Οι αιτήσεις 0001 και 10001 θα χρησιμοποιήσουν το ίδιο ID. Έτσι, εάν το backend αυξάνει το ID σε κάθε αίτηση, θα μπορούσατε να εκμεταλλευτείτε αυτό για να επανεκτελέσετε μια αίτηση (χρειάζεται να στείλετε 10000 αιτήσεις μεταξύ κάθε επιτυχούς επανάληψης).
Επιθέσεις Διασύνδεσης Υπηρεσιών
Έχει παρατηρηθεί ότι ορισμένες διαδικτυακές εφαρμογές βασίζονται σε μια αξιόπιστη υπηρεσία JWT για τη δημιουργία και διαχείριση των tokens τους. Έχουν καταγραφεί περιπτώσεις όπου ένα token, που δημιουργήθηκε για έναν πελάτη από την υπηρεσία JWT, έγινε αποδεκτό από έναν άλλο πελάτη της ίδιας υπηρεσίας JWT. Εάν παρατηρηθεί η έκδοση ή ανανέωση ενός JWT μέσω μιας τρίτης υπηρεσίας, θα πρέπει να διερευνηθεί η δυνατότητα εγγραφής για έναν λογαριασμό σε έναν άλλο πελάτη αυτής της υπηρεσίας χρησιμοποιώντας το ίδιο όνομα χρήστη/ηλεκτρονικό ταχυδρομείο. Στη συνέχεια, θα πρέπει να γίνει μια προσπάθεια να επαναληφθεί το αποκτηθέν token σε μια αίτηση προς τον στόχο για να δούμε αν γίνεται αποδεκτό.
Ένα κρίσιμο ζήτημα μπορεί να υποδειχθεί από την αποδοχή του token σας, επιτρέποντας ενδεχομένως την πλαστογράφηση οποιουδήποτε λογαριασμού χρήστη. Ωστόσο, θα πρέπει να σημειωθεί ότι μπορεί να απαιτείται άδεια για ευρύτερη δοκιμή εάν εγγραφείτε σε μια τρίτη εφαρμογή, καθώς αυτό θα μπορούσε να εισέλθει σε μια νομική γκρίζα περιοχή.
Έλεγχος Λήξης Tokens
Η λήξη του token ελέγχεται χρησιμοποιώντας την αξίωση "exp" Payload. Δεδομένου ότι τα JWT χρησιμοποιούνται συχνά χωρίς πληροφορίες συνεδρίας, απαιτείται προσεκτική διαχείριση. Σε πολλές περιπτώσεις, η σύλληψη και η επανάληψη ενός άλλου χρήστη JWT θα μπορούσε να επιτρέψει την ταυτοποίηση αυτού του χρήστη. Το JWT RFC προτείνει την μείωση των επιθέσεων επανάληψης JWT χρησιμοποιώντας την αξίωση "exp" για να ορίσει μια ώρα λήξης για το token. Επιπλέον, η εφαρμογή σχετικών ελέγχων από την εφαρμογή για να διασφαλιστεί η επεξεργασία αυτής της τιμής και η απόρριψη των ληγμένων tokens είναι κρίσιμη. Εάν το token περιλαμβάνει μια αξίωση "exp" και οι περιορισμοί χρόνου δοκιμών το επιτρέπουν, συνιστάται η αποθήκευση του token και η επανάληψή του μετά την παρέλευση της ώρας λήξης. Το περιεχόμενο του token, συμπεριλαμβανομένης της ανάλυσης χρονικών σημείων και του ελέγχου λήξης (χρονικό σημείο σε UTC), μπορεί να διαβαστεί χρησιμοποιώντας την επιλογή -R του jwt_tool.
Ένας κίνδυνος ασφαλείας μπορεί να υπάρχει εάν η εφαρμογή εξακολουθεί να επικυρώνει το token, καθώς αυτό μπορεί να υποδηλώνει ότι το token δεν θα μπορούσε ποτέ να λήξει.
Εάν ενδιαφέρεστε για καριέρα hacking και να χακάρετε το αχάκωτο - προσλαμβάνουμε! (απαιτείται άπταιστη γραπτή και προφορική γνώση πολωνικών).
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)