6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめてのアドベントカレンダーAdvent Calendar 2024

Day 9

JWTをハッキングしてみる

Last updated at Posted at 2024-12-25

はじめに

こんにちは!
株式会社BTMの畑です。
今回はJWTの取得から、中身のチェック、権限をハッキングして改竄するところまでをやってみます。

本記事で紹介する手法は、セキュリティ検証を目的として自分自身が管理するWebシステムに対してのみ実施してください。
他者のシステムや許可を得ていない環境に対して行うことは不正アクセス禁止法等の法律に違反し、犯罪となります。絶対に行わないでください。

そもそもJWTって?

JWTとは「JSON Web Token」の略で、情報をJSON形式で安全にやり取りするための標準規格です。
RFC7519で定義されています。
主にユーザー認証やセッション管理に使用されます。

↓実際のJWTはこのような見た目で、パッと見は何か分からない見た目になっています。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibmFtZSI6ImJ0bV9oYXRhIiwiaWF0IjoxMjM0NTY3ODkwfQ.ynJxQmc0Ik0Y9yu7CPwX82Rn0rCVs9i4A8T8x6wLvMA

JWTの構成

JWTは以下の3つのパートで構成されています。

  • ヘッダー (Header)
    • トークンのタイプと使用している署名アルゴリズムを指定
  • ペイロード (Payload)
    • 実際に送信したいデータ(クレーム)を含む
  • 署名 (Signature)
    • トークンが改竄されていないことを確認するための署名

これらの3つのパートはそれぞれBase64でエンコードされ、ドット(.)で区切られて1つの文字列として表現されます。

JWTの一般的な使用場面

  • ユーザー認証: ログイン後のセッション管理に使用され、ユーザーの認証状態を維持します。
  • シングルサインオン(SSO): 複数のサービス間で共通の認証情報を共有する際に利用されます。
  • APIアクセストークン: RESTful APIのアクセス制御やクライアント認証に使用されます。

などなど、Webサービスの様々な場面で利用されています。

JWTの利点

  • ステートレス認証が可能(サーバーでセッション情報を保持する必要がない)
  • スケーラビリティが高い(サーバー間での状態共有が不要)
  • クロスドメインでの認証が容易

ただし、セキュリティ面では適切な実装と運用が重要になります。
署名の検証や有効期限の設定、適切な暗号化アルゴリズムの選択などが必要不可欠です。

JWTをハッキングしてみる

事前準備

簡単に動作確認できるようにPHPの処理を作成しました。

 jwt-demo/
  ├── index.php      # ログイン処理
  ├── admin.php      # 管理ページ
  └── functions.php  # 共通関数

ざっくりと以下の機能を用意しています。

  • ユーザー名とパスワードでログイン認証する。
  • 認証成功時に対象アカウントの権限ロールをJWTで返す。
  • 管理ページにアクセスする際にJWTの権限ロールを確認し、権限があれば表示し、権限がなければ非表示にする。

今回の確認用に最低限の実装となっています。そのまま利用すると脆弱性等のリスクがありますのでご注意ください。

まずはJWTを取得します

用意している一般ユーザー(user / user123 )アカウントでログインしてみます。

http://localhost/jwt-demo/index.php

image.png

すると以下のJWTが返ってきました。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqd3QtZGVtbyIsImlhdCI6MTczNDg1OTM5OSwiZXhwIjoxNzM0ODYyOTk5LCJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoidXNlciJ9.GDZ5586GkZRLiZwNEBi8O3aRyKBzOsGXmyrBq_bB214

image.png

取得したJWTをjwt.ioでデコードしてみます。

image.png

JWTがデコードされて右側に表示されます。

署名アルゴリズムはHS256が使われて、ペイロードにユーザー名(username)とロール(role)があることが分かります。

このロールを書き換えることができれば、管理者権限のページにアクセスできるかもしれません。

まずはこのJWTのままで、管理者ページにアクセスしてみます。

管理者ページにアクセスしてみる

さっき取得したJWTをリクエストのAuthorizationヘッダーにセットしてPOSTします。

