Giter VIP home page Giter VIP logo

c-jwt-cracker's Introduction

JWT cracker

A multi-threaded JWT brute-force cracker written in C. If you are very lucky or have a huge computing power, this program should find the secret key of a JWT token, allowing you to forge valid tokens. This is for testing purposes only, do not put yourself in trouble :)

I used the Apple Base64 implementation that I modified slightly.

Build a Docker Image

docker build . -t jwtcrack

Run on Docker

docker run -it --rm  jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE

Manual Compilation

Make sure you have openssl's headers installed. On Ubuntu you can install them with apt-get install libssl-dev

make

If you use a Mac, you can install OpenSSL with brew install openssl, but the headers will be stored in a different location:

make OPENSSL=/usr/local/opt/openssl/include OPENSSL_LIB=-L/usr/local/opt/openssl/lib

Run

$ > ./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE

Run with different HMAC functions

The following hash functions are supported for HMAC, i.e. to generate keyed-hashed message authentication codes: "sha256" for JSON HS256 (HMAC using SHA-256), "sha384" for HS384 and "sha512" for HS512, respectively. You can specify the name of any other hash function exactly as it is named in the OpenSSL. If OpenSSL allows this hash function to be used for HMAC, then jwtcrack will try to decode the secret. However, since jwtcrack is only a decoder, there is no guarantee that this algorithm was actually used for encoding, let alone among the list of algorithms allowed for the "JSON Web Algorithms" RFC. See section 3.1. of the RFC 7518 for more details.

In the following example, we use a sha256 hash function that corresponds to JSON HS256 (HMAC-SHA256), see the "sha256" as a last command line parameter. Also, in this example we specify maximum secret length of 5 characters, and limit the alphabet to the following characters: ABCSNFabcsnf1234

$ > ./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE ABCSNFabcsnf1234 5 sha256

In the above example, the key is Sn1f, and it takes less than a second on an average notebook manufactured around 2019 (e.g. with an Intel CPU based on Ice Lake microarchitecture). GCC version 9.3.0 with "-O3" was used to compile the jwtcrack program. It was linked with the OpenSSL library version 1.1.1f under Linux Ubuntu 20.04.1 LTS.

Here, in the next example, we use "sha512" as a last command line parameter to specify HS512 (HMAC-SHA512), we also specify maximum secret length of 9 characters, and limit the alphabet to the following seven lowercase latin characters: "adimnps".

$ > ./jwtcrack eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJyb2xlIjoiYWRtaW4ifQ.RnWtv7Rjggm8LdMU3yLnz4ejgGAkIxoZwsCMuJlHMwTh7CJODDZWR8sVuNvo2ws25cbH9HWcp2n5WxpIZ9_v0g adimnps 9 sha512

In the above example, the key is adminpass, and it takes about 15 seconds on average to decode on a notebook with Intel Core i7 1065G7 CPU on Ice Lake microarchitecture (2019), base frequency 1.30 GHz, max turbo 3.90 GHz). The combined number of CPU seconds consumed from each of the cores in the user mode due to multithreading is about 100 on average to decode that secret.

Example of using "sha384":

$ > ./jwtcrack eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJyb2xlIjoiYWRtaW4ifQ.31xCH3k8VRqB8l5qBy7RyqI2htyCskBy_4cIWpk3o43UkIMW-IcjTUEL_NyFXUWJ 0123456789 6 sha384

Measurement of time consumed by jwtcrack

/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

Contribute

  • No progress status
  • If you stop the program, you cannot start back where you were

IMPORTANT: Known bugs

The base64 implementation I use (from Apple) is sometimes buggy because not every Base64 implementation is the same. So sometimes, decrypting of your Base64 token will only work partially and thus you will be able to find a secret to your token that is not the correct one.

If someone is willing to implement a more robust Base64 implementation, that would be great :)

c-jwt-cracker's People

Contributors

brendan-rius avatar dszczyt avatar mvmendes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

c-jwt-cracker's Issues

Algorithm does not work with truly random binary keys

Currently, the default alphabet is eariotnslcudpmhgbfywkvxzjqEARIOTNSLCUDPMHGBFYWKVXZJQ0123456789.

If the key is a truly random byte array (as it should be if the JWT signing implementation is secure...), the bruteforce algorithm does not work, as it only checks for bytes matching the code point of the character in the alphabet, in the locale's encoding (so for the default alphabet, possible byte value ranges are 0x30-0x39, 0x41-0x5A and 0x61-0x7A). Thus, even the simple 1-byte 0x00 key is not detected by the algorithm.

You can specify a custom alphabet as an optional parameter of the program, but the parameter being itself a string in the machine's current locale, you can't bruteforce keys which use bytes translating to non-printable characters.

Issues

Your code needs to add OpenSSL_add_all_digests () in main.c; Otherwise, EVP_get_digestbyname () will return as a NULL pointer. Causes the program to fail to run normally.
您的代码需要在main.c中添加OpenSSL _ add _ all _ digest();否则,EVP_get_digestbyname()将作为空指针返回。导致程序无法正常运行。

Unable to install

I am running on Macbook M2 Pro and I have installed OpenSSL by brew install openssl

Then I ran the make command like the following:

$ make OPENSSL=/usr/local/opt/openssl/include OPENSSL_LIB=-L/usr/local/opt/openssl/lib

And I got this error

gcc -I /usr/local/opt/openssl/include -g -std=gnu99 -O3 -I/opt/homebrew/opt/openjdk/include  -c -o main.o main.c
main.c:13:10: fatal error: 'openssl/evp.h' file not found
#include <openssl/evp.h>
         ^~~~~~~~~~~~~~~
1 error generated.
make: *** [main.o] Error 1

Can anyone help me?

Mac instructions did not work for me

