JWT Vulnerabilities (Json Web Tokens)
Last updated
Last updated
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Se sei interessato a una carriera nel hacking e a hackare l'inhackabile - stiamo assumendo! (richiesta di polacco fluente scritto e parlato).
Parte di questo post si basa sul fantastico post: https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology Autore del grande strumento per pentestare i JWT https://github.com/ticarpi/jwt_tool
Esegui jwt_tool con modalità All Tests!
e aspetta le righe verdi.
Se sei fortunato, lo strumento troverà qualche caso in cui l'applicazione web controlla in modo errato il JWT:
Poi, puoi cercare la richiesta nel tuo proxy o scaricare il JWT utilizzato per quella richiesta usando jwt_ tool:
Puoi anche utilizzare l'Estensione Burp SignSaboteur per lanciare attacchi JWT da Burp.
Puoi semplicemente modificare i dati lasciando la firma così com'è e controllare se il server sta verificando la firma. Prova a cambiare il tuo nome utente in "admin", ad esempio.
Per verificare se la firma di un JWT viene verificata:
Un messaggio di errore suggerisce una verifica in corso; i dettagli sensibili negli errori dettagliati dovrebbero essere esaminati.
Un cambiamento nella pagina restituita indica anche una verifica.
Nessun cambiamento suggerisce nessuna verifica; è il momento di sperimentare con la modifica delle affermazioni del payload.
È importante determinare se il token è stato generato lato server o lato client esaminando la cronologia delle richieste del proxy.
I token visti per la prima volta dal lato client suggeriscono che la chiave potrebbe essere esposta al codice lato client, necessitando ulteriori indagini.
I token originati dal lato server indicano un processo sicuro.
Controlla se il token dura più di 24 ore... forse non scade mai. Se c'è un campo "exp", controlla se il server lo gestisce correttamente.
Imposta l'algoritmo utilizzato come "None" e rimuovi la parte della firma.
Utilizza l'estensione Burp chiamata "JSON Web Token" per provare questa vulnerabilità e per cambiare diversi valori all'interno del JWT (invia la richiesta a Repeater e nella scheda "JSON Web Token" puoi modificare i valori del token. Puoi anche selezionare di impostare il valore del campo "Alg" su "None").
L'algoritmo HS256 utilizza la chiave segreta per firmare e verificare ogni messaggio. L'algoritmo RS256 utilizza la chiave privata per firmare il messaggio e utilizza la chiave pubblica per l'autenticazione.
Se cambi l'algoritmo da RS256 a HS256, il codice di backend utilizza la chiave pubblica come chiave segreta e poi utilizza l'algoritmo HS256 per verificare la firma.
Quindi, utilizzando la chiave pubblica e cambiando RS256 in HS256, potremmo creare una firma valida. Puoi recuperare il certificato del server web eseguendo questo:
Un attaccante incorpora una nuova chiave nell'intestazione del token e il server utilizza questa nuova chiave per verificare la firma (CVE-2018-0114).
Questo può essere fatto con l'estensione "JSON Web Tokens" di Burp. (Invia la richiesta al Repeater, all'interno della scheda JSON Web Token seleziona "CVE-2018-0114" e invia la richiesta).
Le istruzioni dettagliano un metodo per valutare la sicurezza dei token JWT, in particolare quelli che utilizzano un'affermazione di intestazione "jku". Questa affermazione dovrebbe collegarsi a un file JWKS (JSON Web Key Set) che contiene la chiave pubblica necessaria per la verifica del token.
Valutazione dei Token con Intestazione "jku":
Verifica l'URL dell'affermazione "jku" per assicurarti che porti al file JWKS appropriato.
Modifica il valore "jku" del token per indirizzarlo verso un servizio web controllato, consentendo l'osservazione del traffico.
Monitoraggio per Interazione HTTP:
Osservare le richieste HTTP al tuo URL specificato indica i tentativi del server di recuperare le chiavi dal link fornito.
Quando si utilizza jwt_tool
per questo processo, è fondamentale aggiornare il file jwtconf.ini
con la tua posizione JWKS personale per facilitare il test.
Comando per jwt_tool
:
Esegui il seguente comando per simulare lo scenario con jwt_tool
:
Un'affermazione di intestazione opzionale nota come kid
è utilizzata per identificare una chiave specifica, che diventa particolarmente vitale in ambienti in cui esistono più chiavi per la verifica della firma del token. Questa affermazione aiuta a selezionare la chiave appropriata per verificare la firma di un token.
Quando l'affermazione kid
è presente nell'intestazione, è consigliabile cercare nella directory web il file corrispondente o le sue variazioni. Ad esempio, se viene specificato "kid":"key/12345"
, i file /key/12345 e /key/12345.pem dovrebbero essere cercati nella radice web.
L'affermazione kid
potrebbe anche essere sfruttata per navigare attraverso il file system, consentendo potenzialmente la selezione di un file arbitrario. È possibile testare la connettività o eseguire attacchi di Server-Side Request Forgery (SSRF) modificando il valore kid
per mirare a file o servizi specifici. Alterare il JWT per cambiare il valore kid
mantenendo la firma originale può essere realizzato utilizzando il flag -T
in jwt_tool, come dimostrato di seguito:
By targeting files with predictable content, it's possible to forge a valid JWT. For instance, the /proc/sys/kernel/randomize_va_space
file in Linux systems, known to contain the value 2, can be used in the kid
parameter with 2 as the symmetric password for JWT generation.
If the kid
claim's content is employed to fetch a password from a database, an SQL injection could be facilitated by modifying the kid
payload. An example payload that uses SQL injection to alter the JWT signing process includes:
non-existent-index' UNION SELECT 'ATTACKER';-- -
This alteration forces the use of a known secret key, ATTACKER
, for JWT signing.
A scenario where the kid
parameter specifies a file path used within a command execution context could lead to Remote Code Execution (RCE) vulnerabilities. By injecting commands into the kid
parameter, it's possible to expose private keys. An example payload for achieving RCE and key exposure is:
/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&
jku stands for JWK Set URL. If the token uses a “jku” Header claim then controlla l'URL fornito. This should point to a URL containing the JWKS file that holds the Public Key for verifying the token. Tamper the token to point the jku value to a web service you can monitor traffic for.
First you need to create a new certificate with new private & public keys
Poi puoi usare ad esempio jwt.io per creare il nuovo JWT con le chiavi pubbliche e private create e puntando il parametro jku al certificato creato. Per creare un certificato jku valido, puoi scaricare quello originale e cambiare i parametri necessari.
Puoi ottenere i parametri "e" e "n" da un certificato pubblico usando:
X.509 URL. Un URI che punta a un insieme di certificati pubblici X.509 (uno standard di formato di certificato) codificati in forma PEM. Il primo certificato nell'insieme deve essere quello utilizzato per firmare questo JWT. I certificati successivi firmano ciascuno il precedente, completando così la catena di certificati. X.509 è definito in RFC 52807. La sicurezza del trasporto è necessaria per trasferire i certificati.
Prova a cambiare questo header in un URL sotto il tuo controllo e verifica se viene ricevuta qualche richiesta. In tal caso, potresti manomettere il JWT.
Per forgiare un nuovo token utilizzando un certificato controllato da te, devi creare il certificato ed estrarre le chiavi pubbliche e private:
Poi puoi usare ad esempio jwt.io per creare il nuovo JWT con le chiavi pubbliche e private create e puntando il parametro x5u al certificato .crt creato.
Puoi anche abusare di entrambe queste vulnerabilità per SSRFs.
Questo parametro può contenere il certificato in base64:
Se l'attaccante genera un certificato autofirmato e crea un token contraffatto utilizzando la corrispondente chiave privata e sostituisce il valore del parametro "x5c" con il certificato appena generato e modifica gli altri parametri, ovvero n, e e x5t, allora essenzialmente il token contraffatto verrebbe accettato dal server.
Se il JWT ha incorporato una chiave pubblica come nel seguente scenario:
Utilizzando il seguente script nodejs è possibile generare una chiave pubblica da quei dati:
È possibile generare una nuova chiave privata/pubblica, incorporare la nuova chiave pubblica all'interno del token e utilizzarla per generare una nuova firma:
Puoi ottenere "n" ed "e" utilizzando questo script nodejs:
Finalmente, utilizzando la chiave pubblica e privata e i nuovi valori "n" ed "e", puoi utilizzare jwt.io per forgiare un nuovo JWT valido con qualsiasi informazione.
Se alcune applicazioni utilizzano ES256 e usano lo stesso nonce per generare due jwt, la chiave privata può essere ripristinata.
Ecco un esempio: ECDSA: Rivelare la chiave privata, se viene utilizzato lo stesso nonce (con SECP256k1)
Il claim JTI (JWT ID) fornisce un identificatore unico per un token JWT. Può essere utilizzato per prevenire la ripetizione del token. Tuttavia, immagina una situazione in cui la lunghezza massima dell'ID è 4 (0001-9999). Le richieste 0001 e 10001 utilizzeranno lo stesso ID. Quindi, se il backend incrementa l'ID ad ogni richiesta, potresti abusare di questo per ripetere una richiesta (necessitando di inviare 10000 richieste tra ogni ripetizione riuscita).
Attacchi di Relay Cross-service
È stato osservato che alcune applicazioni web si affidano a un servizio JWT fidato per la generazione e gestione dei loro token. Sono stati registrati casi in cui un token, generato per un cliente dal servizio JWT, è stato accettato da un altro cliente dello stesso servizio JWT. Se si osserva l'emissione o il rinnovo di un JWT tramite un servizio di terze parti, dovrebbe essere indagata la possibilità di registrarsi per un account su un altro cliente di quel servizio utilizzando lo stesso nome utente/email. Dovrebbe quindi essere fatto un tentativo di ripetere il token ottenuto in una richiesta al target per vedere se viene accettato.
Un problema critico potrebbe essere indicato dall'accettazione del tuo token, potenzialmente consentendo la falsificazione dell'account di qualsiasi utente. Tuttavia, va notato che potrebbe essere necessaria l'autorizzazione per test più ampi se ci si registra su un'applicazione di terze parti, poiché questo potrebbe entrare in un'area grigia legale.
Controllo di Scadenza dei Token
La scadenza del token viene controllata utilizzando il claim "exp" Payload. Dato che i JWT vengono spesso impiegati senza informazioni di sessione, è necessaria una gestione attenta. In molti casi, catturare e ripetere il JWT di un altro utente potrebbe consentire l'impostazione di quell'utente. L'RFC JWT raccomanda di mitigare gli attacchi di ripetizione JWT utilizzando il claim "exp" per impostare un tempo di scadenza per il token. Inoltre, è cruciale l'implementazione di controlli pertinenti da parte dell'applicazione per garantire l'elaborazione di questo valore e il rifiuto dei token scaduti. Se il token include un claim "exp" e i limiti di tempo di test lo consentono, si consiglia di memorizzare il token e ripeterlo dopo che il tempo di scadenza è passato. Il contenuto del token, inclusa l'analisi del timestamp e il controllo della scadenza (timestamp in UTC), può essere letto utilizzando il flag -R di jwt_tool.
Potrebbe essere presente un rischio per la sicurezza se l'applicazione continua a convalidare il token, poiché potrebbe implicare che il token non potrebbe mai scadere.
Se sei interessato a una carriera nel hacking e a hackare l'inhackabile - stiamo assumendo! (richiesta di polacco fluente scritto e parlato).
Impara e pratica il Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica il Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)