Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
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.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-97657 — Python PoC for CVE-2026-97657: forges AES-CTR recovery tokens via XOR malleability to bypass authentication and take over WordPress accounts in Abandoned Cart Pro ≤10.8.0. | Kitploit
Tools/GitHubGitHub/murrez/cve-2026-97657
Privilege EscalationVulnerability ScannersVulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityCryptographyAuthentication
GitHubmurrez/cve-2026-97657

CVE-2026-97657

Python PoC for CVE-2026-97657: forges AES-CTR recovery tokens via XOR malleability to bypass authentication and take over WordPress accounts in Abandoned Cart Pro ≤10.8.0.

122 days 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
View Repository

CVE-2026-97657 — Abandoned Cart Pro for WooCommerce authentication bypass

Python 3 PoC for CVE-2026-97657 — Abandoned Cart Pro for WooCommerce (Tyche Softwares) ≤ 10.8.0. CNA: Wordfence.

ProductAbandoned Cart Pro for WooCommerce
Affected≤ 10.8.0 (upgrade to a fixed release above 10.8.0)
CWECWE-639 — authorization bypass through user-controlled key
CVSS 3.19.8 Critical
Verify markerPOCBIT-97657-OK (session/admin check)
PoCbithttps://pocbit.org/pocs/cve-2026-97657

Description

Recovery links use MAC-free AES-CTR tokens (Wcal_Aes_Ctr-compatible layout: 8-byte CTR nonce + ciphertext, base64). The plugin loads the per-email encrypt_key from the attacker-controlled user_email query parameter. In wcap_email_track_links() (Pro; Lite analogue wcal_email_track_links()), the wcap_nonce / HMAC check runs only when wcap_nonce is non-empty, so omitting it skips integrity verification. After decryption, the abandoned_id (cart row ID) is used without proving it belongs to that email, then wp_set_auth_cookie() runs when auto-login is enabled (default).

An unauthenticated attacker with one legitimate recovery URL from their own reminder email can XOR-malleate the CTR ciphertext to change the embedded cart ID to a victim’s abandoned cart ID (same length as the source ID), open the forged URL without wcap_nonce, and log in as the victim (including administrators who abandoned a cart).

Typical URL shape (Pro):

GET /?wacp_action=checkout_link&[email protected]&validate=<token>

(wcap_action / wcal_action variants exist; track-links URLs may include extra parameters such as c=.)


Requirements

cd CVE-2026-97657
pip install -r requirements.txt
  • Python 3.9+
  • Dependencies: requests, urllib3

Usage overview

ModePurposeRequired arguments
check (default)Read plugin readme.txt, flag version ≤ 10.8.0-t URL or --list FILE
forgeBuild forged recovery URL locally (no HTTP)--recovery-link, --source-cart-id, --target-cart-id
exploitForge token + HTTP GET + verify WordPress sessionSame as forge

Recommended workflow (authorized lab):

  1. Mass or single check — confirm plugin slug + version ≤ 10.8.0.
  2. forge — validate cart ID padding and URL shape before sending traffic.
  3. exploit — one GET to the forged recovery URL; confirm cookies + /wp-admin/.

Exploit/forge does not use -t / --list. The target host is taken from --recovery-link (scheme + host).


Prerequisites (exploit / forge)

RequirementWhy
One legitimate recovery URLSupplies a valid CTR nonce + ciphertext and (usually) your user_email / encrypt_key row in ac_sent_history
Plugin ≤ 10.8.0 with auto-login enabled (default)Patched builds or disabled auto-login block wp_set_auth_cookie()
Victim registered WordPress user with an abandoned cart rowTakeover path logs in user_id from ac_abandoned_cart_history; pure guest carts use a different branch
checkout_link URL strongly preferredPlaintext is {abandoned_cart_id}&url=.... track_links tokens encode email_sent_id, not cart ID — wrong ID type breaks the forge
Equal-length IDsCTR XOR malleability only flips bytes 1:1; pad with zeros (see below)

Obtaining --recovery-link

  1. On the target shop, register/login as a user you control.
  2. Add products to cart and leave checkout (abandon).
  3. Wait for a reminder email (or shorten cutoff timers in a lab you own).
  4. Copy the full checkout_link from the email (or from webhooks / plugin export if enabled).

Example Pro shapes (from vendor docs / 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>

Paste the URL exactly as in the email (including validate; query order does not matter).

Obtaining cart row IDs

SourceField
WooCommerce Abandoned Cart → Cart details (admin)Abandoned cart ID (DB primary key)
Webhook payload (wcap_cart, checkout_link context)"id": "383" on the cart resource
MySQL (lab)wp_ac_abandoned_cart_history.id (Pro table prefix may differ)

--source-cart-id must be the ID inside your token’s plaintext (your abandoned cart row). --target-cart-id is the victim’s row in the same table.

Zero-padding (same length)

The PoC rejects mismatched lengths. Pad both IDs to the same width:

Source (yours)Target (victim)OK?
383001Yes (3 chars)
03830001Yes (4 chars)
3831No — run forge with 0383 / 0001 instead

CLI reference

FlagModesMeaning
-t, --targetcheckWordPress site root, e.g. https://shop.example.com
--list FILEcheckOne site URL per line; # comments ignored
--modeallcheck (default), forge, exploit
--recovery-link URLforge, exploitFull recovery URL from reminder email
--source-cart-idforge, exploitYour abandoned cart row ID (in token plaintext)
--target-cart-idforge, exploitVictim abandoned cart row ID (same string length)
-j Ncheck (list)Parallel workers (default 8)
--timeout SECcheck, exploitHTTP timeout (default 15)
--insecurecheck, exploitDisable TLS certificate verification
--jsonl FILEcheck, exploitAppend one JSON object per run
--vuln-list FILEcheckWrite URLs with version ≤ 10.8.0
-q, --quietallLess console output
--no-colorallPlain terminal

Exit codes

CodeWhen
0Exploit: success: true; forge: always; check: always (single -t)
1Exploit: login/admin verification failed
2Check list run with no -t semantics (informational)

Check mode

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.txt
  • Alternate slug woocommerce-abandoned-cart-pro

Forge mode (offline)

python poc.py --mode forge \
  --recovery-link "https://shop.example.com/?wacp_action=checkout_link&[email protected]&validate=..." \
  --source-cart-id "0383" \
  --target-cart-id "0001"

Output JSON includes exploit_url (HMAC suffix stripped from validate, nonce parameters removed).

The PoC also removes wcap_nonce / wcal_nonce from the query if they were present on the original link.


Exploit mode (--mode exploit)

Performs local token forgery then a single unauthenticated HTTP GET (plus redirect follows). No WordPress credentials are sent.

Attack chain (what the PoC automates)

sequenceDiagram
  participant Att as Attacker PoC
  participant WP as WordPress + Pro plugin
  participant DB as Plugin DB
Download Tool