Skip to main content

Blackbox, non-intrusive detector for wp2shell (WordPress core pre-auth RCE, CVE-2026-63030 / CVE-2026-60137).

Project description

wp2shell-detect

Blackbox, non-intrusive detector for wp2shell — the pre-authentication RCE chain in WordPress core disclosed on 2026-07-17:

  • CVE-2026-63030 — route confusion in the REST batch endpoint (/wp-json/batch/v1): a sub-request whose path fails wp_parse_url() lands in the validation array but not the handler array, desynchronising the two.
  • CVE-2026-60137 — SQL injection in WP_Query's author__not_in handling, reachable pre-auth through that route confusion.

Chained, they let an anonymous attacker forge an administrator account and drop a plugin webshell — on a default install, no plugin or theme required.

Full technical writeup: https://own2pwn.fr/articles/appsec/wp2shell-wordpress-rce

What this tool does (and does not)

It detects exposure. It does not exploit anything. Every request it makes is a normal, read-only request a crawler could send:

  1. Fingerprints the WordPress core version from many public sources, so a hardened install that strips the generator tag is still identified: the generator meta tag, core asset ?ver= (on /wp-includes/ and /wp-admin/ assets, which track core), the RSS feed generator (?v=), /wp-links-opml.php, the login page assets, /wp-includes/version.php, readme.html, and the /wp-json/ index. Sources are cross-checked and a confidence (high when ≥2 agree) is reported.
  2. Compares the version to the known-vulnerable ranges.
  3. Checks the REST batch route with a benign OPTIONS request (and the REST index) — which returns the route schema without ever invoking the handler — to tell whether an edge mitigation is in place.
  4. Discovers headless WordPress back-ends. If the target front isn't WP but references a WordPress host on the same domain (via CSP, the Link header or asset URLs — common with headless/Next.js fronts), the tool reports it, and --discover scans it too.

No request triggers the vulnerability. No POST /wp-json/batch/v1, no author_exclude, no SQL. If the core version is hidden, the tool says so rather than guessing (confirming wp2shell blindly would require exploiting it).

Resilience: retries with backoff, gzip/deflate decoding, https→http fallback, cross-host redirect following, a browser-like User-Agent (overridable), and parallel multi-target scanning.

Vulnerable ranges

Range Exposure Fixed in
6.8.0 – 6.8.5 SQL injection only (no RCE) 6.8.6
6.9.0 – 6.9.4 pre-auth RCE 6.9.5
7.0.0 – 7.0.1 pre-auth RCE 7.0.2

Install

pip install wp2shell-detect

Or run it straight from source (single file, no dependencies, Python 3.8+):

git clone https://github.com/own2pwn-fr/wp2shell-detect
./wp2shell-detect/wp2shell_detect.py https://example.com

Usage

Zero dependencies. Python 3.8+.

wp2shell-detect https://example.com
wp2shell-detect --json https://a.example https://b.example
wp2shell-detect --targets hosts.txt --workers 16   # parallel sweep
wp2shell-detect --discover https://front.example   # follow headless WP

(Installed from PyPI, the command is wp2shell-detect. From a clone, call ./wp2shell_detect.py with the same arguments.)

Options: --json, --discover, --workers N, --timeout S, --user-agent UA, --insecure, --targets FILE. Exit code 2 if any target is found vulnerable (handy in CI / cron sweeps).

Headless WordPress

Modern sites often serve a JS/Next.js front on www. and keep WordPress on a sibling host (wordpress., wp., cms.). Scanning www. then returns not WordPress — correctly, because that host isn't WordPress. Point the scan at the WordPress host, or pass --discover to have the tool find and scan it from the front's CSP / Link header / asset URLs automatically.

Example:

[!!] https://blog.example.com  ->  VULNERABLE (pre-auth RCE)
      version : 6.9.3  (generator meta tag=6.9.3, RSS feed generator=6.9.3)
      batch   : reachable  (/wp-json/batch/v1)
      cves    : CVE-2026-63030, CVE-2026-60137
      note    : WordPress 6.9.3 is in the wp2shell pre-auth RCE range. REST batch endpoint reachable — no edge mitigation.

Mitigation

Patch WordPress core to 6.8.6 / 6.9.5 / 7.0.2 or later. If patching must wait, block the batch route at the edge (/wp-json/batch/v1 and ?rest_route=/batch/v1) or via a must-use plugin hooking rest_pre_dispatch, then audit for rogue admin accounts and unknown plugins.

Legal

For authorised assessment only. Running this against systems you neither own nor are mandated to test may be illegal in your jurisdiction. You are responsible for how you use it.

License

MIT. See LICENSE. By own2pwn.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wp2shell_detect-1.0.1.tar.gz (11.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wp2shell_detect-1.0.1-py3-none-any.whl (12.3 kB view details)

Uploaded Python 3

File details

Details for the file wp2shell_detect-1.0.1.tar.gz.

File metadata

  • Download URL: wp2shell_detect-1.0.1.tar.gz
  • Upload date:
  • Size: 11.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for wp2shell_detect-1.0.1.tar.gz
Algorithm Hash digest
SHA256 4be413afc938eedeb021be9b96c42c3a6d2fe27c4ae8f5f2bab3669700a7e7f4
MD5 7f6dae8653933f7f175829f9036acd79
BLAKE2b-256 ca3fd2f5b2735c424c6e9898bf37f52b75fe09685572cd12259cdbfa6abed438

See more details on using hashes here.

File details

Details for the file wp2shell_detect-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for wp2shell_detect-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c177c36dcf4ca8875ab7665347d987f205b5f6d855ad5d6e74f2cdb4f37080da
MD5 45a56c979b561bae61345ccd77f39e9a
BLAKE2b-256 80190667959aa48239f64fb8b8d6216f662d4e0cb27b61bedb15d49fc68f7925

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page