JWT Vulnerabilities (Json Web Tokens)
Last updated
Last updated
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
ハッキングキャリアに興味があり、ハッキング不可能なものをハッキングしたい方 - 私たちは採用しています! (流暢なポーランド語の読み書きが必要です)。
この記事の一部は素晴らしい投稿に基づいています: https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology JWTをペンテストするための素晴らしいツールの作者 https://github.com/ticarpi/jwt_tool
jwt_toolをAll Tests!
モードで実行し、緑のラインを待ちます。
運が良ければ、ツールはウェブアプリケーションがJWTを不正にチェックしているケースを見つけるでしょう:
その後、プロキシでリクエストを検索するか、jwt_ toolを使用してそのリクエストで使用されたJWTをダンプできます:
You can also use the Burp Extension SignSaboteurを使用して、BurpからJWT攻撃を実行できます。
署名をそのままにしてデータを改ざんし、サーバーが署名を確認しているかどうかをチェックできます。例えば、ユーザー名を「admin」に変更してみてください。
JWTの署名が検証されているかどうかを確認するには:
エラーメッセージが継続的な検証を示唆している場合、詳細なエラーに含まれる機密情報を確認する必要があります。
返されたページの変更も検証を示します。
変更がない場合は検証が行われていないことを示唆します。この場合、ペイロードの主張を改ざんする実験を行うべきです。
トークンがサーバー側で生成されたのか、クライアント側で生成されたのかを、プロキシのリクエスト履歴を調べて判断することが重要です。
クライアント側から最初に見られたトークンは、キーがクライアント側のコードに露出している可能性があるため、さらなる調査が必要です。
サーバー側から発生したトークンは、安全なプロセスを示します。
トークンが24時間以上持続するかどうかを確認してください...もしかしたら期限が切れないかもしれません。「exp」フィールドがある場合、サーバーがそれを正しく処理しているかどうかを確認してください。
使用するアルゴリズムを「None」に設定し、署名部分を削除します。
Burp拡張機能「JSON Web Token」を使用して、この脆弱性を試し、JWT内の異なる値を変更します(リクエストをリピーターに送信し、「JSON Web Token」タブでトークンの値を変更できます。「Alg」フィールドの値を「None」に設定することもできます)。
アルゴリズムHS256は、秘密鍵を使用して各メッセージに署名し、検証します。 アルゴリズムRS256は、プライベートキーを使用してメッセージに署名し、公開鍵を認証に使用します。
アルゴリズムをRS256からHS256に変更すると、バックエンドコードは公開鍵を秘密鍵として使用し、その後HS256アルゴリズムを使用して署名を検証します。
次に、公開鍵を使用し、RS256をHS256に変更することで、有効な署名を作成できます。これを実行して、ウェブサーバーの証明書を取得できます:
攻撃者はトークンのヘッダーに新しい鍵を埋め込み、サーバーはこの新しい鍵を使用して署名を検証します (CVE-2018-0114)。
これは「JSON Web Tokens」Burp拡張機能を使用して行うことができます。 (リクエストをリピーターに送信し、JSON Web Tokenタブ内で「CVE-2018-0114」を選択してリクエストを送信します)。
この手順は、特に「jku」ヘッダー主張を使用するJWTトークンのセキュリティを評価する方法を詳述しています。この主張は、トークンの検証に必要な公開鍵を含むJWKS(JSON Web Key Set)ファイルにリンクする必要があります。
「jku」ヘッダーを持つトークンの評価:
「jku」主張のURLを確認して、適切なJWKSファイルにリンクしていることを確認します。
トークンの「jku」値を変更して、制御されたWebサービスに向け、トラフィックを観察できるようにします。
HTTPインタラクションの監視:
指定したURLへのHTTPリクエストを観察することで、サーバーが提供されたリンクから鍵を取得しようとしていることがわかります。
このプロセスにjwt_tool
を使用する際は、テストを容易にするために、jwtconf.ini
ファイルを個人のJWKSの場所で更新することが重要です。
jwt_tool
のコマンド:
次のコマンドを実行して、jwt_tool
でシナリオをシミュレートします:
オプションのヘッダー主張であるkid
は、特定の鍵を識別するために使用され、トークン署名検証のために複数の鍵が存在する環境では特に重要です。この主張は、トークンの署名を検証するために適切な鍵を選択するのに役立ちます。
ヘッダーにkid
主張が存在する場合、対応するファイルまたはそのバリエーションをウェブディレクトリで検索することが推奨されます。たとえば、"kid":"key/12345"
が指定されている場合、ファイル_/key/12345_および_/key/12345.pem_をウェブルートで検索する必要があります。
kid
主張は、ファイルシステムをナビゲートするために悪用される可能性があり、任意のファイルを選択できる可能性があります。特定のファイルやサービスをターゲットにするためにkid
値を変更することで、接続性をテストしたり、サーバーサイドリクエストフォージェリ(SSRF)攻撃を実行することが可能です。元の署名を保持しながらkid
値を変更するためにJWTを改ざんすることは、以下のように-T
フラグを使用して達成できます:
ファイルの予測可能な内容をターゲットにすることで、有効なJWTを偽造することが可能です。たとえば、Linuxシステムの/proc/sys/kernel/randomize_va_space
ファイルは、値2を含むことで知られており、JWT生成の対称パスワードとして2を使用してkid
パラメータに利用できます。
kid
クレームの内容がデータベースからパスワードを取得するために使用される場合、kid
ペイロードを変更することでSQLインジェクションが可能になります。JWT署名プロセスを変更するためにSQLインジェクションを使用する例のペイロードは次のとおりです:
non-existent-index' UNION SELECT 'ATTACKER';-- -
この変更により、JWT署名に既知の秘密鍵ATTACKER
が使用されることになります。
kid
パラメータがコマンド実行コンテキスト内で使用されるファイルパスを指定するシナリオは、リモートコード実行(RCE)脆弱性につながる可能性があります。kid
パラメータにコマンドを注入することで、秘密鍵を露出させることが可能です。RCEと鍵の露出を達成するための例のペイロードは次のとおりです:
/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&
jkuはJWK Set URLを表します。 トークンが“jku”ヘッダークレームを使用している場合は、提供されたURLを確認してください。これは、トークンを検証するための公開鍵を保持するJWKSファイルを含むURLを指す必要があります。トークンを改ざんして、jku値を監視できるWebサービスにポイントさせます。
まず、新しい秘密鍵と公開鍵を持つ新しい証明書を作成する必要があります。
次に、例えば jwt.io を使用して、作成した公開鍵と秘密鍵を使用し、パラメータ jku を作成した証明書にポイントします。 有効な jku 証明書を作成するには、元の証明書をダウンロードし、必要なパラメータを変更できます。
公開証明書から "e" と "n" のパラメータを取得するには、次のようにします:
X.509 URL。PEM形式でエンコードされた一連のX.509(証明書フォーマット標準)公開証明書を指すURI。セット内の最初の証明書は、このJWTに署名するために使用されるものでなければなりません。次の証明書はそれぞれ前の証明書に署名し、証明書チェーンを完成させます。X.509はRFC 52807で定義されています。証明書を転送するには、トランスポートセキュリティが必要です。
このヘッダーをあなたの管理下にあるURLに変更して、リクエストが受信されるか確認してください。その場合、JWTを改ざんすることができるかもしれません。
あなたが制御する証明書を使用して新しいトークンを偽造するには、証明書を作成し、公開鍵と秘密鍵を抽出する必要があります:
その後、例えば jwt.io を使用して、作成した公開鍵と秘密鍵を使用し、パラメータ x5u を作成した .crt 証明書にポイントします。
これらの脆弱性の両方をSSRFに悪用することもできます。
このパラメータにはbase64形式の証明書が含まれる場合があります:
攻撃者が自己署名証明書を生成し、対応する秘密鍵を使用して偽造トークンを作成し、「x5c」パラメータの値を新しく生成した証明書に置き換え、他のパラメータ、つまり n、e、x5t を修正すれば、基本的に偽造トークンはサーバーによって受け入れられます。
JWTに次のシナリオのように埋め込まれた公開鍵がある場合:
次のnodejsスクリプトを使用すると、そのデータから公開鍵を生成することができます:
新しいプライベート/パブリックキーを生成し、新しいパブリックキーをトークン内に埋め込み、それを使用して新しい署名を生成することが可能です:
このnodejsスクリプトを使用して「n」と「e」を取得できます:
最終的に、公開鍵と秘密鍵、そして新しい「n」と「e」の値を使用して、jwt.ioを使って任意の情報を持つ新しい有効なJWTを偽造できます。
いくつかのアプリケーションがES256を使用し、同じノンスを使用して2つのJWTを生成する場合、秘密鍵を復元できます。
ここに例があります: ECDSA: 同じノンスを使用した場合の秘密鍵の明らかにする (SECP256k1使用)
JTI (JWT ID)クレームは、JWTトークンの一意の識別子を提供します。これは、トークンの再生を防ぐために使用できます。 しかし、IDの最大長が4(0001-9999)である状況を想像してください。リクエスト0001と10001は同じIDを使用します。したがって、バックエンドが各リクエストでIDをインクリメントしている場合、これを悪用してリクエストを再生することができます(各成功した再生の間に10000リクエストを送信する必要があります)。
クロスサービスリレー攻撃
いくつかのWebアプリケーションがトークンの生成と管理のために信頼されたJWTサービスに依存していることが観察されています。JWTサービスによって1つのクライアントのために生成されたトークンが、同じJWTサービスの別のクライアントによって受け入れられた事例が記録されています。サードパーティサービスを介してJWTの発行または更新が観察された場合、同じユーザー名/メールを使用してそのサービスの別のクライアントにアカウントを登録する可能性を調査する必要があります。その後、取得したトークンをターゲットへのリクエストで再生して受け入れられるかどうかを確認する試みを行うべきです。
あなたのトークンが受け入れられることによって重大な問題が示される可能性があり、これにより任意のユーザーアカウントの偽装が可能になるかもしれません。ただし、サードパーティアプリケーションにサインアップする場合、より広範なテストの許可が必要になる可能性があるため、これは法的なグレーゾーンに入る可能性があります。
トークンの有効期限チェック
トークンの有効期限は「exp」ペイロードクレームを使用してチェックされます。JWTはセッション情報なしで使用されることが多いため、慎重な取り扱いが必要です。多くの場合、他のユーザーのJWTをキャプチャして再生することで、そのユーザーのなりすましが可能になることがあります。JWT RFCは、トークンの有効期限を設定するために「exp」クレームを利用してJWT再生攻撃を軽減することを推奨しています。さらに、この値の処理と期限切れトークンの拒否を確実にするために、アプリケーションによる関連チェックの実装が重要です。トークンに「exp」クレームが含まれており、テストの時間制限が許可される場合、有効期限が過ぎた後にトークンを保存して再生することが推奨されます。トークンの内容、タイムスタンプの解析および有効期限のチェック(UTCのタイムスタンプを含む)は、jwt_toolの-Rフラグを使用して読み取ることができます。
アプリケーションがトークンをまだ検証している場合、トークンが決して期限切れにならないことを示唆する可能性があるため、セキュリティリスクが存在するかもしれません。
ハッキングキャリアに興味があり、ハッキング不可能なものをハッキングしたい方 - 私たちは採用しています! (流暢なポーランド語の読み書きが必要です)。
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングを学び、実践する: HackTricks Training GCP Red Team Expert (GRTE)