
PoC em Python para CVE-2026-97657: forja tokens de recuperação AES-CTR via maleabilidade XOR para contornar a autenticação e assumir o controle de contas WordPress no Abandoned Cart Pro ≤10.8.0.
PoC em Python 3 para CVE-2026-97657 — Abandoned Cart Pro for WooCommerce (Tyche Softwares) ≤ 10.8.0. CNA: Wordfence.
| Produto | Abandoned Cart Pro for WooCommerce |
| Afetado | ≤ 10.8.0 (atualize para uma versão corrigida acima de 10.8.0) |
| CWE | CWE-639 — bypass de autorização por meio de chave controlada pelo usuário |
| CVSS 3.1 | 9.8 Crítico |
| Marcador de verificação | POCBIT-97657-OK (verificação de sessão/admin) |
| PoCbit | https://pocbit.org/pocs/cve-2026-97657 |
Os links de recuperação usam tokens AES-CTR sem MAC (layout compatível com Wcal_Aes_Ctr: nonce CTR de 8 bytes + texto cifrado, base64). O plugin carrega a encrypt_key por e-mail a partir do parâmetro de consulta user_email controlado pelo atacante. Em wcap_email_track_links() (Pro; análogo no Lite wcal_email_track_links()), a verificação de wcap_nonce / HMAC é executada somente quando wcap_nonce não está vazio, portanto omiti-lo ignora a verificação de integridade. Após a descriptografia, o abandoned_id (ID da linha do carrinho) é usado sem comprovar que pertence àquele e-mail, e então wp_set_auth_cookie() é executado quando o login automático está habilitado (padrão).
Um atacante não autenticado com uma URL de recuperação legítima do seu próprio e-mail de lembrete pode mallear por XOR o texto cifrado CTR para alterar o ID de carrinho embutido para o ID do carrinho abandonado da vítima (mesmo comprimento do ID de origem), abrir a URL forjada sem wcap_nonce e fazer login como a vítima (incluindo administradores que abandonaram um carrinho).
Formato típico da URL (Pro):
GET /?wacp_action=checkout_link&[email protected]&validate=<token>
(Existem variantes wcap_action / wcal_action; os URLs de track-links podem incluir parâmetros extras, como c=.)
cd CVE-2026-97657
pip install -r requirements.txt
requests, urllib3| Modo | Finalidade | Argumentos obrigatórios |
|---|---|---|
check (padrão) | Lê o readme.txt do plugin, sinaliza versão ≤ 10.8.0 | -t URL ou --list FILE |
forge | Constrói localmente a URL de recuperação forjada (sem HTTP) | --recovery-link, --source-cart-id, --target-cart-id |
exploit | Forja o token + HTTP GET + verifica a sessão do WordPress | O mesmo que forge |
Fluxo de trabalho recomendado (laboratório autorizado):
check em massa ou individual — confirme o slug do plugin + versão ≤ 10.8.0.forge — valide o preenchimento do cart ID e o formato da URL antes de enviar tráfego.exploit — um GET para a URL de recuperação forjada; confirme os cookies + /wp-admin/.Exploit/forge não usa -t / --list. O host de destino é obtido de --recovery-link (esquema + host).
| Requisito | Motivo |
|---|---|
| Uma URL de recuperação legítima | Fornece um nonce CTR válido + ciphertext e (normalmente) sua linha de user_email / encrypt_key em ac_sent_history |
| Plugin ≤ 10.8.0 com auto-login habilitado (padrão) | Builds corrigidos ou auto-login desabilitado bloqueiam wp_set_auth_cookie() |
| Usuário registrado do WordPress vítima com uma linha de carrinho abandonado | O caminho de takeover faz login com user_id de ac_abandoned_cart_history; carrinhos puramente de convidados usam um ramo diferente |
URL checkout_link fortemente preferida | O texto simples é {abandoned_cart_id}&url=.... Tokens track_links codificam email_sent_id, não o cart ID — tipo de ID errado quebra o forge |
| IDs de comprimento igual | A maleabilidade XOR do CTR apenas inverte bytes 1:1; preencha com zeros (veja abaixo) |
--recovery-linkcheckout_link completo do e-mail (ou de webhooks / exportação do plugin, se habilitado).Exemplos de formatos Pro (da documentação do fornecedor / 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>
Cole a URL exatamente como no e-mail (incluindo validate; a ordem dos parâmetros não importa).
| Origem | Campo |
|---|---|
| WooCommerce Abandoned Cart → Cart details (admin) | ID do carrinho abandonado (chave primária do BD) |
Payload do Webhook (contexto wcap_cart, checkout_link) | "id": "383" no recurso do carrinho |
| MySQL (lab) | wp_ac_abandoned_cart_history.id (o prefixo da tabela Pro pode variar) |
--source-cart-id deve ser o ID dentro do texto simples do seu token (sua linha de carrinho abandonado). --target-cart-id é a linha da vítima na mesma tabela.
O PoC rejeita comprimentos incompatíveis. Preencha ambos os IDs com a mesma largura:
| Origem (seu) | Destino (vítima) | OK? |
|---|---|---|
383 | 001 | Sim (3 caracteres) |
0383 | 0001 | Sim (4 caracteres) |
383 | 1 | Não — execute forge com 0383 / 0001 em vez disso |
| Flag | Modos | Significado |
|---|---|---|
-t, --target | check | Raiz do site WordPress, ex.: https://shop.example.com |
--list FILE | check | Uma URL de site por linha; comentários com # são ignorados |
--mode | todos | check (padrão), forge, exploit |
--recovery-link URL | forge, exploit | URL de recuperação completa do e-mail de lembrete |
--source-cart-id | forge, exploit | ID da sua linha de carrinho abandonado (no texto simples do token) |
--target-cart-id | forge, exploit | ID da linha de carrinho abandonado da vítima (mesmo comprimento de string) |
-j N | check (lista) | Workers paralelos (padrão 8) |
--timeout SEC | check, exploit | Timeout HTTP (padrão 15) |
--insecure | check, exploit | Desativar a verificação do certificado TLS |
--jsonl FILE | check, exploit | Anexar um objeto JSON por execução |
--vuln-list FILE | check | Gravar URLs com versão ≤ 10.8.0 |
-q, --quiet | todos | Menos saída no console |
--no-color | todos | Terminal simples |
Códigos de saída
| Código | Quando |
|---|---|
| 0 | Exploit: success: true; forge: sempre; check: sempre (-t único) |
| 1 | Exploit: falha na verificação de login/admin |
| 2 | Execução de lista de check sem semântica de -t (informativo) |
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
Sondagens:
/wp-content/plugins/woocommerce-abandon-cart-pro/readme.txtwoocommerce-abandoned-cart-pro