
CVE-2026-79387の概念実証。PbootCMSのユーザー管理における認証済みSQLインジェクションで、任意のフィールド更新とアカウント乗っ取りを可能にします。
| フィールド | 詳細 |
|---|---|
| CVE ID | CVE-2026-79387 |
| 製品 | PbootCMS |
| 影響を受けるバージョン | 3.2.0 – 3.2.5、およびそれ以前の可能性あり |
| 脆弱性の種類 | SQL インジェクション (CWE-89) |
| 攻撃ベクトル | リモート (認証済み) |
| CVSS 深刻度 | 高 |
| 発見者 | JiahaoLi |
| ベンダー | https://www.pbootcms.com/ |
PbootCMS V3.2.5 のユーザー管理モジュールに SQL インジェクションの脆弱性が存在します。この脆弱性は /apps/admin/controller/system/UserController.php の mod() メソッド (149 行目) および /apps/admin/model/system/UserModel.php の modUser() メソッドに存在します。
field パラメータは GET リクエストを通じて完全にユーザーが制御でき、ホワイトリスト検証が一切行われていません。value パラメータも同様にユーザーが制御でき、SQL の UPDATE 文に直接連結されます。認証済みの攻撃者は field として任意のデータベースカラム (例: password、username、status、role) を指定でき、任意のデータ操作が可能になります。
// UserController.php - mod() method
if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
if ($this->model->modUser($ucode, "$field='$value',update_user='" . session('username') . "'")) {
location(- 1);
}
}
$field と $value は $_GET スーパーグローバルから直接取得され、サニタイズもホワイトリストもパラメータ化クエリもなしに SQL 文字列へ連結されます。この文字列はその後 UserModel::modUser() に渡され、さらに基底クラスの Model::update() メソッドへ転送されます。引数が文字列(配列ではない)であるため、checkKey() によるフィールド名の検証をバイパスし、SET 句にそのまま埋め込まれます:
UPDATE ay_user SET <user-controlled>= '<user-controlled>', update_user='admin' WHERE ucode='<ucode>'
GET /admin.php?p=/User/mod&ucode=10002&field=password&value=<MD5>
→ UserController::mod()
→ UserModel::modUser($ucode, "password='<value>',update_user='admin'")
→ Model::table('ay_user')->where("ucode='$ucode'")->update($data_string)
→ SQL: UPDATE ay_user SET password='<value>',update_user='admin' WHERE ucode='10002'
認証済みの攻撃者は以下を実行できます:
ucode=10001 を除く)。value パラメータでシングルクォートのエスケープが可能であり、スタック型またはトートロジーベースの攻撃を可能にする可能性があります。これはアカウント乗っ取りおよびCMSバックエンドの完全な制御につながります。
192.168.1.104、Apache/PHP 7.2.1/SQLite でテスト済み)PbootCMS の管理ダッシュボードにアクセスし、デフォルトの admin アカウントでログインします。

システム管理 → ユーザー管理 → ユーザー追加 に移動します。新しいユーザーを作成します:
admin2admin
ユーザーリストで admin2 が ucode=10002 として確認できます:

新しいブラウザウィンドウを開きます。admin2 としてパスワード 123456 でログインを試みます — 実際のパスワードは admin であるため、これは失敗します:

すでにログイン済みの管理者ブラウザを使用して、以下に移動します:
http://192.168.1.104/PbootCMS/admin.php?p=/User/mod&ucode=10002&field=password&value=14e1b600b1fd579f47433b88e8d85291
14e1b600b1fd579f47433b88e8d85291は123456の MD5 ハッシュです。
mod() メソッドはインジェクションを実行し、location(-1) を介してリダイレクトします:

次に、admin2 / 123456 でログインを試みます:

SQL インジェクションによりパスワードが正常に変更されました。 ユーザーは新しいパスワードでログインしており、完全なアカウント乗っ取りが確認されました。

update() が文字列引数を受け取ると、その文字列はエスケープされずに そのまま SET 句で使用されます:
final public function update($data = null)
{
if (is_array($data)) {
// Array path: checkKey() validates field names
...
} else {
// String path: NO VALIDATION AT ALL
$update_string = $data;
}
$this->sql['value'] = $update_string;
$sql = $this->buildSql($this->updateSql);
return $this->getDb()->amd($sql); // Direct execution, no prepared statement
}
field パラメータに対するホワイトリスト検証 — 既知のカラム名(status、username、realname、password)のみを許可する。$value をサニタイズし、クォートの脱出を防ぐ。field が password の場合、保存前に値へ encrypt_string() を適用する。mod() 内の「単一フィールド変更」分岐では、有効な CSRF トークンとロールレベルの認可チェックを必須とする。開示: この脆弱性はベンダーへ責任ある開示を行いました。影響を受けるバージョンを使用している場合は、直ちに更新し、すべてのバックエンドアカウントを監査してください。