Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
wp2shell-cve-2026-63030-root-cause — Independent root cause analysis and proof-of-concept for unauthenticated SQL injection to RCE in WordPress (CVE-2026-63030 + CVE-2026-60137), with Docker lab and detailed exploit chain documentation. | Kitploit
Tools/GitHubGitHub/tcyph3r/wp2shell-cve-2026-63030-root-cause
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & Education
GitHubtcyph3r/wp2shell-cve-2026-63030-root-cause

wp2shell-cve-2026-63030-root-cause

Independent root cause analysis and proof-of-concept for unauthenticated SQL injection to RCE in WordPress (CVE-2026-63030 + CVE-2026-60137), with Docker lab and detailed exploit chain documentation.

View Repository
1 month agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

wp2shell (CVE-2026-63030 + CVE-2026-60137): Independent Root Cause Analysis

WordPress core disclosed wp2shell on 2026-07-17 as a critical, unauthenticated RCE affecting default installs (WordPress 6.9.0-6.9.4, 7.0.0-7.0.1, zero plugins required). The original discoverer (Searchlight Cyber) withheld technical details at disclosure time. This repo documents an independent root-cause analysis derived entirely from diffing WordPress core source between the vulnerable (6.9.4) and patched (6.9.5) releases, plus live verification in a local lab.

Credit: the reproduction here follows the request shape from sergiointel/wp2shell-poc, confirmed byte-for-byte and cross-checked against the real patch diff.

Contents

  • root_cause_analysis.md - full writeup: the two chained bugs, exact vulnerable code, the patch diff, the exploit chain, and live before/after verification against a real WP 6.9.4 instance.
  • poc_upstream.py - unmodified copy of sergiointel's original PoC (SQLi only).
  • poc_upstream_rce.py - sergiointel's PoC as updated roughly 22 hours after disclosure, adding unauthenticated privilege escalation and RCE without cracking any credential. See section 7 of root_cause_analysis.md.
  • poc_extract.py / poc_extract2.py - a tuned variant (larger SLEEP(), higher timing threshold, longer character-search ceiling) needed to get a reliable signal in a Dockerized/proxied lab where the upstream script's default SLEEP(0.15) was lost in network jitter.
  • docker-compose.yml - spin up the same WordPress 6.9.4 + MariaDB lab used for verification.
  • payload.json, response.json, response_patched.json - a hand-crafted request replicating the PoC's structure and the raw server responses, before and after applying the 6.9.5 patch files in place.
  • End-to-end chain, confirmed

    A second, independently written PoC (github.com/Icex0/wp2shell-poc) was reviewed in full and describes the same root cause mechanism independently, corroborating the analysis below. Using its content-based (boolean, not timing-based) blind SQLi extraction, this lab's admin credential hash was recovered with 100% accuracy, and, using that known credential, a full SQLi-to-RCE chain was demonstrated live: SQL injection to credential extraction to authenticated plugin-upload webshell to code execution as www-data. See section 6 of root_cause_analysis.md.

    That credential-cracking path is real but is not the only one. sergiointel's PoC was subsequently updated to achieve unauthenticated RCE with no credential cracking at all, by using UNION SELECT to forge fake database rows that WordPress's own Customizer/nav-menu/oEmbed-cache code trusts enough to let an unauthenticated user-creation request succeed. See section 7 of root_cause_analysis.md. The unauthenticated SQL injection alone is sufficient for full RCE on a default install.

    Summary of findings

    CVE-2026-63030 (REST batch route confusion, CWE-436): WP_REST_Server::serve_batch_request_v1() appends to a $matches[] array by simple push, but skips the append when a sub-request's path fails to parse (e.g. a deliberately malformed "http://:" entry). That single skip desynchronizes $matches[] from $requests[] by one index for every following entry. At dispatch time, $matches[$i] no longer corresponds to $requests[$i], so the code ends up executing a request's data under a different route's matched handler than the one it was actually validated against.

    CVE-2026-60137 (SQL injection): WP_Query::get_posts() only ran absint() sanitization on author__not_in inside an is_array() branch. A scalar string value skipped sanitization entirely and was concatenated directly into ... post_author NOT IN ($value).

    Chained: the route-confusion bug lets an attacker get a request declared against /wp/v2/categories (which doesn't recognize author_exclude, so it's never sanitized) actually dispatched through the posts controller (which does read author_exclude and forwards it into WP_Query). No authentication required.

    On the RCE claim: confirmed live that unauthenticated blind SQL injection works and can exfiltrate arbitrary DB content, including wp_users.user_pass. A single timing-based extraction pass in a virtualized lab had meaningful bit-error noise (~94% per-character accuracy in testing here); a content-based (boolean) oracle did not share that failure mode and recovered the same field with 100% accuracy. RCE was confirmed via two distinct paths: cracking a recovered password hash (conditional on password strength), and an unauthenticated privilege-escalation gadget chain using UNION-forged database rows that WordPress's own Customizer/nav-menu/oEmbed-cache code trusts (unconditional, no credential compromise required). See section 7 of root_cause_analysis.md.

    Reproducing

    root@kitploit:~
    docker compose up -d
    # wait for WordPress install wizard to be reachable on :8890, then complete setup
    
    HTTP_PROXY=http://127.0.0.1:8080 HTTPS_PROXY=http://127.0.0.1:8080 \
      python3 poc_extract2.py http://localhost:8890 "SELECT DATABASE()"
    

    See root_cause_analysis.md for the full technical writeup.

    Responsible Disclosure

    WordPress has published official fixes: 6.9.5 and 7.0.2 (7.1 Beta 2 for the beta branch), released 2026-07-17. Update immediately if you run an affected version. This repository is published for defensive and educational purposes after the patch was already public. Only run any of the code here against systems you own or are explicitly authorized to test.

    Download Tool