
Python-PoC für CVE-2026-97657: fälscht AES-CTR-Wiederherstellungstoken durch XOR-Malleabilität, um die Authentifizierung zu umgehen und WordPress-Konten in Abandoned Cart Pro ≤10.8.0 zu übernehmen.
Python-3-PoC für CVE-2026-97657 — Abandoned Cart Pro for WooCommerce (Tyche Softwares) ≤ 10.8.0. CNA: Wordfence.
| Produkt | Abandoned Cart Pro for WooCommerce |
| Betroffen | ≤ 10.8.0 (Upgrade auf eine korrigierte Version über 10.8.0) |
| CWE | CWE-639 — Autorisierungsumgehung durch benutzergesteuerten Schlüssel |
| CVSS 3.1 | 9.8 Kritisch |
| Verifikationsmarker | POCBIT-97657-OK (Session-/Admin-Prüfung) |
| PoCbit | https://pocbit.org/pocs/cve-2026-97657 |
Wiederherstellungslinks verwenden MAC-freie AES-CTR-Token (mit Wcal_Aes_Ctr kompatibles Layout: 8-Byte-CTR-Nonce + Chiffretext, base64). Das Plugin lädt den encrypt_key pro E-Mail aus dem vom Angreifer kontrollierten user_email-Query-Parameter. In wcap_email_track_links() (Pro; Lite-Analogon wcal_email_track_links()) läuft die Prüfung von wcap_nonce / HMAC nur, wenn wcap_nonce nicht leer ist, sodass das Weglassen die Integritätsprüfung überspringt. Nach der Entschlüsselung wird die abandoned_id (Warenkorb-Zeilen-ID) verwendet, ohne zu belegen, dass sie zu dieser E-Mail gehört, und anschließend läuft wp_set_auth_cookie(), wenn die automatische Anmeldung aktiviert ist (Standard).
Ein nicht authentifizierter Angreifer mit einer legitimen Wiederherstellungs-URL aus seiner eigenen Erinnerungs-E-Mail kann den CTR-Chiffretext per XOR-Manipulation so verändern, dass die eingebettete Warenkorb-ID zu einer Warenkorb-ID des Opfers wird (gleiche Länge wie die Quell-ID), die gefälschte URL ohne wcap_nonce öffnen und sich als das Opfer anmelden (einschließlich Administratoren, die einen Warenkorb abgebrochen haben).
Typische URL-Form (Pro):
GET /?wacp_action=checkout_link&[email protected]&validate=<token>
(wcap_action / wcal_action-Varianten existieren; Track-Link-URLs können zusätzliche Parameter wie c= enthalten.)
cd CVE-2026-97657
pip install -r requirements.txt
requests, urllib3| Modus | Zweck | Erforderliche Argumente |
|---|---|---|
check (Standard) | Liest die Plugin-readme.txt und meldet Version ≤ 10.8.0 | -t URL oder --list FILE |
forge | Erstellt lokal eine gefälschte Recovery-URL (kein HTTP) | --recovery-link, --source-cart-id, --target-cart-id |
exploit | Fälscht Token + HTTP GET + verifiziert WordPress-Session | Wie bei forge |
Empfohlener Workflow (autorisiertes Labor):
check — Plugin-Slug + Version ≤ 10.8.0 bestätigen.forge — Cart-ID-Padding und URL-Form validieren, bevor Traffic gesendet wird.exploit — ein GET an die gefälschte Recovery-URL; Cookies + /wp-admin/ bestätigen.Exploit/forge verwendet nicht -t / --list. Der Zielhost wird aus --recovery-link übernommen (Schema + Host).
| Anforderung | Warum |
|---|---|
| Eine legitime Recovery-URL | Liefert einen gültigen CTR-Nonce + Ciphertext und (üblicherweise) deine user_email / encrypt_key-Zeile in ac_sent_history |
| Plugin ≤ 10.8.0 mit aktiviertem Auto-Login (Standard) | Gepatchte Builds oder deaktiviertes Auto-Login blockieren wp_set_auth_cookie() |
| Registrierter WordPress-Benutzer als Opfer mit einer abandoned-cart-Zeile | Der Übernahmepfad meldet user_id aus ac_abandoned_cart_history an; reine Gast-Carts verwenden einen anderen Zweig |
checkout_link-URL stark bevorzugt | Der Klartext ist {abandoned_cart_id}&url=.... track_links-Tokens kodieren email_sent_id, nicht die Cart-ID — falscher ID-Typ bricht die Forge |
| Gleich lange IDs | CTR-XOR-Malleabilität ändert nur Bytes 1:1; mit Nullen auffüllen (siehe unten) |
--recovery-link beschaffencheckout_link aus der E-Mail kopieren (oder aus Webhooks / Plugin-Export, falls aktiviert).Beispielhafte Pro-Formen (aus Herstellerdokumentation / Webhooks):
https://shop.example/?wacp_action=checkout_link&validate=<base64-token>
https://shop.example/?wacp_action=checkout_link&[email protected]&validate=<token>
https://shop.example/?wacp_action=track_links&[email protected]&validate=<token>&c=<coupon-token>
Fügen Sie die URL exakt wie in der E-Mail ein (einschließlich validate; die Reihenfolge der Query-Parameter spielt keine Rolle).
| Quelle | Feld |
|---|---|
| WooCommerce Abandoned Cart → Cart details (Admin) | Abandoned-Cart-ID (DB-Primärschlüssel) |
Webhook-Payload (wcap_cart, checkout_link-Kontext) | "id": "383" auf der Warenkorb-Ressource |
| MySQL (Lab) | wp_ac_abandoned_cart_history.id (Pro-Tabellenpräfix kann abweichen) |
--source-cart-id muss die ID innerhalb des Klartexts Ihres Tokens sein (Ihre Abandoned-Cart-Zeile). --target-cart-id ist die Zeile des Opfers in derselben Tabelle.
Der PoC lehnt unterschiedliche Längen ab. Füllen Sie beide IDs auf dieselbe Breite auf:
| Quelle (Ihre) | Ziel (Opfer) | OK? |
|---|---|---|
383 | 001 | Ja (3 Zeichen) |
0383 | 0001 | Ja (4 Zeichen) |
383 | 1 | Nein — führen Sie forge stattdessen mit 0383 / 0001 aus |
| Flag | Modi | Bedeutung |
|---|---|---|
-t, --target | check | WordPress-Site-Root, z. B. https://shop.example.com |
--list FILE | check | Eine Site-URL pro Zeile; #-Kommentare werden ignoriert |
--mode | alle | check (Standard), forge, exploit |
--recovery-link URL | forge, exploit | Vollständige Wiederherstellungs-URL aus der Erinnerungs-E-Mail |
--source-cart-id | forge, exploit | Ihre Abandoned-Cart-Zeilen-ID (im Token-Klartext) |
--target-cart-id | forge, exploit | Abandoned-Cart-Zeilen-ID des Opfers (gleiche String-Länge) |
-j N | check (Liste) | Parallele Worker (Standard 8) |
--timeout SEC | check, exploit | HTTP-Timeout (Standard 15) |
--insecure | check, exploit | TLS-Zertifikatsprüfung deaktivieren |
--jsonl FILE | check, exploit | Ein JSON-Objekt pro Lauf anhängen |
--vuln-list FILE | check | URLs mit Version ≤ 10.8.0 schreiben |
-q, --quiet | alle | Weniger Konsolenausgabe |
--no-color | alle | Einfaches Terminal |
Exit-Codes
| Code | Wann |
|---|---|
| 0 | Exploit: success: true; forge: immer; check: immer (einzelnes -t) |
| 1 | Exploit: Login-/Admin-Verifizierung fehlgeschlagen |
| 2 | Check-Listen-Lauf ohne -t-Semantik (informativ) |
python poc.py -t https://shop.example.com --mode check
python poc.py --list targets.example.txt --mode check -j 16 --vuln-list hits.txt --jsonl scan.jsonl
Probes:
/wp-content/plugins/woocommerce-abandon-cart-pro/readme.txtwoocommerce-abandoned-cart-pro