tags: API_Hacking JWT_Hacking JWT_Cracking_Secret_Key
Questo attacco è rilevante quando il JWT è firmato utilizzando un algoritmo di firma simmetrico, come HS256, HS384, o HS512. Questi algoritmi simmetrici utilizzano la stessa “secret key” sia per firmare il JWT (generare la firma) che per verificarlo (controllare se la firma è valida).
Cracking della secret key
Recupera un JWT Valido dall’API Target
Per poter tentare di crackare la secret key, hai bisogno di un JWT valido emesso dall’API target. Come ottenerlo? Dipende dall’applicazione, ma i metodi più comuni sono:
- Autenticazione Normale: Se l’applicazione ha un form di login (username/password), usa le tue credenziali (o crea un account di test se permesso) per autenticarti. Dopo il login di successo, l’applicazione dovrebbe restituire un JWT (di solito nell’header
Authorization: Bearer ...o in un cookie). Questo è lo scenario più tipico. - Registrazione Utente: Se l’applicazione permette la registrazione di nuovi utenti, registrati e poi autenticati per ottenere un JWT.
- JWT Fornito per Test: In alcuni contesti di CTF o ambienti di test (come TryHackMe), potresti trovare un JWT valido già fornito come parte dell’esercizio o recuperabile in modo semplice.
Esempio
Supponiamo di aver effettuato il login con successo sull’API target e di aver recuperato questo JWT (ipotetico) dall’header Authorization: Bearer ...:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoidXNlciIsImlhdCI6MTY3ODg4NjQwMCwiZXhwIjoxNjc4ODkwMDAwfQ.ViusA3LqjFa7giZxC9s7vgk1mxva-Jw5o51QvE0zYJoSalva il JWT che hai recuperato in un file di testo. Ad esempio, crea un file chiamato token.jwt e copia dentro l’intero JWT dopo averlo salvato possiamo utilizzare Hashcat per provare a crackarlo tramite un attacco a dizionario dove per dizionario possiamo utilizzare o delle wordlist tipo Rockyou, SecList oppure una specifica per i JWT chiamata jwt.secrets.list:
hashcat -m 16500 token.jwt wordlists/jwt.secrets.listDove:
-
hashcat: Invoca il programma Hashcat. -
-m 16500: Specifica la modalità di hash da usare.16500è il numero di modalità per JWT (JSON Web Token) in Hashcat. Questa modalità dice ad Hashcat che stiamo attaccando una firma JWT e che deve provare a crackare la secret key. -
token.jwt: Il file contenente il JWT che vogliamo crackare (il file che abbiamo creato al passo 2). -
wordlists/jwt.secrets.list: Il percorso alla wordlist che Hashcat userà per l’attacco di dizionario. Sostituisciwordlists/jwt.secrets.listcon il percorso effettivo alla tua wordlist. -
Hashcat inizierà a provare a firmare il JWT con ogni parola della wordlist come secret key, e a confrontare la firma risultante con la firma del JWT originale. Questo processo può richiedere tempo, a seconda della lunghezza e complessità della wordlist e della potenza di calcolo del tuo sistema.
Se l’attacco ha successo puoi vedere il risultato in un formato simile a questo:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoidXNlciIsImlhdCI6MTY3ODg4NjQwMCwiZXhwIjoxNjc4ODkwMDAwfQ.ViusA3LqjFa7giZxC9s7vgk1mxva-Jw5o51QvE0zYJo:**la_secret_key_crackata**Nel caso non riuscissi a vederla puoi anche provare con il comando:
hashcat -m 16500 token.jwt wordlists/jwt.secrets.list --showDove **la_secret_key_crackata** sarà la secret key che Hashcat ha trovato.
Se Hashcat non trova la secret key (dopo aver provato tutte le parole nella wordlist), vedrai un output diverso che indica che non sono state trovate corrispondenze (Status: Exhausted, o qualcosa di simile). In questo caso, l’attacco di cracking con quella wordlist è fallito, il che non significa necessariamente che la secret key sia forte, ma solo che non è presente nella wordlist usata.
Creazione del Payload
Ora che abbiamo la secret key possiamo crearci un nostro payload modificato in modo da ottenere maggiori privilegi, lo possiamo fare tramite il sito https://jwt.io/ oppure codificando ogni messaggio JSON i base64
Il payload esatto dipende da come l’applicazione gestisce i ruoli e i permessi. Potrebbe essere admin: true, isAdmin: 1, un array di ruoli, etc. Analizza il JWT originale per capire quali claim sono rilevanti per l’autorizzazione e come sono strutturati
La cosa importante da capire è che l’header e il payload del messaggio JSON possono essere codificati e decodificati con un semplice convertitore base64, ma la chiave no, la chiave ha bisogno di una funzione che generi un hash specifico e quindi non basta convertire la secret key in base64 per ottenere un nuovo payload. Quindi per generare il payload modificato possiamo farlo o tramite il sito https://jwt.io/ che però è molto restrittivo e per esercitazioni come quelle di TryHackMe non va bene perchè come minimo vuole una password di 32 Byte oppure possiamo utilizzare il seguente programma Python:
import jwt
payload = { #Il payload lo devi sostituire con il tuo
"username": "admin",
"role": "administrator"
}
secret_key = "secret" # Qua è dove devi inserire la secret key (anche se corta)
algorithm = "HS256"
jwt_token = jwt.encode(payload, secret_key, algorithm=algorithm)
print(jwt_token)Assicurati di avere PyJWT installato: pip install pyjwt.
Questo script genererà un JWT con la secret key “secret” e payload admin, anche se la chiave è corta, senza darti l’avviso di jwt.io.
Invio del Payload
Ora che abbiamo creato il payload falsificato lo possiamo mandare al server tramite il seguente comando:
curl -H 'Authorization: Bearer [JWT_FALSIFICATO_ADMIN]' http://[API_ENDPOINT]/endpoint_admin_onlySe l’attacco ha successo e hai creato un JWT admin valido, la risposta dall’API dovrebbe indicare che l’accesso è stato autorizzato con privilegi amministrativi. La risposta esatta dipende dall’API (potrebbe essere un codice di stato 200 OK con dati amministrativi, un messaggio di successo specifico per gli admin, l’accesso a funzionalità che prima erano negate, etc.). Se ottieni successo, hai dimostrato la vulnerabilità di secret key debole e la possibilità di elevazione di privilegi tramite JWT falsificati.