http://localhost/jwt-demo/admin.php

image.png

残念ながら、アクセスできませんでした。

image.png

{"error":"Forbidden"}

では、ペイロードのユーザー名とロールを admin にしてみます。

image.png

jwt.ioのデコード側を書き換えるとエンコード側も自動的に更新されます。

このJWTだとどうでしょうか?

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqd3QtZGVtbyIsImlhdCI6MTczNDg1OTM5OSwiZXhwIjoxNzM0ODYyOTk5LCJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIn0.EPSwhNNLnAKi5aXcBR_F0c4lmA89Y7X5q-lGlXtJeJI

さっきと同じようにJWTをリクエストのAuthorizationヘッダーにセットしてPOSTします。

http://localhost/jwt-demo/admin.php

image.png

{"error":"Forbidden"}

ダメでした。

さすがにそんな簡単じゃないですね。。
「あ、どうも、adminです」と言っていれば、入れてしまう認証だと意味がないので当たり前っちゃ当たり前ですね。

シークレットキーをハッキング

最初にJWTを確認したときに署名アルゴリズムでHS256が使われていることを確認しています。

つまり何かの鍵(シークレットキー)で署名されているので、いくらロールを改竄したとしても、署名検証で不正なJWTと判定されてアクセスできません。

であれば、そのシークレットキーが分かればアクセスできそうですね。

総当たりツール

ここではオープンソースのパスワードクラックツールのJohn the Ripperを利用します。

パスワード管理やセキュリティを考える際に、攻撃者がどのようにパスワードを解読するかを知っておくことは重要です。

John the Ripper は教育目的や自社のセキュリティチェックを目的として使用することを推奨します。
他者の端末やシステムから許可を得ずに情報を取得する行為は、法律に違反する可能性があります。使用する際は、必ず管理者から許可を得た情報、またはご自身で作成した情報に対してのみ使用してください。

今回は以下のWindows版を使用しました。

1.9.0-jumbo-1 64-bit Windows binaries

取得したJWTをテキストファイルにコピペして、jwt.txtとして保存します。

作成したjwt.txtを解読対象としてJohn the Ripperを動かします。

PS C:\john-1.9.0-jumbo-1-win64\run> john.exe jwt.txt
Using default input encoding: UTF-8
Loaded 1 password hash (HMAC-SHA256 [password is key, SHA256 256/256 AVX2 8x])
Will run 16 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/run/password.lst, rules:Wordlist
demo             (?)
1g 0:00:00:00 DONE 2/3 (2024-12-23 12:14) 47.61g/s 1560Kp/s 1560Kc/s 1560KC/s 123456..skyline!
Use the "--show" option to display all of the cracked passwords reliably
Session completed

今回は検証用に単純なシークレットキーを設定しているので、あっという間に特定されました。

AIによるパスワード解析も発展しており日々解析速度が速くなっています。
複雑で長いキーにすることと合わせて、JWTの有効期限を適切に設定することも重要です。
参考:AIによるパスワードの解析時間をセキュリティ会社が公開。8桁なら7時間以内に解析完了

では、特定されたシークレットキーを入力してJWTを改竄します。

image.png

そして出来上がったJWTをリクエストのAuthorizationヘッダーにセットしてPOSTします。

http://localhost/jwt-demo/admin.php

image.png

{"message":"Welcome to the admin page!"}

やりました!
管理者ページにアクセスできました!

まとめ

JWTを使用する際の注意点

  • 機密情報の扱い
    • ペイロードは暗号化されていないため、機密情報は含めないようにする。
  • セキュアな鍵を設定
  • 有効期限の設定
    • JWTには適切な有効期限を設定し、長期間の使用を避ける。

おわりに

今回はJWTをハッキングしてみることで仕組みを確認しました。
JWTは適切に実装・運用することで安全で効率的な認証・認可の仕組みを提供できます。
セキュリティを確保しながら、モダンなWebアプリケーション開発に活用していきましょう。

株式会社BTMではエンジニアの採用をしております。
ご興味がある方はぜひコチラをご覧ください。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?