## https://sploitus.com/exploit?id=BB1B9118-BF3C-5F4C-805A-63268F33EE6A
# xss2shell-check
Non-destructive, dependency-free detector for the **CVE-2026-64638 ("XSS2Shell")**
reflection primitive in WordPress `wp-login.php`.
## Background
CVE-2026-64638 is a **pre-authentication reflected XSS in WordPress core**,
disclosed by PWN.AI on 2026-08-07 (CVSS 8.9, CWE-79) and patched in 7.0.3 with
backports to every maintained branch (6.9.6, 6.8.7, 6.7.6, 6.6.6, 6.5.9, β¦).
The root cause is a **parser differential** between PHP's `strip_tags()` and
WordPress's KSES sanitizer:
- `strip_tags()` refuses to recognize a tag when whitespace follows `` survives as plain text.
- KSES has no such rule and re-parses the text into a **live ``
element** inside the login error message.
That yields attacker-chosen DOM injection with chosen `id`/`class`/`href`
attributes β the primitive behind the published multi-stage chain
(DOM clobbering β REST JSONP β Application Password theft β plugin upload β
RCE against a logged-in admin victim).
## What this tool does
Two non-destructive probes (a failed login with a random marker username):
1. **RAW_HTML** β `marker` appears unescaped in the error response.
2. **AREA_BYPASS** β `` survives `strip_tags()` and reappears
as a live/normalized element (e.g. `area id="marker"`) in the response.
No payload executes anything; the tool only measures whether attacker HTML is
rendered as live DOM. Optional extras:
- `--version` β fingerprint core version via the feed `` tag.
- `--jsonp` β verify the REST JSONP envelope (`_jsonp`/`_envelope`) used by
the published chain is reachable.
## Usage
```bash
python3 xss2shell_check.py https://example.com
python3 xss2shell_check.py --jsonp --verbose https://example.com
python3 xss2shell_check.py --version https://example.com
python3 xss2shell_check.py --json https://example.com
```
Python 3.6+, stdlib only. No dependencies.
| Flag | Purpose |
|------|---------|
| `--version` | fingerprint core version (feed generator tag, homepage meta fallback) |
| `--jsonp` | also verify the REST JSONP envelope (`_jsonp`/`_envelope`) is reachable |
| `-v, --verbose` | print probe response snippets (evidence for reports) |
| `--json` | machine-readable JSON result (CI / automation) |
### Exit codes
| Code | Meaning |
|------|-------------------------------------------|
| 0 | VULNERABLE (reflection primitive present) |
| 1 | PATCHED / NOT VULNERABLE |
| 2 | ERROR (unreachable, WAF challenge, unexpected response) |
## Detection matrix
| Observed behavior | Verdict | Exit |
|---|---|---|
| `marker` echoed unescaped | RAW_HTML β vulnerable | 0 |
| `` re-parsed into a live `` (any quoting / void form) | AREA_BYPASS β vulnerable | 0 |
| Username HTML-escaped | ESCAPED β not vulnerable | 1 |
| Tags stripped, text remains | STRIPPED β not vulnerable | 1 |
| Raw `` passes through but is never re-parsed | RAW_TEXT_ONLY β inert text, not vulnerable | 1 |
| No echo at all | NOT_REFLECTED β not vulnerable | 1 |
| Probe blocked (HTTP β₯ 400 / challenge page) or target unreachable | ERROR | 2 |
## Detection notes
- The **vulnerable signature is the normalized element** (``).
Attribute quoting varies by KSES generation (old custom parser:
``; DOMDocument: `` / ``), so all
forms are matched. A raw `` passthrough *without* re-parsing is
inert text in the browser, not the primitive β it is reported as
`RAW_TEXT_ONLY` and does not trigger a false positive.
- The version label is **advisory only**: patched backports (6.9.6, 6.8.7,
6.7.6, 6.6.6, 6.5.9, 4.7.34, β¦) fall *inside* the 4.7.0β7.0.2 series and
are accounted for per branch; the reflection check stays authoritative.
- Requests: 1 GET (login page β also captures WAF/sticky cookies and the
effective URL after redirects) + 2 POSTs with unique random markers.
POST redirects are re-issued as POST. WAF blocks surface as exit 2, not
as a silent "not vulnerable".
- A false negative is possible if a custom `login_errors` filter or CDN/WAF
rewrites responses, or the login error never echoes the username.
## Disclaimer
Authorized security testing only. This tool is intended exclusively for
testing systems you own or have explicit written permission to assess.
Unauthorized testing is illegal in most jurisdictions.
## References
- [Criminal IP β WordPress Vulnerability CVE-2026-64638: Login Page XSS to Server-Side Code Execution](https://www.criminalip.io/knowledge-hub/blog/37190)
- [CUHK ITS β WordPress Pre-Authenticated XSS Vulnerability "XSS2Shell" (CVE-2026-64638)](https://www.itsc.cuhk.edu.hk/all-it/information-security/information-security-alerts/wordpress-pre-authenticated-xss-vulnerability-xss2shell-cve-2026-64638/)
## License
[MIT](LICENSE)