
Cで書かれたJWTブルートフォースクラッカー
Cで書かれたマルチスレッドのJWTブルートフォースクラッカーです。非常に幸運であるか、膨大な計算能力を持っている場合、このプログラムはJWTトークンの秘密鍵を見つけ出し、有効なトークンを偽造できるようにします。これはテスト目的のみであり、トラブルに巻き込まれないようにしてください :)
わずかに修正した Apple Base64実装 を使用しています。
docker build . -t jwtcrack
docker run -it --rm jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
opensslのヘッダーがインストールされていることを確認してください。
Ubuntuでは apt-get install libssl-dev でインストールできます。
make
Macを使用している場合、brew install openssl でOpenSSLをインストールできますが、ヘッダーは別の場所に保存されます。
make OPENSSL=/usr/local/opt/openssl/include OPENSSL_LIB=-L/usr/local/opt/openssl/lib
$ > ./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
HMAC(鍵付きハッシュメッセージ認証コードを生成するため)でサポートされているハッシュ関数は以下の通りです:JSON HS256(HMAC-SHA256)用の"sha256"、HS384用の"sha384"、HS512用の"sha512"です。OpenSSLで指定されている名前とまったく同じように、他のハッシュ関数の名前を指定することもできます。OpenSSLがこのハッシュ関数をHMACで使用することを許可している場合、jwtcrackは秘密鍵の解読を試みます。ただし、jwtcrackは単なるデコーダであるため、このアルゴリズムが実際にエンコードに使用されたという保証はなく、ましてや"JSON Web Algorithms" RFCで許可されているアルゴリズムのリストに含まれているかどうかも不明です。詳細はRFC 7518のセクション3.1を参照してください。
次の例では、JSON HS256(HMAC-SHA256)に対応するsha256ハッシュ関数を使用します。最後のコマンドラインパラメータとして"sha256"を指定してください。また、この例では秘密鍵の最大長を5文字に指定し、アルファベットを次の文字に限定します:ABCSNFabcsnf1234
$ > ./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE ABCSNFabcsnf1234 5 sha256
上記の例では、鍵は Sn1f であり、2019年頃に製造された平均的なノートパソコン(例えばIce LakeマイクロアーキテクチャベースのIntel CPU搭載)で1秒未満で処理されます。jwtcrackプログラムのコンパイルにはGCCバージョン9.3.0("-O3"付き)が使用されました。Linux Ubuntu 20.04.1 LTS上でOpenSSLライブラリバージョン1.1.1fとリンクされています。
次に、最後のコマンドラインパラメータとして"sha512"を使用してHS512(HMAC-SHA512)を指定します。また、秘密鍵の最大長を9文字に指定し、アルファベットを次の7つの小文字ラテン文字に限定します:"adimnps"。
$ > ./jwtcrack eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJyb2xlIjoiYWRtaW4ifQ.RnWtv7Rjggm8LdMU3yLnz4ejgGAkIxoZwsCMuJlHMwTh7CJODDZWR8sVuNvo2ws25cbH9HWcp2n5WxpIZ9_v0g adimnps 9 sha512
上記の例では、鍵は adminpass であり、Intel Core i7 1065G7 CPU(Ice Lakeマイクロアーキテクチャ、2019年、ベース周波数1.30 GHz、最大ターボ3.90 GHz)搭載のノートパソコンで平均約15秒かかります。マルチスレッドによるユーザーモードでの各コアからの合計CPU秒数は、その秘密鍵を解読するのに平均約100秒です。
"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
私が使用している(Apple製の)Base64実装は、すべてのBase64実装が同じではないため、時々バグがあります。 そのため、Base64トークンの復号が部分的にしか機能せず、正しくない秘密鍵が見つかってしまうことがあります。
より堅牢なBase64実装を実装してくれる人がいれば、素晴らしいのですが :)