Wp2shell-detect, a non-intrusive detector for the WordPress core pre-auth RCE

own2pwn-fr1 pts0 comments

GitHub - own2pwn-fr/wp2shell-detect: Blackbox, non-intrusive detector for wp2shell (WordPress core pre-auth RCE, CVE-2026-63030 / CVE-2026-60137). Detection only. · GitHub

/" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

Uh oh!

There was an error while loading. Please reload this page.

own2pwn-fr

wp2shell-detect

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

main

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>4 Commits<br>4 Commits

.github/workflows

.github/workflows

.gitignore

.gitignore

LICENSE

LICENSE

README.md

README.md

pyproject.toml

pyproject.toml

test_wp2shell_detect.py

test_wp2shell_detect.py

wp2shell_detect.py

wp2shell_detect.py

View all files

Repository files navigation

wp2shell-detect

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

CVE-2026-63030 — route confusion in the REST batch endpoint<br>(/wp-json/batch/v1): a sub-request whose path fails wp_parse_url() lands in<br>the validation array but not the handler array, desynchronising the two.

CVE-2026-60137 — SQL injection in WP_Query's author__not_in handling,<br>reachable pre-auth through that route confusion.

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

Full technical writeup:<br>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<br>is a normal, read-only request a crawler could send:

Fingerprints the WordPress core version from many public sources, so a<br>hardened install that strips the generator tag is still identified: the<br>generator meta tag, core asset ?ver= (on /wp-includes/ and<br>/wp-admin/ assets, which track core), the RSS feed generator (?v=),<br>/wp-links-opml.php, the login page assets, /wp-includes/version.php,<br>readme.html, and the /wp-json/ index. Sources are cross-checked and a<br>confidence (high when ≥2 agree) is reported.

Compares the version to the known-vulnerable ranges.

Checks the REST batch route with a benign OPTIONS request (and the REST<br>index) — which returns the route schema without ever invoking the handler —<br>to tell whether an edge mitigation is in place.

Discovers headless WordPress back-ends. If the target front isn't WP but<br>references a WordPress host on the same domain (via CSP, the Link header or<br>asset URLs — common with headless/Next.js fronts), the tool reports it, and<br>--discover scans it too.

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

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

Vulnerable ranges

Range<br>Exposure<br>Fixed in

6.8.0 – 6.8.5<br>SQL injection only (no RCE)<br>6.8.6

6.9.0 – 6.9.4<br>pre-auth RCE<br>6.9.5

7.0.0 – 7.0.1<br>pre-auth RCE<br>7.0.2

Usage

Zero dependencies. Python 3.8+.

./wp2shell_detect.py https://example.com<br>./wp2shell_detect.py --json https://a.example https://b.example<br>./wp2shell_detect.py --targets hosts.txt --workers 16 # parallel sweep<br>./wp2shell_detect.py --discover https://front.example # follow headless WP

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

Headless WordPress

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

Example:

VULNERABLE (pre-auth RCE)<br>version : 6.9.3 (generator meta tag=6.9.3,...

wordpress wp2shell core auth wp2shell_detect https

Related Articles