Estrenando este nuevo año, 2023 ya, que por cierto, feliz año si aún no os lo he dicho. Llega el momento de volver con las entradas en el blog y el día de hoy os traigo una entrada donde hablaremos de evasión, inyección de código y codificación, una combinación perfecta para nuestras auditorías web. Empezamos…

Antes de nada debemos poner algo de contexto, el código de estado HTTP 302 es indicativo de redirección, por citar como lo describe la documentación de MDN (que os lo dejo en las referencias) diremos que:

…un 302 indica que el recurso solicitado ha sido movido temporalmente a la URL dada por las cabeceras Location.

Y bien, por tanto ya podemos intuir que las cabeceras serán muy determinantes en este laboratorio.

Vamos de lleno al laboratorio que he preparado. El código es sencillo y os lo dejo al final del post.

Empezaremos el análisis revisando el código fuente expuesto a través del navegador:

Ahora llevemos este análisis al BurpSuite para reconocer la petición generada y sobre todo la respuesta del servidor.

Aquí observamos 2 aspectos relevantes: 1, siendo el código de respuesta un HTTP 302, observamos la aparición de la cabecera «Location», que por ahora se mantiene vacía. 2, en el cuerpo de la respuesta se observa una etiqueta HTML incompleta.
Con esto observado, podemos aventurarnos a pensar que será necesario el envío de al menos un parámetro, a continuación haremos algo de fuzzing para identificar el potencial parámetro a enviar.
Para el descubrimiento de parámetros emplearemos la herramienta ffuf, herramienta que funciona bastante ágil y que nos devolverá el siguiente resultado:

ffuf -w /usr/share/wordlists/dirb/common.txt -u http://127.0.0.1:8090/redirect.php?FUZZ=X

Por tanto ahora incluiremos este parámetro descubierto en nuestra petición y enviaremos una petición de prueba al servidor.

La respuesta es bastante reveladora y nos dará explicación sobre nuestras anteriores interrogantes: ¿Qué pasa con la cabecera «Location»? ¿Por qué la etiqueta HTML del body se presenta incompleta? La respuesta para ambos casos es que el valor del parámetro «url» se refleja en la respuesta, esto es bastante interesante.
Por ahora validemos el comportamiento que asume el servidor al insertar una URL válida:

Efectivamente la redirección es confirmada.

Dado este comportamiento, podremos validar la inserción de código, inicialmente vamos a centrarnos en el cuerpo de la respuesta (body):

Se evidencia que el laboratorio es vulnerable, por ahora a HTML injection, pero tenemos un problema que debemos cubrir en estos momento: Dado que nuestra inserción también se traslada al valor de la cabecera «Location», como lo comentamos anteriormente, seremos redirigido a un contenido obviamente inexistente, como se observa a continuación:

Por lo tanto nos centraremos en identificar un caracter que permita alterar el funcionamiento normalizado de la recogida de la cadena para ser depositada en la cabecera HTTP «Location». Para ello emplearemos el Intruder de BurpSuite:

GET /redirect.php?url=§§"><h1>aaa</h1>

Antes de ponerlo en marcha debemos realizar algunas parametrizaciones, como seleccionar que el tipo de payload será «Brute Forcer», la lista de caracteres que se emplearán, la longitud mínima y máxima de la cadena y finalmente optaremos por codificar la inserción en URL encoding.

Lamentablemente esto no nos arroja los resultados esperados.

Después probaremos suerte con algunos caracteres especiales. Aquí también debemos tener en cuenta algunas parametrizaciones previas al ataque:

El resultado se planteaba alentador, pero finalmente nos mantenemos en el mismo sitio.

Profundizando un poco más en la codificación URL, notamos que existen algunos valores que no estamos teniendo en cuenta, para ello nos apoyamos en tablas como la siguiente:

Reflexionando en esto último, nos generaremos el listado de caracteres hexadecimal (que básicamente es lo que queda al excluir el símbolo de porcentaje), lo podemos hacer mediante el uso de bash usando el siguiente bucle for:

for((i=0; i<=255; i++)); do printf "%.2x\n" $i; done

Lo volvemos a poner en marcha con nuestro Intruder y ahora si obtendremos los resultados deseados:

Esto sucede con los caracteres: Null, Line Feed y Carriage Return. Veamos detenidamente el comportamiento del servidor al insertar estos caracteres previo a nuestro payload:

Lo primero de reseñar es que el código de estado de la página de respuesta pasa del HTTP 302 al HTTP 200, lo que quiere decir que la cabecera «Location» desaparece y por tanto ya no seremos redirigidos a ningún otro sitio web.
Luego por tanto, ya podremos centrarnos en el cuerpo de la respuesta (body), que al observarla con el navegador:

Nos evidencia claramente la inyección HTML. Pero vayamos un poco más allá, tiremos de JavaScript para ejecutar un recurrente XSS reflejado:

Desde el navegador observaremos la habitual ventana emergente con el mensaje definido:

Listo. Antes de cerrar el post os dejo el código fuente para que podáis usarlo a vuestra necesidad:

<html>
 <head>
  <title>Infayer Laboratory</title>
 </head>
 <body>
  <?php header("Location: ".$_GET['url']); ?>
  <p>You are being redirected... <a href="<?php echo $_GET['url'];?>"></a></p>
 </body>
</html>

Referencias: