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
Tools/GitHubGitHub/bhanunamikaze/wp2shell-cve-2026-63030-poc
ReconnaissanceVulnerability ScannersExploitationWeb Application ExploitationInformation GatheringWeb SecurityPenetration TestingLearning & Education
GitHubbhanunamikaze/wp2shell-cve-2026-63030-poc

WP2Shell-CVE-2026-63030-POC

PoC detector & safe validator for the WP2Shell WordPress vulnerability chain: CVE-2026-63030 (REST batch-route confusion) + CVE-2026-60137 (author__not_in SQL injection). For authorized security testing only.

View RepositoryWebsite
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 Detector and Validation PoC

License: MIT Python 3.9+ CVE-2026-63030 CVE-2026-60137 Security Research

CVE coverage: CVE-2026-63030 and CVE-2026-60137 Intended use: Authorized security testing, defensive validation, and disposable localhost labs only

WP2Shell is a WordPress Core vulnerability chain combining a pre-authentication REST API batch-route confusion bug (CVE-2026-63030) with a WP_Query author__not_in SQL injection primitive (CVE-2026-60137). This repository provides a Python proof-of-concept scanner and safe validator so defenders can fingerprint affected WordPress installations, confirm the vulnerable behavior in an isolated lab, and verify remediation — without needing to extract data or achieve code execution.

Overview

This project fingerprints WordPress installations and validates the two vulnerability primitives associated with the WP2Shell WordPress Core vulnerability chain:

  • CVE-2026-63030 — REST API batch-route confusion.
  • CVE-2026-60137 — incomplete sanitization of WP_Query::author__not_in, which can result in SQL injection when attacker-controlled input reaches the parameter.

When both conditions are present, an unauthenticated request may reach the vulnerable SQL construction through the WordPress REST API batch endpoint. Public advisories describe the combined impact as potentially leading to remote code execution.

This repository should be used only on systems you own or are explicitly authorized to test. Prefer an isolated Docker or virtual-machine lab bound to 127.0.0.1.


Safety Notice

The current source file contains state-changing functionality, including database-data extraction attempts, file-write attempts, authentication workflows, administrator creation, plugin upload, and command execution.

  • WordPress fingerprinting.
  • Version assessment.
  • Local source-tree version checks.
  • Safe route-confusion validation.
  • Non-destructive timing-based SQL injection confirmation in an isolated lab.
  • Reporting, evidence collection, and remediation.

Vulnerability Summary

CVE-2026-63030 — REST API Batch-Route Confusion

WordPress affected releases can lose alignment between internal arrays used to track:

  • Parsed batch requests.
  • Matched REST route handlers.
  • Validation results.

When a malformed batch member is accepted into one internal array but not another, later requests can become associated with the wrong handler. A request may therefore be validated as one route but executed using another route's callback.

Security impact:

  • REST request/handler desynchronization.
  • Validation against the wrong route schema.
  • Unexpected nested batch execution.
  • Pre-authentication reachability of otherwise constrained code paths.
  • When combined with CVE-2026-60137, potential SQL injection and further compromise.

CVE-2026-60137 — author__not_in SQL Injection

The affected WP_Query implementation does not consistently normalize author__not_in before using it to construct an SQL NOT IN (...) condition.

The parameter normally expects a list of integer author IDs. If a scalar string reaches the vulnerable query construction without the intended REST-schema validation, unsafe SQL structure can survive into the database query.

Security impact:

  • Blind SQL injection.
  • Boolean or timing-based database oracle.
  • Potential disclosure of WordPress database contents.
  • Increased impact when chained with CVE-2026-63030.

Affected Versions

WordPress branchAffectedFixed release
6.8.xCVE-2026-60137 only: 6.8.0–6.8.56.8.6
6.9.xBoth issues: 6.9.0–6.9.46.9.5
7.0.xBoth issues: 7.0.0–7.0.17.0.2
7.1 prereleaseBeta 1 affectedBeta 2
Earlier than 6.8Not affected by these two CVEsN/A

WordPress released fixes on July 17, 2026 and enabled forced automatic updates for affected installations because of the severity.


Vulnerability Workflow

root@kitploit:~
Unauthenticated client
        |
        v
WordPress REST batch endpoint
        |
        v
Malformed batch member creates request/handler misalignment
        |
        v
Later request is validated against one route
but dispatched using another route's handler
        |
        v
Scalar author_exclude reaches WP_Query as author__not_in
        |
        v
Unsafe value reaches SQL NOT IN (...) construction
        |
        v
Blind SQL timing or Boolean oracle
        |
        v
Potential database compromise
        |
        v
Potential application-level compromise and RCE

The detector should stop after confirming the route-confusion and SQL-injection primitives. It does not need to extract data or execute commands to establish that an affected installation is vulnerable.


Detection Workflow

Phase 1 — Normalize the target

The tool:

  1. Adds a default http or https scheme if missing.
  2. Normalizes the WordPress installation path.
  3. Rejects unsupported URL schemes and embedded credentials.
  4. Applies redirect, proxy, TLS, and timeout policies.

Phase 2 — Identify WordPress

The scanner checks for:

  • wp-content/ references.
  • wp-includes/ references.
  • WordPress generator metadata.
  • REST API discovery links.
  • WordPress REST index structure.
  • The wp/v2 namespace.
  • Optional feed and readme.html fingerprints.

Phase 3 — Determine the version

Version evidence can come from:

  • HTML generator metadata.
  • Feed generator metadata.
  • WordPress core asset query strings.
  • HTTP generator headers.
  • readme.html.
  • A local wp-includes/version.php file.

Evidence is scored and reconciled. Conflicting remote version indicators lower confidence.

Phase 4 — Check batch-route exposure

The scanner attempts to discover /batch/v1 through:

root@kitploit:~
/?rest_route=/
/wp-json/

The route can be addressed using either:

root@kitploit:~
/?rest_route=/batch/v1
/wp-json/batch/v1

Phase 5 — Safe route-confusion probe

The safe probe contains:

  1. A deliberately malformed internal path.
  2. A request to an invalid post ID with a harmless nested public GET.
  3. A following /batch/v1 request.

A vulnerable server returns an outer 207 Multi-Status response in which the invalid post request is processed as a nested batch request.

The detector reports:

root@kitploit:~
route-confusion-observed

when it sees:

  • The expected parse_path_failed marker.
  • A second outer response with status 207.
  • A nested responses array showing that the harmless internal request ran.

Phase 6 — Timing-based SQLi confirmation

A non-destructive SQLi validator should send paired requests that differ only by a constant Boolean condition:

root@kitploit:~
False control -> no deliberate database delay
True test     -> deliberate database delay

The validator must:

  • Accept the expected outer HTTP 207.
  • Parse both the outer and nested batch envelopes.
  • Verify the malformed-request markers.
  • Ensure the SQLi-bearing nested request returned a valid response.
  • Collect multiple true and false samples.
  • Randomize or interleave sample order.
  • Compare medians rather than a single request.
  • Report insufficient measurements as inconclusive.

A repeatable gap between true and false samples confirms that attacker-controlled input reached SQL evaluation. No database contents need to be selected or extracted.


Requirements

  • Python 3.9 or later.
  • No third-party Python packages are required by the supplied script.
  • Network access to the authorized WordPress installation.
  • For local testing:
    • A disposable WordPress 7.0.1 or 6.9.4 lab.
    • A database container or dedicated test database.
    • The web service bound to 127.0.0.1.
    • No production credentials or data.

Check Python:

root@kitploit:~
python3 --version

Optional syntax validation:

root@kitploit:~
python3 -m py_compile WP2Shell_CVE-2026-63030_POC.py

Installation

Rename the supplied script to a predictable filename:

root@kitploit:~
mv 'poc(1).py' WP2Shell_CVE-2026-63030_POC.py
chmod +x WP2Shell_CVE-2026-63030_POC.py

Display global help:

root@kitploit:~
python3 WP2Shell_CVE-2026-63030_POC.py --help

Display the version:

root@kitploit:~
python3 WP2Shell_CVE-2026-63030_POC.py --version

Commands

The script defines three commands:

root@kitploit:~
remote   Fingerprint and scan HTTP(S) WordPress targets.
local    Read the installed WordPress version from a source tree.
exploit  State-changing proof-of-concept path.

Current Build Status

CommandStatus
localImplemented
remoteCLI is defined, but run_remote() is currently a stub and returns an error
exploitContains state-changing functionality; restrict to a disposable local lab and separate it from defensive scanning

The source currently prints the following for remote:

root@kitploit:~
Remote scanning not fully implemented in this snippet. Use 'local' or 'exploit'.

Restore a complete run_remote() implementation before advertising bulk remote scanning as functional.


Local Version Assessment

The local command reads:

root@kitploit:~
<wordpress-root>/wp-includes/version.php

and extracts $wp_version.

Basic usage

root@kitploit:~
python3 WP2Shell_CVE-2026-63030_POC.py local \
  --wordpress-root /var/www/html

JSON report

root@kitploit:~
python3 WP2Shell_CVE-2026-63030_POC.py local \
  --wordpress-root /var/www/html \
  --format json \
  --output local-result.json

Docker-based WordPress installation

When the WordPress container is named wordpress, copy or mount the source tree to the host, or run the version check inside the container:

root@kitploit:~
docker compose exec wordpress php -r \
  'require "/var/www/html/wp-includes/version.php"; echo $wp_version, PHP_EOL;'

Vulnerable lab setup with compose.yaml

Use the provided compose.yaml to run a disposable local lab bound to 127.0.0.1:8080:

root@kitploit:~
docker compose up -d

Once the first-time WordPress setup completes in the browser at http://127.0.0.1:8080, you can run:

root@kitploit:~
python3 WP2Shell_CVE-2026-63030_POC.py remote \
  --authorized \
  --target http://127.0.0.1:8080 \
  --active-probe \
  --format json

To stop and remove the lab:

root@kitploit:~
docker compose down -v

Local command options

OptionDescription
--wordpress-root PATHRequired directory containing wp-includes/version.php
-f, --formattable, json, jsonl, or csv
-o, --output FILEWrite the report to a file
--fail-onExit-code policy: never, vulnerable, or unknown

Example vulnerable-version output

root@kitploit:~
[
  {
    "selected_version": "7.0.1",
    "version_assessment": "affected-wp2shell",
    "verdict": "CONFIRMED_AFFECTED_VERSION",
    "severity": "critical"
  }
]

A local version result confirms that the installed release is in the published affected range. It does not, by itself, demonstrate runtime exploitability or the effect of a backported patch.


Remote Scanner Interface

The remote parser supports the following arguments, but the supplied run_remote() implementation is currently incomplete.

Single target

Expected interface after restoring run_remote():

root@kitploit:~
python3 WP2Shell_CVE-2026-63030_POC.py remote \
  --authorized \
  --target https://wordpress.example \
  --active-probe

Multiple explicit targets

root@kitploit:~
python3 WP2Shell_CVE-2026-63030_POC.py remote \
  --authorized \
  --target https://site-one.example \
  --target https://site-two.example \
  --active-probe

Target file

Create targets.txt:

root@kitploit:~
https://site-one.example/
https://site-two.example/blog/

Expected interface:

root@kitploit:~
python3 WP2Shell_CVE-2026-63030_POC.py remote \
  --authorized \
  --targets-file targets.txt \
  --active-probe \
  --format jsonl \
  --output results.jsonl

Standard input

root@kitploit:~
cat targets.txt | python3 WP2Shell_CVE-2026-63030_POC.py remote \
  --authorized \
  --stdin

Proxy usage

root@kitploit:~
python3 WP2Shell_CVE-2026-63030_POC.py remote \
  --authorized \
  --target https://wordpress.example \
  --active-probe \
  --proxy http://127.0.0.1:8081

Custom request header

root@kitploit:~
python3 WP2Shell_CVE-2026-63030_POC.py remote \
  --authorized \
  --target https://wordpress.example \
  --header 'Authorization: Bearer TEST_TOKEN'

Remote options

OptionPurpose
-u, --target URLTarget URL; repeatable
-l, --targets-file FILEOne target per line; repeatable
--stdinRead targets from stdin
--authorizedRequired authorization acknowledgement
--default-schemeScheme applied when omitted
-c, --concurrencyConcurrent target workers
--rateAggregate request rate
--timeoutPer-request timeout
--retriesRetry count
--max-targetsMaximum number of accepted targets
--max-body-bytesMaximum retained response body
-k, --insecureDisable TLS verification
--no-redirectsDisable redirects
--allow-cross-host-redirectsPermit redirects to another host
--proxyHTTP/HTTPS proxy
-H, --headerCustom header; repeatable
--user-agentOverride User-Agent
--fingerprint-levelquick, standard, or extended
--active-probeSend the safe route-confusion probe
--rest-endpointquery, pretty, or both
--include-request-logAdd URL, status, and timing metadata
-f, --formattable, json, , or

Safe Runtime Validation

For a non-destructive local validation of both primitives, use a dedicated validator that:

  • Refuses non-loopback hosts.
  • Confirms route confusion first.
  • Runs constant-condition timing samples only after route confusion succeeds.
  • Does not extract data or execute commands.

Example workflow:

root@kitploit:~
python3 wp2shell_local_validator.py check \
  --authorized \
  --target http://127.0.0.1:8080 \
  --sqli \
  --delay 2 \
  --samples 4 \
  --warmups 2 \
  --debug \
  --dump-dir evidence \
  --output result.json

Expected vulnerable-lab timing pattern:

root@kitploit:~
False controls: approximately 0.03–0.10 seconds
True tests:     consistently delayed

Expected verdict:

root@kitploit:~
FULL_VULNERABILITY_PRIMITIVES_CONFIRMED

A timing test can execute the delay expression more than once, so a configured two-second delay may produce an observed delay near four seconds. The important signal is the repeatable separation between true and false conditions.


Output Formats

Table

Best for interactive terminal use:

root@kitploit:~
--format table

JSON

Best for evidence and integration:

root@kitploit:~
--format json --output result.json

JSON Lines

Best for large target sets:

root@kitploit:~
--format jsonl --output results.jsonl

CSV

Best for spreadsheets and reporting:

root@kitploit:~
--format csv --output results.csv

Verdicts

VerdictMeaning
CONFIRMED_VULNERABLE_BEHAVIORRuntime route-confusion behavior was observed
CONFIRMED_AFFECTED_VERSIONLocal source version is in an affected range
LIKELY_VULNERABLERemote version evidence indicates an affected release
VULNERABLE_SQLI_ONLYVersion is affected by CVE-2026-60137 but outside the complete route-confusion range
AFFECTED_VERSION_BUT_BEHAVIOR_NOT_OBSERVEDAffected version detected, but safe runtime behavior was absent
PATCHED_VERSIONVersion meets the published fixed boundary
NOT_AFFECTEDVersion is outside the affected branch
POTENTIALLY_EXPOSED_VERSION_UNKNOWNWordPress and the batch route were found, but the version is hidden
WORDPRESS_VERSION_UNKNOWNWordPress detected without reliable version evidence
ERRORThe target could not be assessed
NOT_WORDPRESS_OR_NOT_DETECTEDNo reliable WordPress evidence

Exit Codes

The scanner uses policy-driven exit codes.

CodeMeaning
0No policy-triggering result, or --fail-on never
2Vulnerable or affected result under the default policy
3Unknown or inconclusive result when --fail-on unknown is selected
1Argument, input, or incomplete-command error

A vulnerability finding can therefore return a non-zero status intentionally.

Example:

root@kitploit:~
python3 WP2Shell_CVE-2026-63030_POC.py local \
  --wordpress-root /var/www/html \
  --fail-on vulnerable

echo $?

Vulnerable-versus-Fixed Differential Test

A strong validation compares two clean environments.

Vulnerable environment

root@kitploit:~
WordPress 7.0.1

Expected:

root@kitploit:~
route-confusion-observed
repeatable true/false SQL timing difference

Fixed environment

root@kitploit:~
WordPress 7.0.2

Expected:

root@kitploit:~
route-confusion-not-observed
SQLi timing test not reached or no valid timing oracle

Always recreate the WordPress volume when changing versions. Reusing a volume can preserve old or automatically updated core files.

root@kitploit:~
docker compose down -v
docker compose pull
docker compose up -d

Remediation

Update immediately to one of the fixed releases or a later supported release:

  • WordPress 6.8.6.
  • WordPress 6.9.5.
  • WordPress 7.0.2.
  • WordPress 7.1 beta2 or later, for prerelease testing.

Temporary controls should cover both batch endpoint forms:

root@kitploit:~
/wp-json/batch/v1
/?rest_route=/batch/v1

Additional defensive actions:

  1. Review logs for anonymous batch requests, malformed internal URLs, nested batch structures, and unusual author_exclude values.
  2. Review administrator accounts, plugin changes, unexpected PHP files, and database access after any period of exposure.
  3. Verify WordPress Core checksums and restore from a known-good backup if compromise is suspected.
  4. Rotate secrets and credentials stored in the WordPress database when SQL injection exploitation may have occurred.

Blocking the endpoint is a temporary mitigation, not a substitute for updating WordPress Core.


Detection Ideas

Potential indicators include:

  • Anonymous POST requests to either batch endpoint form.
  • HTTP 207 responses containing nested responses arrays.
  • Malformed internal URLs in batch request bodies.
  • Nested requests objects inside another batch member.
  • Scalar or SQL-shaped author_exclude values.
  • Repeated paired requests with alternating fast and delayed responses.
  • Unexpected WordPress administrator creation.
  • Unexpected plugin installation or activation.
  • New PHP files under writable WordPress directories.
  • Database queries containing unusual author__not_in expressions.

Known Limitations in the Supplied Script

  • Cookie handling is not equivalent to a persistent browser session.
  • Database table prefixes are assumed in some code paths.
  • Database FILE privilege and filesystem paths vary by deployment.
  • INTO OUTFILE is usually restricted and cannot overwrite existing files.
  • WordPress may disable plugin installation through DISALLOW_FILE_MODS.
  • Timing thresholds can be affected by proxies, WAFs, PHP timeouts, database timeouts, and load.
  • Version strings can be hidden, spoofed, cached, or inconsistent.
  • An observed affected version does not prove the absence of a security backport.
  • A missing timing signal does not prove the server is patched.

References

  • WordPress 7.0.2 Security Release:
    https://wordpress.org/news/2026/07/wordpress-7-0-2-release/

  • WordPress 7.0.2 Documentation and changed files:
    https://wordpress.org/documentation/wordpress-version/version-7-0-2/

  • NVD — CVE-2026-63030:
    https://nvd.nist.gov/vuln/detail/CVE-2026-63030

  • NVD — CVE-2026-60137:
    https://nvd.nist.gov/vuln/detail/CVE-2026-60137

  • WordPress release archive:
    https://wordpress.org/download/releases/


Legal and Ethical Use

Use this project only when:

  • You own the system, or
  • You have explicit written authorization, and
  • The requested test activity is within the agreed scope.

Do not expose deliberately vulnerable WordPress installations to the public Internet. Use disposable credentials, synthetic data, isolated networks, and clean snapshots. Destroy or reset the lab after testing.

The safest proof of vulnerability is the minimum evidence necessary to demonstrate the issue:

root@kitploit:~
Affected version
        +
Route-confusion behavior
        +
Repeatable constant-condition SQL timing oracle

Credential theft, persistence, webshell installation, and command execution are unnecessary for confirming that the vulnerability exists.

Download Tool
jsonl
csv
-o, --outputWrite output to a file
--fail-onExit-code policy