
CVE-2026-61500 の Python PoC と Docker ラボ: Rejetto HFS V8 の PRNG 状態を復元して管理者セッション Cookie を偽造し、server_code を介して RCE を達成します。
CVE-2026-61500 は、Rejetto HFS 3.0.0 から 3.2.0 にかけて存在する未認証のセッション偽造脆弱性です。HFS は Koa のセッション Cookie 署名鍵を JavaScript の Math.random() で生成し、さらに未認証の SRP ログインハンドシェイクにおいて同一の V8 PRNG の出力を露出していました。攻撃者は PRNG の状態を再構築し、署名鍵を復元し、管理者セッションを偽造し、文書化されている server_code 設定機能を利用してサーバーサイド JavaScript を実行できます。
このリポジトリには、Python による概念実証と、公式の HFS 3.2.0 および 3.2.1 イメージを使用した使い捨ての Docker 比較環境が含まれています。公開ビルドは、意図的にローカルループバックインターフェース上の HTTP ターゲットに限定されています。
| 項目 | 状態 |
|---|---|
| 未認証のログイン応答から V8 xorshift128+ の状態を復元 | 確認済み |
| アクティブな HFS Cookie 署名鍵を復元 | 確認済み |
| HFS 管理者として受け入れられるセッションを偽造 | 確認済み |
公式 HFS 3.2.0 で無害な server_code マーカーを実行 | 確認済み |
| 分離された Compose ネットワーク内で root リバースシェルを取得 | 確認済み |
| 公式 HFS 3.2.1 ではセッション偽造の前に停止 | 確認済み |
| インターネット全体を対象とした攻撃や永続化 | 提供も主張もしていない |
admin アカウントに対して、未認証の loginSrp1 API リクエストを 6 回送信します。脆弱な各応答は、数値の loggingIn.sid とその署名済みセッション Cookie を Set-Cookie ヘッダーに含めます。randomId(30) で使用される 3 つの base-36 チャンクを再現します。PoC は V8 の最短文字列表現の丸めを考慮し、候補を観測された hfs_http.sig HMAC と照合します。これにより起動オフセットも特定されます。username: admin を含む合成セッションに署名し、get_config を呼び出して、偽造された Cookie が管理者アクセス権を持つことを証明します。server_code モジュールを指定して set_config を呼び出します。デフォルトのペイロードは /data に無害なマーカーを書き込みます。--command はループバック Docker ラボでのみ使用可能です。これはブラックボックスの HTTP チェーンです。PoC はターゲットからファイル、メモリ、環境変数、プロセス状態を読み取りません。ソースの知識は、脆弱なアルゴリズムをモデル化するために使用されています。
59472e534bf7e056d708382d02935c2eaf956927。この修正は、署名鍵を Node.js の randomBytes() による 32 バイトに置き換え、露出していた数値のログイン識別子を randomUUID() に置き換えます。明示的に強力な COOKIE_SIGN_KEYS 値を指定することで署名鍵の予測は緩和されますが、アップグレードが依然として推奨される修復策です。
rejetto/hfs:v3.2.0、ダイジェスト
sha256:d6765e93b68de222583be7788afad699695fd08aa2f56377337f5139779e0746。rejetto/hfs:v3.2.1、ダイジェスト
sha256:61db4da1f494df254aa7f48889c676b424b413e45b7b92cf4276f4b8e632aaec。python:3.13-alpine、ダイジェスト
sha256:1a63a53928ce53d2b0baf08092a703f4840ac5dfbd61fd48802dbf48e08c801e。両方の HFS サービスはホストのループバックにのみバインドされ、コールバックはポートを公開しません。ラボは合成の管理者を作成します。これは loginSrp1 が既存のユーザー名に対して呼び出される必要があるためです。パスワードは exploit によって知られることも使用されることもありません。
必要なものは Docker と Compose、Python 3.10 以降、および curl です。
./verify.sh
検証スクリプトは lab/runtime/vulnerable と lab/runtime/fixed のみを削除し、両方のダイジェスト固定イメージを起動し、ポジティブコントロールとネガティブコントロールを実行し、デフォルトでコンテナを停止します。検査のためにラボを起動したままにするには、KEEP_LAB=1 ./verify.sh を使用します。
ラボを保持した状態で、無害なマーカーを直接実行するには次のようにします。
python3 cve-2026-61500-poc.py \
--target http://127.0.0.1:28182 \
--marker cve-2026-61500-rce-marker.txt
所有するラボコンテナ内でコマンド実行を実証するには次のようにします。
python3 cve-2026-61500-poc.py \
--target http://127.0.0.1:28182 \
--command 'id > /data/cve-command-output.txt'
非ループバックのホスト名、HTTPS ターゲット、またはリモート IP は引数検証によって拒否されます。この exploit は HFS の server_code を変更します。使い捨てのラボ、または明示的な許可を得たシステムにのみ使用してください。
記録されたデモはさらに一歩進みます。demo.sh は Compose ネットワーク上で非公開の callback サービスを起動し、--command を使用して Bash リバースシェルをそれに接続します。コールバックは id、uname -a、pwd、exit のみを送信し、無視される lab/runtime/ 以下にトランスクリプトを記録して閉じます。コールバックポートはホストにバインドされません。
2026-09-26 の実際の実行では、1 つの PRNG 状態とその署名鍵を復元し、偽造された管理者 get_config に対して HTTP 200 を受信し、マーカーペイロードをインストールし、脆弱なコンテナ内で CVE_2026_61500_RCE_CONFIRMED を観測しました。別の --command 'id > /data/cve-command-output.txt' コントロールは、その公式コンテナ内で uid=0(root) gid=0(root) groups=0(root) を生成しました。記録された Docker 専用のリバースシェルは、独立して同じ root アイデンティティと /data 作業ディレクトリを返しました。3.2.1 に対しては、最初のログイン応答に不透明な UUID が含まれており、PoC はセッション偽造を試みる前にステータス 3 で終了しました。docs/example-output.txt と docs/e2e-results.json を参照してください。
2026-09-26 に、正確な CVE および exploit/PoC の検索を SearchSploit (ローカルの Exploit-DB インデックス)、GitHub でインデックスされた Web 結果、Packet Storm、Exploit-DB、および一般の Web に対して実行しました。その時点では、動作する公開 exploit は特定されませんでした。見つかった結果は CVE/アドバイザリのメタデータと exploit 追跡ページのみでした。これは日付付きのベストエフォートの結果であり、他の場所に exploit が存在し得ない、または後で出現し得ないという主張ではありません。
<[email protected]>
(Twitter: @aramosf)。許可されたセキュリティ研究、防御的検証、および教育のみを目的としています。許可の取得と適用法の遵守はあなたの責任です。