
Cracker di forza bruta per JWT scritto in C
Un cracker JWT multi-thread per brute-force scritto in C. Se sei molto fortunato o hai una potenza di calcolo enorme, questo programma dovrebbe trovare la chiave segreta di un token JWT, permettendoti di forgiare token validi. Questo è solo a scopo di test, non metterti nei guai :)
Ho usato l'implementazione Base64 di Apple che ho leggermente modificato.
docker build . -t jwtcrack
docker run -it --rm jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
Assicurati di avere installati gli header di openssl.
Su Ubuntu puoi installarli con apt-get install libssl-dev
make
Se usi un Mac, puoi installare OpenSSL con brew install openssl, ma gli header saranno memorizzati in una
posizione diversa:
make OPENSSL=/usr/local/opt/openssl/include OPENSSL_LIB=-L/usr/local/opt/openssl/lib
$ > ./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
Le seguenti funzioni hash sono supportate per HMAC, cioè per generare codici di autenticazione dei messaggi con chiave: "sha256" per JSON HS256 (HMAC usando SHA-256), "sha384" per HS384 e "sha512" per HS512, rispettivamente. Puoi specificare il nome di qualsiasi altra funzione hash esattamente come è nominata in OpenSSL. Se OpenSSL permette a questa funzione hash di essere usata per HMAC, allora jwtcrack proverà a decodificare il segreto. Tuttavia, poiché jwtcrack è solo un decodificatore, non c'è garanzia che questo algoritmo sia stato effettivamente utilizzato per la codifica, figuriamoci tra l'elenco di algoritmi consentiti per il documento "JSON Web Algorithms" RFC. Vedi la sezione 3.1. dell'RFC 7518 per maggiori dettagli.
Nell'esempio seguente, usiamo una funzione hash sha256 che corrisponde a JSON HS256 (HMAC-SHA256), vedi "sha256" come ultimo parametro della riga di comando. Inoltre, in questo esempio specifichiamo una lunghezza massima del segreto di 5 caratteri e limitiamo l'alfabeto ai seguenti caratteri: ABCSNFabcsnf1234
$ > ./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE ABCSNFabcsnf1234 5 sha256
Nell'esempio sopra, la chiave è Sn1f, e ci vuole meno di un secondo su un notebook medio prodotto intorno al 2019 (ad esempio con una CPU Intel basata su microarchitettura Ice Lake). GCC versione 9.3.0 con "-O3" è stato usato per compilare il programma jwtcrack. È stato linkato con la libreria OpenSSL versione 1.1.1f sotto Linux Ubuntu 20.04.1 LTS.
Qui, nel prossimo esempio, usiamo "sha512" come ultimo parametro della riga di comando per specificare HS512 (HMAC-SHA512), specifichiamo anche una lunghezza massima del segreto di 9 caratteri e limitiamo l'alfabeto ai seguenti sette caratteri latini minuscoli: "adimnps".
$ > ./jwtcrack eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJyb2xlIjoiYWRtaW4ifQ.RnWtv7Rjggm8LdMU3yLnz4ejgGAkIxoZwsCMuJlHMwTh7CJODDZWR8sVuNvo2ws25cbH9HWcp2n5WxpIZ9_v0g adimnps 9 sha512
Nell'esempio sopra, la chiave è adminpass, e ci vogliono circa 15 secondi in media per decodificare su un notebook con CPU Intel Core i7 1065G7 su microarchitettura Ice Lake (2019), frequenza base 1.30 GHz, turbo massimo 3.90 GHz). Il numero totale di secondi CPU consumati da ciascuno dei core in modalità utente a causa del multithreading è di circa 100 in media per decodificare quel segreto.
Esempio di utilizzo di "sha384":
$ > ./jwtcrack eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJyb2xlIjoiYWRtaW4ifQ.31xCH3k8VRqB8l5qBy7RyqI2htyCskBy_4cIWpk3o43UkIMW-IcjTUEL_NyFXUWJ 0123456789 6 sha384
/usr/bin/time -f "Total number of CPU-seconds consumed directly from each of the CPU cores: %U\nElapsed real wall clock time used by the process: %E" ./jwtcrack eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJyb2xlIjoiYWRtaW4ifQ.RnWtv7Rjggm8LdMU3yLnz4ejgGAkIxoZwsCMuJlHMwTh7CJODDZWR8sVuNvo2ws25cbH9HWcp2n5WxpIZ9_v0g adimnps 9 sha512
L'implementazione Base64 che uso (da Apple) a volte è difettosa perché non tutte le implementazioni Base64 sono uguali. Quindi a volte, la decodifica del tuo token Base64 funzionerà solo parzialmente e quindi sarai in grado di trovare un segreto per il tuo token che non è quello corretto.
Se qualcuno volesse implementare un'implementazione Base64 più robusta, sarebbe fantastico :)