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,...