On my mac those instructions did not work. I had to do

make OPENSSL=/usr/local/opt/openssl/include and replace -lssl for -L/usr/local/opt/openssl/lib in the Makefile.

brew link openssl says
Warning: Refusing to link: openssl
Linking keg-only openssl means you may end up linking against the insecure,
deprecated system OpenSSL while using the headers from Homebrew's openssl.
Instead, pass the full include/library paths to your compiler e.g.:
-I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib

./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
Secret is "Sn1f"
Time taken 8 seconds 990 milliseconds

EVP_get_digestbyname returns null

When I run the software on Ubuntu 18.04, I get this error message:

Cannot initialize the default message digest sha256, aborting

Following the Linux Die manual at https://linux.die.net/man/3/evp_get_digestbyname:

EVP_get_digestbyname(), EVP_get_digestbynid() and EVP_get_digestbyobj() return an EVP_MD structure when passed a digest name, a digest NID or an ASN1_OBJECT structure respectively. The digest table must be initialized using, for example, OpenSSL_add_all_digests() for these functions to work.

Following the instructions from the manual, I added OpenSSL_add_all_digests(); before line 203 in main.c and it works.

I'll open a PR when I have time.

More Optimization

More optimization

Multi-processing:

You can optimize more by using multiprocessing instead of using multi-threading .
You can get result more quickly if you do this through multi-processing (i.e., run code on parallel CPUs).
This is because if you are going towards multi-threading then you are giving OS to schedule the threads but in practical you can only run threads equal to CPU number of system. So, you just wasting time of program by Process scheduling.
If you can use multi-processing way, then it will be better optimized. You can test the results.

Hardware SHA extension

Other then that you can also use hardware SHA extension if it is available in CPU. https://en.wikipedia.org/wiki/Intel_SHA_extensions

Thanks, hope above suggestion will help and make better code.

How long does it take to decrypt?

eyJhbGciOiJBMjU2S1ciLCJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIn0.y2qOedKZ9ARDRplnqi_BKF4xNFRT_efQP_UnzcgQGyLZ34z8rbtoyg.uZUm__embCk8O75x.T45_PBiTnEm81KHomFnVdZeekbW7wrSiGXCIVgUV54y8X5gwI6GI6TWdCHTJuyQo7P4RHNhF4USlOUkBJmUozo_XAUWdEd7QKNPDfo-Udw9Ih1Ah8cLBUaJGZbbjVLrphbeu-QPZc_1qi4F80ehzDOEITCjKE0MhW1CdJtxfHOVtWAnIc2bck_jFhDe4AkO-jB1VmpsO210CPx3I7jAO4GdQDpKvehF3iN1MnU9nJE9uMnWsFHnjEHGhrR12fdf5RPGqi03NsENkfYhTYTIfq4GEAgGStQndRUaRJjHWvWDOv8d_BBOMmNh-PByCb-nTdqCQ5wZyEujRQw05mX0USePdJBMJNAhVTrayeewvVQHopECXnAD8S0qK9GMNcTh29caTs1EsHwXtP3-Qier-6rOaVZlQwkd0sMk7CI_KWUyClF3bjAhx8zqyjanTYmwoZ1c2VqBheFydUE7SQjWPUOBB_cx7tXe2l_Z8XLRwT_cJWLCnrLShBg5DzHpEiT74wTSmvx8Q5OAtwnkdGYJezRZiF6sNSjckiq-E3lo_ZlTXL58aG_Ph0mByJ9R-IrguiPN6ICu6rlJZ0e63lWD2qKXyD7Rj86MEhl_X42ntGPQUhugwb4dNaTvB8jWMaW3mDJtfbHeuPknemYEnNdq_d3R0gfaM0FQZcrxLgDLIHcpflu4O3aotxIVZ5Z89H5TJQmB_adZce8KQ4mQafvPMBu6Ebwq7wYiJp8DilrHSwzlRUYCsUG-0NsRGI07liqDeoIKsf4ZUi-no7GOrWRkfUH_dceZ5lGi1nRr85Cmxvz9YJmEe5Cc0OT0JT3R36S1y910M_WQ7srwz4IA.BKR51ksUIxmLeYWMY632Lw

not working

are you sure that your tool is still working?

Build failed on Ubuntu 18.04

gcc -o jwtcrack main.o base64.o -lssl -lcrypto -lpthread
/usr/bin/ld: base64.o: relocation R_X86_64_32S against `.rodata' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
Makefile:16: recipe for target 'jwtcrack' failed
make: *** [jwtcrack] Error 1

I have this error when build with Ubuntu 18.04, please help

crash at main.c:230

Starting program: /tmp/c-jwt-cracker/jwtcrack eyJhbGciOiJuIiwiZCI6IkpEZ0xjUnNaRDNFSUt5NG1KUWtMY0JzWmNYdz0ifQ
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x000055555555567f in main (argc=<optimised out>, argv=<optimised out>) at main.c:230
230		g_payload_b64_len = strlen(g_payload_b64);
(gdb) bt
#0  0x000055555555567f in main (argc=<optimised out>, argv=<optimised out>) at main.c:230
(gdb) 

Add Progress, Minlength and verbose mode

As many other users requested, a progress indicator and a min-length option would be helpful.

Maybe a verbose mode where you can see what words are tested would be cool ;)

Wrong secret found

Have a look at this token

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6IjlhbnZ4QGhpdGJ0cy5jb20iLCJpc3N1ZWQiOjE1MTE4NzUyNDg5NDYsImZyb21JUCI6IjEwMy4yNTIuMjAyLjEzNSJ9.7IWrW_E7raEajHOHCB44YYgX_9RbfUALTwQehFeGcs4

The cracker give me Zzfu as a secret, which is invalid.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.