linuxCuento

Enumeration

Vamos a empezar con un escaneo nmap :

┌──(pylon㉿kali)-[~/…/pylon/THL/Cuento/content]
└─$ nmap -p- --open -sS --min-rate=5000 -n -Pn 192.168.3.129 -vvv
Starting Nmap 7.98 ( https://nmap.org ) at 2025-12-25 12:11 +0100
Nmap wishes you a merry Christmas! Specify -sX for Xmas Scan (https://nmap.org/book/man-port-scanning-techniques.html).
Initiating ARP Ping Scan at 12:11
Scanning 192.168.3.129 [1 port]
Completed ARP Ping Scan at 12:11, 0.03s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 12:11
Scanning 192.168.3.129 [65535 ports]
Discovered open port 22/tcp on 192.168.3.129
Discovered open port 8080/tcp on 192.168.3.129
Completed SYN Stealth Scan at 12:11, 26.34s elapsed (65535 total ports)
Nmap scan report for 192.168.3.129
Host is up, received arp-response (0.00014s latency).
Scanned at 2025-12-25 12:11:13 CET for 26s
Not shown: 65533 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT     STATE SERVICE    REASON
22/tcp   open  ssh        syn-ack ttl 64
8080/tcp open  http-proxy syn-ack ttl 64
MAC Address: 00:0C:29:AE:76:6D (VMware)

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 26.48 seconds
           Raw packets sent: 131090 (5.768MB) | Rcvd: 24 (1.040KB)

Vamos a realizar un segundo escaneo para obtener más detalle de ambos puertos:

Vemos que en el 8080no obtenemos gran información solo que se está empleando un proxy para hacer pública la web.

Vamos a ver la aplicación web:

Vemos que tenemos una zona para poner texto donde Ask a question vamos a poner cualquier cosa:

Vemos que nos responde lo que podría ser un ChatBot. Vamos a ver como se tramita por detrás esto:

Vemos que apunta a un endpoint llamado ask donde le pasa el parámetro query con nuestro input como valor, la respuesta del servidor es el siguiente contenido en JSON:

Vemos que si ponemos otro tipo de input devuelve:

Vemos que se trata de una serie de respuestas ya configuradas, si probamos otro tipo de inputs recibiremos como respuesta la misma respuesta. En este caso el ChatBot esta en mantenimiento y ni disponible para responder otro tipo de preguntas. Así que no podremos jugar con algún Prompt Injection. Vamos a realizar fuzzing para ver si hay algo interesante en la web:

circle-info

En esta parte es un poco rara, ya que el directorio que nos interesa devuelve un 404 y no sale en el fuzzing normal. Cuando lo hagaís vereis muchos endpoints que son del ChatBot.

Podemos ver el endpoint static si accedemos a el veremos lo siguiente:

Shell as raton

Vemos que está devolviendo un error ya que está intentando apuntar a un archivo que no encuentra, vamos a intentar un Path Traversal:

Vemos que funciona, vamos a ver que usuarios existen en el sistema:

Vemos que existen los siguientes usuarios

  • vboxuser

  • raton

  • churrumais

Vamos a intentar leer el id_rsa de todos los usuarios:

vboxuser:

raton:

Podemos leer el id_rsa vamos a darle los respectivos permisos al archivo e intentar acceder por SSH:

Vemos que la id_rsa no esta siendo aceptada y transcurre al método de contraseña... Así que vamos aprovechar el Path Traversal para leer las variables de entorno, para ello apuntaremos a /proc/self/environ que nos permitirá leer las variables de entorno del propietario del proceso.

Comparto un esquema visual de lo que estaría ocurriendo:

La zona vulnerable al LFI es causada por esta parte del código:

path.lstrip('/') lo que hace quitar todas las / en el inicio. Así que si nuestro input que metemos es /etc/passwd esto lo dejará como etc/passwd .

Aquí define directorios permitidos para que la aplicación las considere válidas. APP_ROOT normalmente suele ser la ruta en donde se encuentra alojada el servidor como por ejemplo /var/www/html/ . Luego con os.path.join une la ruta completa alojada la web añadiendo site y wwwroot entonces lo dejaría algo como /var/www/html/site/wwwroot/ . Luego vemos que recoge el valor de la variable de entorno HOME en este caso si el usuario raton es el que está desplegando la aplicación el valor que obtiene es /home/raton/ .

Así que vamos a leer las variables de entorno:

Si vemos las variables podemos encontrar la variable llamada SNOWFLAKE_PASSWORD donde nos da una contraseña que es ratonguaton . Vamos a probarlas para acceder por SSH:

Ya estamos dentro como el usuario raton !!

Si hacemos un ls podremos ver lo siguiente:

Vemos que la aplicación web era NLWeb . Si entramos y leemos el requeriments.txt encontraremos lo siguiente:

Vemos que emplea aiohttp>=3.9.1 con la vulnerabililad de Path Traversal reportada e identificada como CVE-2024-23334arrow-up-right.

Shell as root

Vamos a ver los puertos abiertos en la máquina:

Vemos que está el puerto 5000 abierto, vamos a lanzar un curl para ver que se trata:

Vemos que se trata de un login, vamos a hacer Port Forwarding para llevarnos el puerto a nuestra máquina. Para ello lo haré con SSH:

Ahora vamos a intentar acceder a la aplicación web:

Vamos a probar algunas credenciales predeterminadas como admin:admin :

Vemos que solo puede acceder el usuario churrumais cuyo usuario existente en el sistema desconocemos de sus credenciales. Buscando por el sistema encontré lo siguiente en el /opt/ :

Vemos la aplicación web loganalyzer vamos a leer su código:

Vemos que se trata de una aplicación en Flask. Donde podemos ver lo siguiente definido:

Ya tenemos las credenciales de acceso como churrumais vamos a probarlas:

Vamos a darle a Go to Log Analysis a ver que ocurre:

Vemos que podemos ejecutar algún comando 👀... Vamos a probar id :

No ocurrió nada, vamos a ver que ocurre por atrás:

Vemos que se tramita por POST, ya que tenemos el código fuente vamos a ver que hace con nuestro input:

Vemos que pilla y guarda nuestro input en la variable filter_cmd donde luego lo mete y ejecuta en grep -r '{filter_cmd}' /var/log/analyzer/ 2>/dev/null . Así que viendo donde se guarda nuestro input donde lo mete entre comillas simples podremos cerrarlas añadir un nuevo comando y comentar todo lo demás. Así que el payload podría quedar algo así:

Vamos a ver si se ha creado el archivo y con que usuario:

Lo crea como root , vamos a darle SUID a /bin/bash :

root! ;)