
Verhaltensbasierter WordPress-CVE-2026-64638-Scanner, der gutartige Login-Probes verwendet; klassifiziert das Sanitizer-Verhalten und erzeugt reine Alert-PoCs für autorisierte Nutzung.
Verhaltensbasierter Massen-Scanner und beweistauglicher PoC-Generator für die WordPress-Pre-Auth-XSS-zu-RCE-Kette, die über 500 Millionen Websites betrifft.
Nur Erkennung. Keine Waffenisierung. Entwickelt für Bug-Bounty-Programme und Blue Teams.
Was ist das? • Schnellstart • Shodan-Dorks • Verwendung • Entscheidungsmatrix • Erkennung • FAQ
Durchsuchen Sie vor dem Scannen das Internet nach potenziell verwundbaren WordPress-Instanzen:
http.component:"wordpress" -http.title:"Just a moment"
Findet WordPress-Seiten und schließt dabei Cloudflare-Seiten im Modus "I'm Under Attack" sowie Bot-Schutz-Seiten aus, die automatisierte Anfragen blockieren oder mit einer Challenge beantworten.
http.component:"wordpress" http.title:"Log In"
Gibt nur WordPress-Anmeldeseiten zurück — genau die Angriffsfläche für CVE-2026-64638.
http.component:"wordpress" "wp-content" "?ver=7.0" -"?ver=7.0.3"
Markiert WordPress-7.0.x-Instanzen ohne den 7.0.3-Patch per Asset-Versions-Fingerprinting.
http.component:"wordpress" http.html:"wp-login.php"
Erfasst Seiten, auf denen wp-login.php erreichbar ist, aber nicht unbedingt die aktuelle Seite ist — für eine breitere Abdeckung.
http.component:"wordpress" -http.title:"Just a moment" -http.title:"Attention Required" -org:"Cloudflare"
Aggressiver Filter, der die meisten Cloudflare-geschützten Ziele entfernt. Für Scans in großem Maßstab mit --active verwenden — Cloudflare drosselt oder blockiert die Probe-Anfrage.
Tipp: Exportieren Sie Shodan-Ergebnisse mit
shodan downloadund leiten Sie die Hostnamen direkt inxss2shell_mass.py -iweiter.
Am 7. August 2026 hat pwn.ai CVE-2026-64638 (XSS2Shell) offengelegt — eine kritische Pre-Auth-Cross-Site-Scripting-Schwachstelle im WordPress-Core, die sich bis hin zur Remote-Codeausführung auf dem Server ausweiten lässt. [citation:pwn.ai blog]
Der Fehler nutzt eine Parser-Diskrepanz zwischen PHP strip_tags() und WordPress wp_kses_post() aus:
strip_tags() verwendet < unmittelbar gefolgt von einem Buchstaben, um HTML-Tags zu identifizieren. < area id=...> (mit einem Leerzeichen) wird als Text behandelt — es überlebt.wp_kses_post() (KSES) erkennt < area als gültiges <area>-Element — und <area> ist in KSES auf der Whitelist. [citation:pwn.ai blog]Ein fehlgeschlagener Login mit einem speziell präparierten Benutzernamen < area id=ajaxurl href=/?rest_route=/&_method=GET&_jsonp=alert>... umgeht beide Sanitizer, wird als Live-DOM auf der Anmeldeseite gerendert, kapert das eigene user-profile.js-Skript von WordPress per DOM-Clobbering und löst alert() im WordPress-Ursprung aus — null Klicks, keine Authentifizierung, keine Cookies erforderlich. [citation:pwn.ai blog]
Zu einem angemeldeten Administrator eskaliert? Dieselbe Primitive stiehlt Application Passwords per Same-Origin-Method-Execution (SOME), lädt ein bösartiges Plugin hoch und führt PHP als www-data aus. [citation:pwn.ai blog] [citation:hadrian.io blog]
Betroffen: WordPress 6.4 bis 7.0.2 — in 7.0.3 gepatcht, mit Backports bis 4.7+.
Auswirkungen: ~500 Millionen Websites zum Zeitpunkt der Offenlegung. [citation:pwn.ai blog]
Dies ist ein reines Erkennungs-Toolkit. Es beinhaltet keine Waffenisierung der Schwachstelle — es gibt Sicherheitsforschern, Bug-Bounty-Jägern und Blue Teams alles an die Hand, um:
"Ein Versionsstring sagt, welcher Patchstand der Code sein sollte.
Nur das Verhalten des Anmeldeseiten-Sanitizers sagt, ob der Fehler greift."
Verwaltete Hosts portieren Sicherheitspatches still zurück, ohne die Versionsstrings zu erhöhen. Login-Härtungs-Plugins ersetzen die Fehlermeldung vollständig und unterbinden damit den Reflexionskanal selbst auf unsicheren Versionen. Reine Versions-Scanner erzeugen False Positives und False Negatives. Dieser Scanner sendet eine einzige harmlose Probe und klassifiziert das tatsächliche Sanitizer-Verhalten.
git clone https://github.com/jakestone/xss2shell.git
cd xss2shell
pip install -r requirements.txt
# Passive — no probes sent to target, version + endpoint fingerprinting only
python3 xss2shell_mass.py -i domains.txt -o results
# Active — sends ONE benign failed-login per host (authorized assets only!)
python3 xss2shell_mass.py -i domains.txt -o results --active --workers 80
# Single target
python3 make_poc.py --target https://blog.example.com
# Batch from scanner output
python3 make_poc.py --from-results results.csv -o pocs/
Öffnen Sie die generierte .poc.html in Ihrem Browser und zeichnen Sie dabei ein Video auf → wenn alert() ausgelöst wird, haben Sie Pre-Auth-XSS-Beweise erfasst.
xss2shell_mass.py)usage: xss2shell_mass.py [-h] -i INPUT [-o OUTPUT]
[--active] [--workers WORKERS]
[--timeout TIMEOUT] [--quiet]
?ver=-Parameter, wp-content-Referenzen)user-profile.js-Gadget eingebunden, Core-Asset-Versionen/?rest_route=/&_method=GET&_jsonp=<random> — ist der JSONP-Pfad offen?--active-Flag)Sendet einen einzelnen fehlgeschlagenen Login mit dem Benutzernamen < area id=<RANDOM> href=/x2s> und klassifiziert die HTML-Antwort:
bypass — Echtes <area>-Element mit unserer Markierung hat überlebt → strip_tags/KSES-Diskrepanz BESTÄTIGTescaped — Markierung vorhanden, aber Entity-kodiert → Patch oder Härtung vorhandenstripped — Standard-WP-Fehler angezeigt, Tags entfernt → acevomod oder gepatchtclosed — Keinerlei Benutzername-Reflexion → Login-Härtungs-Plugin installiertmake_poc.py)usage: make_poc.py [-h] [--target TARGET] [--from-results FROM_RESULTS]
[-o OUTDIR]
Generiert für jedes Ziel die veröffentlichte pwn.ai-PoC-Seite — das exakte HTML-Formular, das auf einem ungepatchten WordPress alert() auslöst. Drei Payload-Varianten sind in Kommentaren enthalten:
Die Entscheidungs-Engine des Scanners kombiniert die Versionsklassifizierung (aus der stable-check-API von WordPress.org) mit verhaltensbasierten Beweisen, um 10 unterschiedliche Einstufungen zu erzeugen:
CSV-Spalten: host, url, status, checker_status, wp_version, branch_status, evidence, http, ms, error
Die Spalte checker_status bildet auf das Vokabular des öffentlichen pwn.ai-Checkers ab (vulnerable / patched / not_wordpress / unreachable / inconclusive / error), für eine direkte Korrelation.
Wenn Sie auf der Verteidigungsseite stehen, finden Sie hier die forensischen Signale, die diese Schwachstelle hinterlässt:
# Primary signal: encoded '<' in the log parameter
POST /wp-login.php → log=%3C... (URL-encoded < in username field)
# Higher confidence: paired with REST pivoting
GET /?rest_route=/&_method=GET&_jsonp=... # JSONP callback
GET /wp-json/wp/v2/statuses/publish?_jsonp=... # WAF-bypass variant
# Escalation stage indicators
GET /wp-admin/authorize-application.php?success_url=<off-origin>
POST /wp-admin/update.php?action=upload-plugin
GET /wp-content/plugins/<random>/shell.php
Blockieren Sie POST /wp-login.php, wenn der log-Parameter %3C (URL-kodiertes <) enthält. Gültige WordPress-Benutzernamen enthalten niemals spitze Klammern. Nicht auf bestimmte Tags eingrenzen — KSES erlaubt Tabulator, Zeilenumbruch und Wagenrücklauf nach < sowie jedes Whitelist-Tag, daher lässt sich eine Tag-spezifische Regel trivial umgehen. [citation:hadrian.io blog]
Der _jsonp=-Callback in der Eskalationsphase verwendet Punkte für die Eigenschafts-Traversierung (z. B. window.opener.approve.click). Kennzeichnen Sie REST-Anfragen mit gepunkteten JSONP-Callbacks als starke Indikatoren für eine Ausnutzung. [citation:hadrian.io blog]
THIS TOOL IS DETECTION-ONLY. IT DOES NOT:
✗ Weaponize the JSONP callback beyond the public alert()
✗ Include admin-lure pages or Application Password capture
✗ Include REST abuse, plugin upload, or PHP shell code
✗ Execute more than one failed login per target per scan
YOU MUST:
✓ Only scan assets you own or have written authorization to test
✓ Only generate PoCs for your own browser on your own server
✓ Never send PoC links to site admins/users
✓ Never escalate past alert() without program written approval
✓ Follow the bug bounty program scope and rules
This toolkit exists for authorized security research, bug bounty
programs, and defensive detection engineering. Misuse is your
responsibility.
xss2shell/
├── README.md ← You are here
├── xss2shell_mass.py ← Behavior-first mass scanner (v1.1.0)
├── make_poc.py ← Evidence-grade PoC page generator
├── requirements.txt ← Python dependencies (just `requests`)
├── .gitignore ← Ignores scan outputs and cache
└── example/
├── domains.txt ← Example input file
└── example_output.csv ← Example scan output
F: Warum nicht einfach den WordPress-Versionsstring prüfen?
A: Verwaltete Hosts (WP Engine, Kinsta, Pantheon usw.) portieren Sicherheitspatches häufig zurück, ohne die Version zu erhöhen. Login-Härtungs-Plugins ersetzen die Fehlermeldung vollständig. Beide Fälle erzeugen False Positives bei reinen Versions-Scannern und False Negatives bei verborgenen Versionen. Dieser Scanner testet das tatsächliche Sanitizer-Verhalten.
F: Ist die --active-Probe gefährlich?
A: Nein. Sie sendet genau einen fehlgeschlagenen Login mit einem harmlosen Markierungs-Benutzernamen. Sie versucht nicht, JavaScript auszuführen, enumeriert keine gültigen Benutzernamen und löst keinen tatsächlichen Exploit aus. Sie ist weniger invasiv als ein normaler Anmeldeversuch.
F: Kann dieses Tool für nicht autorisierte Scans verwendet werden?
A: Nein. Die aktive Probe sendet einen HTTP-POST an /wp-login.php, also eine Anfrage an den Zielserver. Verwenden Sie es nur für Assets, die Ihnen gehören oder für die Sie eine ausdrückliche schriftliche Genehmigung zum Testen haben.
F: Was ist der Unterschied zwischen vulnerable und confirmed_vulnerable?
A: vulnerable bedeutet, dass die WordPress.org-API die Version als unsicher einstuft, wir die strip_tags/KSES-Diskrepanz aber nicht verhaltensbasiert bestätigt haben. confirmed_vulnerable bedeutet, dass wir eine Probe gesendet haben und das <area>-Element beide Sanitizer überlebt hat — die veröffentlichte Kette kann greifen.
F: Kann ich das für meine Bug-Bounty-Programm-Berichte verwenden?
A: Ja! Die Spalte checker_status bildet direkt auf das Vokabular des öffentlichen pwn.ai-Checkers ab, für eine einfache Korrelation. Kombinieren Sie Scan-Ergebnisse mit PoC-Videobeweisen aus make_poc.py für vollständige Berichte.
F: Erkennt dieses Tool die RCE-Kette?
A: Nein. Dieses Toolkit erkennt den Pre-Auth-XSS-Einstiegspunkt. Die vollständige RCE-Kette erfordert einen angemeldeten Administrator, aktivierte Application Passwords und Plugin-Upload-Berechtigungen — Bedingungen, die dieser Scanner nicht bewertet. Der Scanner konzentriert sich auf das, was extern beobachtbar ist: die Sanitizer-Umgehung.
Erstellt von 0xlipon • Nur Erkennung • Nur für autorisierte Nutzung
| Ressource | Link |
|---|
| Originale Offenlegung (pwn.ai) | pwn.ai/blog/xss2shell |
| Technische Analyse (Hadrian) | hadrian.io/blog/wordpress-xss2shell |
| WordPress-Sicherheitshinweis (GHSA) | GHSA-52p2-r8wf-jcrf |
| SOME-Angriffsforschung (2022) | pwn.ai/blog/bypass-csp-using-wordpress |
| WordPress-7.0.3-Release | wordpress.org/news/2026/08/wordpress-7-0-3-release |
| Flag | Beschreibung |
|---|
-i, --input | Datei mit einem Host pro Zeile (nackte Domain oder vollständige URL) |
-o, --output | Basis-Pfad für Ausgabedateien (erzeugt .csv + .json) |
--active | Verhaltensprobe aktivieren — ein fehlgeschlagener Login pro Host |
--workers | Thread-Pool-Größe (Standard: 50, max. ~200 bei guten Verbindungen) |
--timeout | HTTP-Timeout in Sekunden (Standard: 10) |
--quiet | Nur confirmed_vulnerable, vulnerable und likely_vulnerable ausgeben |
| Variante | href-Wert | Wann verwenden |
|---|
| Standard | /?rest_route=/&_method=GET&_jsonp=alert | Standard-WordPress |
| Envelope | /?rest_route=/&_method=GET&_envelope=1&_jsonp=alert | REST gibt 401 zurück (verpackt in 200) |
| WAF-Pivot | /wp-json/wp/v2/statuses/publish?_jsonp=alert&_method=GET | ?rest_route= von WAF blockiert |
| Einstufung | Bedingungen |
|---|
confirmed_vulnerable 🔴 | Version ist unsicher UND die Proben-Markierung hat als <area>-Element überlebt UND das user-profile.js-Gadget ist vorhanden |
vulnerable 🔴 | Version ist laut wordpress.org unsicher; Verhaltensprobe NICHT ausgeführt (erneut mit --active ausführen) |
likely_vulnerable 🟠 | Proben-Markierung hat überlebt, ABER user-profile.js nicht eingebunden (veröffentlichtes Auto-Fire-Gadget fehlt) |
mitigated 🟣 | Version ist unsicher, ABER Proben-Markierung wurde escaped/stripped/closed (stiller Backport oder Härtung) |
likely_patched 🟢 | Version verborgen/unbekannt, ABER Proben-Markierung wurde escaped/stripped |
patched 🟢 | Version ist latest oder outdated (hat Sicherheits-Backports) |
not_wordpress ⚫ | Kein WordPress-Fingerprint erkannt |
unreachable ⚫ | Verbindung fehlgeschlagen (Timeout, SSL, DNS) |
inconclusive 🟡 | WAF-Block, Cloudflare-Challenge, verborgene Version ohne Probe oder Anmeldeseite fehlt |
error 🟡 | Unerwarteter Fehler während des Scans |