
CVE-2026-10795を再現するDockerラボ:UpdraftPlus UpdraftCentralの認証バイパスを連鎖させてプラグインをインストールし、RCEを実現します。脆弱/パッチ適用済みターゲット、PoCエクスプロイト、ソースレベルのウォークスルーが含まれています。
このリポジトリには、UpdraftPlus WordPress プラグインの UpdraftCentral リモート通信レイヤーに影響を与える、未認証の認証バイパス脆弱性である CVE-2026-10795 を再現・検証するためのローカル Docker ラボが含まれています。
脆弱な動作は UpdraftCentral の RPC メッセージ処理フローに存在します。脆弱なバージョンでは、偽造された format=1 RPC メッセージが署名検証をバイパスし、失敗する RSA 復号パスを引き起こしつつ、予測可能な null キー/null IV の動作で対称復号に到達できます。これにより、巧妙に細工された暗号化 RPC メッセージが UpdraftCentral コマンドとして受け入れられ、ディスパッチされる可能性があります。
このラボでは、2 つの UpdraftPlus バージョンを比較しています:
| Service | UpdraftPlus version | Purpose | URL |
|---|---|---|---|
vuln | 1.26.4 | 脆弱な比較対象 | http://127.0.0.1:8081 |
patched | 1.26.5 | パッチ適用済みの比較対象 | http://127.0.0.1:8082 |
実証されるチェーンは次のとおりです:```text Unauthenticated attacker → forged UpdraftCentral RPC request → format=1 signature verification bypass → failed RSA decrypt not rejected in vulnerable version → predictable zero-key/zero-IV decrypt path → forged JSON RPC command accepted → privileged UpdraftCentral command dispatch → plugin.upload_plugin → install and activate marker plugin → hard-coded /usr/bin/id proof endpoint
主な脆弱性は認証バイパスです。このラボは、特権を持つUpdraftCentralキー状態が存在する場合、バイパスをRCE型の影響に連鎖させることができることを示しています。これは、UpdraftCentralがWordPressプラグインをインストールおよびアクティブ化できる正規のプラグイン管理コマンドを公開しているためです。
これは直接的なコマンドインジェクションの脆弱性ではありません。コード実行の証明は、RPC認証境界をバイパスした後に、認証済みプラグインインストール機能を悪用することから得られます。
このラボは、制御されたローカル研究、ソースレベルでの理解、およびポートフォリオデモンストレーションのみを目的として設計されています。
## 検証済みの事実
| 主張 | 証拠 | このラボでの検証方法 |
| ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| このラボではUpdraftPlus 1.26.4に脆弱性があります。 | 脆弱なサービスは、偽造された`format=1` RPCメッセージを受け入れ、`plugin.upload_plugin`をディスパッチします。 | `python3 poc/poc.py --url http://127.0.0.1:8081`を実行します。 |
| このラボではUpdraftPlus 1.26.5が偽造メッセージをブロックします。 | パッチ適用済みサービスはRPC応答ボディを返さず、偽造コマンドをディスパッチしません。 | `python3 poc/poc.py --url http://127.0.0.1:8082`を実行します。 |
| この問題はUpdraftCentral RPCレイヤーにおける認証バイパスです。 | 脆弱なバージョンでは、偽造された未認証RPCリクエストがコマンドディスパッチに到達できます。 | ポート`8081`と`8082`の間で`--ping`の動作を比較します。 |
| このラボはマーカープラグインを事前インストールしません。 | セットアップはWordPress、UpdraftPlus、およびローカルのUpdraftCentralキー状態のみをインストールします。 | PoCを実行する前に`/wp-json/cve-lab/v1/id`を確認します。 |
| PoCは偽造RPCを通じてマーカープラグインをインストールします。 | PoCはRPCデータフィールドにZIPプラグインペイロードを含む`plugin.upload_plugin`を送信します。 | PoCを実行し、その後`/wp-json/cve-lab/v1/id`をリクエストします。 |
| 脆弱なターゲットはRCE型の影響に到達します。 | マーカープラグインは`/usr/bin/id`の出力を返すハードコードされたエンドポイントを公開します。 | 脆弱なターゲットは`uid=33(www-data) gid=33(www-data)`を返します。 |
| パッチ適用済みターゲットはマーカープラグインをインストールしません。 | マーカーエンドポイントはパッチ適用済みサービスで`404 rest_no_route`を返します。 | `http://127.0.0.1:8082`に対してPoCを実行します。 |
| このラボにはUpdraftCentralキー状態が必要です。 | UpdraftCentralのディスパッチはローカルキーエントリと関連するメタデータに依存します。 | `scripts/setup-wordpress.sh`を確認します。 |
## 前提条件と未知の事項
このラボは、リモートコントロールが設定されたサイト状態を再現するために、ローカルのUpdraftCentralキー状態を意図的にシードします。
シードされたキー状態はラボの前提条件であり、脆弱性そのものではありません。これにより、ラボは脆弱なRPC解析および復号パスを一貫して実行できます。
このラボは、すべてのUpdraftPlusインストールが直ちに悪用可能であると主張するものではありません。実証された連鎖は、特権を持つWordPressユーザーに関連付けられたUpdraftCentralローカルキーエントリの存在に依存します。
このラボは、ハードコードされた`/usr/bin/id`証明エンドポイントを公開するマーカープラグインをインストールすることで、制御されたRCE型の影響を示します。汎用ウェブシェル、任意コマンド実行パラメータ、リバースシェル、永続化メカニズム、認証情報の窃取、外部コールバックは提供しません。
PoCはローカルターゲットのみを対象としており、デフォルトで非ローカルホスト名を拒否します。
## 根本原因の概要
根本原因は、脆弱なバージョンのUpdraftPlusにおけるUpdraftCentral RPCメッセージの不適切な検証です。
脆弱なRPCフローは`format=1`メッセージを受け入れます。`format=1`パスは、新しいメッセージ形式と同じ署名検証を必要としません。
概要レベルの問題は次のとおりです:```text
format=1 message
→ signature verification is bypassed
→ RSA decrypt of the symmetric key can fail
→ failed decrypt result is not rejected
→ false is passed into the symmetric cipher as a key
→ phpseclib normalizes this into a predictable null key path
→ attacker-controlled encrypted JSON can decrypt successfully
→ command is dispatched
脆弱な動作では、RSA復号は以下を返すことがあります:```text false
失敗した復号結果を拒否する代わりに、この脆弱なフローは処理を続行し、その値を対称復号レイヤーに渡します。
実際の脆弱なパターンは次のとおりです。```php
$sym_key = $rsa->decrypt($sym_key);
$rij->setKey($sym_key);
$decrypted = $rij->decrypt($ciphertext);
The problem is that $sym_key is not validated before it is used.
When $sym_key is false, the cipher setup follows a predictable null key/null IV behavior. This makes it possible to craft an encrypted RPC payload using a known zero key and zero IV.
The patched version adds a guard before the symmetric key is used:```php if (false === $sym_key || !is_string($sym_key) || strlen($sym_key) < 16) { return false; }
これにより、信頼境界が変更されます。
パッチ適用前:```text
failed RSA decrypt result could still reach symmetric decrypt
パッチ適用後:```text failed RSA decrypt result is rejected before command dispatch
これが、脆弱なサービスが偽造されたRPCコマンドをディスパッチする一方、パッチ適用済みのサービスがそうしない理由です。
## 認証バイパスがなぜコード実行につながるのか
CVE-2026-10795は、根本的な欠陥がRPC認証およびメッセージ検証層にあるため、認証バイパスとして最も適切に説明されます。
しかし、その認証境界がバイパスされた後、攻撃者が制御するRPCメッセージは、特権的なUpdraftCentralコマンドに到達できます。
重要なコマンドパスの1つは次のとおりです:```text
plugin.upload_plugin
このコマンドは、UpdraftCentral のプラグイン管理機能の一部です。プラグインの ZIP ペイロードを受け取り、一時的な場所に書き込み、プラグインをインストールし、要求に応じてアクティブ化します。
したがって、影響の連鎖は次のとおりです。```text Authentication bypass → forged privileged RPC command → plugin upload through legitimate UpdraftCentral functionality → plugin installation → plugin activation → WordPress plugin code execution
これはコマンドインジェクションではありません。
このラボは、単一のエンドポイントを公開するマーカープラグインをインストールすることでコード実行を実演します。```text
/wp-json/cve-lab/v1/id
マーカープラグインはコマンドパラメータを受け付けません。実行できるのは次のみです:```text /usr/bin/id
これにより、実証が制御された状態に保たれ、ラボが汎用のWebシェルに変わることを回避できます。
## ソースパッチの概要
関連するパッチの動作として、パッチ適用版はRPCメッセージ本体の復号を試みる前に、無効な対称鍵を拒否します。
重要な検証は次のとおりです。```php
if (false === $sym_key || !is_string($sym_key) || strlen($sym_key) < 16) {
return false;
}
これにより、RSA復号の失敗結果が予測可能な対称鍵パスになり得るという脆弱なフォールバック動作が防止されます。
実際の結果は次のとおりです。```text UpdraftPlus 1.26.4 → forged format=1 RPC message reaches command dispatch
UpdraftPlus 1.26.5 → failed symmetric key validation stops the forged message → command dispatch is not reached
このラボは、実際のUpdraftCentralプラグインのアップロードコマンドパスを対象とすることで、下流への影響も検証します。
関連するコマンドの動作は次のとおりです:```text
plugin.upload_plugin
→ base64 decode ZIP data
→ write temporary ZIP file
→ UpdraftCentral_Plugin_Upgrader->install()
→ activate_plugin()
パッチ適用版は、このコマンドパスに到達する前に偽造メッセージをブロックします。
このセクションでは、脆弱なパスをソースコードレベルで説明し、各PoCステップを関連するUpdraftPlus / UpdraftCentralの動作に対応付けます。
このラボは、偽の脆弱なアプリケーションルートに依存していません。脆弱な動作は、実際のUpdraftCentral RPCリスナーと実際のUpdraftCentralプラグイン管理コマンドパスを通じて到達します。
重要なソース領域は次のとおりです。```text vendor/team-updraft/common-libs/src/updraft-rpc/class-udrpc2.php central/bootstrap.php central/listener.php central/commands.php central/modules/plugin.php
### リスナー作成
脆弱なRPCパスは、WordPressが以下を含むPOSTリクエストを受信したときに始まります:```text
udrpc_message
format
key_name
RPCライブラリは、それらのPOSTフィールドが存在する場合、WordPressのwp_loadedにリスナーを登録します。
概念的には、フローは次のとおりです。```php if (!empty($_POST['udrpc_message']) && !empty($_POST['format'])) { add_action('wp_loaded', array($this, 'wp_loaded')); add_action('wp_loaded', array($this, 'wp_loaded_final'), 10000); }
これは、攻撃者が特別なRESTエンドポイントや管理URLを知る必要がないことを意味します。偽造されたRPCリクエストは、通常のPOSTリクエストとしてWordPressサイトのルートに送信されます。