Reflected XSS

Reflected XSS surge cuando una aplicación recibe datos en una solicitud HTTP e incluye esos datos en la respuesta inmediata de forma no segura.

Impacto del ataque de un Reflected XSS

Si un atacante puede controlar un script que se ejecuta en el navegador de la víctima, normalmente puede comprometer completamente a ese usuario:

  • Realizar cualquier acción dentro de la aplicación que el usuario pueda realizar.

  • Ver cualquier información que el usuario pueda ver.

  • Modificar cualquier información que el usuario pueda modificar.

  • Iniciar interacciones con otros usuarios de la aplicación, incluidos ataques maliciosos, que parecerán ser originados desde el usuario víctima.

Existen múltiples métodos para inducir a un usuario a realizar una solicitud que controlamos, como las siguientes:

  • Colocar enlaces en un sitio web controlado por el atacante, o en otro sitio que permita generar contenido.

  • Enviar un enlace en un correo electrónico, tweet u otro mensaje.

La necesidad de un mecanismo de entrega externo para el ataque significa que el impacto del Reflected XSS es generalmente menos severo que el del Stored XSS.

Reflected XSS en contexto HTML sin nada codificado

El siguiente sitio posee un Reflected XSS en la función de búsqueda.

Al ingresar datos en el parámetro de búsqueda, estos son reflejados en el body de la respuesta del sitio:

Al enviar datos, estos son enviados mediante un método GET:

Como se ve a continuación, estos datos son reflejados en el body de la respuesta:

Ahora, validamos si podemos enviar código JavaScript. Se enviará el payload <script>alert(1)</script> encodeado en URL:

Vemos que el payload no es codificado en la respuesta:

Por lo tanto, si lo revisamos en la web, vemos que salta el pop-up con el mensaje que dejamos en el alert() enviado:

Reflected XSS en atributo con angle brackets codificado en HTML

El siguiente sitio posee un Reflected XSS en la función de búsqueda.

Al ingresar datos en el parámetro de búsqueda, estos son reflejados en el body de la respuesta del sitio:

Al enviar datos, estos son enviados mediante un método GET:

Como se ve a continuación, estos datos son reflejados en el body de la respuesta:

Ahora enviamos el payload <script>alert(1)</script>:

En la respuesta, los símbolos <> se encuentran codificados, por lo tanto, no podemos usar una nueva etiqueta HTML:

Como los datos se encuentran en del atributo value del tag input, podemos enviar un payload para que trabaje dentro de este mismo tag. Para este caso, usamos el payload " onmouseover="alert(1):

Con las primeras comillas del payload, cerramos el atributo value, y este dejará el nuevo atributo onmouseover dentro del tag input:

Ahora, si mandamos el payload directamente en la web, y pasamos el mouse sobre la barra de búsqueda, salta el pop-up con el mensaje indicado en el payload:

Relfected XSS en un string JavaScript con angle brackets codificados en HTML

El siguiente sitio posee un Reflected XSS en la función de búsqueda.

Al ingresar datos en el parámetro de búsqueda, estos son reflejados en el body de la respuesta del sitio:

Validamos si podemos ingresar el siguiente payload '</script><script>alert(1)</script>, cerrando el tag script:

Los angle brackets se encuentran codificados en la respuesta:

Usamos el siguiente payload '-alert(1)-', donde, se usan - para concatenar e indicar que se tiene tomar en cuenta el valor de alert():

Vemos que el payload no se codifica en la respuesta:

Al ingresar este payload directamente en la barra de búsqueda, vemos que salta el pop-up con el mensaje dentro de la función alert():

Reflected XSS en contexto HTML con la mayoría de las etiquetas y atributos bloqueados

Como indica el título del lab, se presentan múltiples bloqueos de etiquetas y atributos a nivel de HTML, por este motivo, es necesario identificar cuáles podemos usar.

Usando el intruder de Burp Suite, y el Cheat Sheet de PortSwigger, podemos validar las etiquetas/atributos permitidos.

Lo primero es mandar el request de la búsqueda al Intruder:

En este, seleccionamos donde necesitamos agregar el payload:

Ahora, desde la web de PortSwigger copiamos los tags:

Estos los agregamos a la lista de payloads:

Ya con esto, le damos clic en Start attack, y cuando termine, revisamos las respuestas que tengan mayor largo, que en este caso, es body:

Con este tag, repetimos lo anterior, pero ahora agregando los events del cheat sheet:

Acá podemos filtrar por dos opciones, por el status code o por el largo:

Con esto, validamos ingresando la función alert() dentro del atributo onresize, y vemos que salta el pop-up al momento de ajustar el tamaño de la página:

Para poder enviar este payload a un usuario, podemos usar el siguiente iframe:

<iframe src="https://target.com/?search=%22%3E%3Cbody%20onresize=alert(document.cookie)%3E" onload=this.style.width='100px'>

Reflected XSS en contexto HTML con todas las etiquetas bloqueadas excepto las personalizadas

Como se especifica en el título del lab, los tags normales de HTML no pueden ser usados en este caso, debido que, estos se encuentran filtrados, por este motivo, es que se validará con el envío de un tag personalizado.

En la barra de búsqueda, ingresamos un tag no personalizado, y vemos que tenemos un error 400, indicando que el tag no se encuentra permitido:

Ahora modificamos el tag a uno custom, con atributos que nos permitan inyectar JavaScript <wolf id=x tabindex=1 onfocus=alert(1)>:

Este tag es reflejado de forma correcta en la respuesta, pero al momento de querer hacer saltar el pop-up no salta, así que para generar el alert(), se llama el id con el siguiente string (#x) al final del payload:

Reflected XSS con algunas marcas SVG permitidas

Al inyectar un payload en la opción de búsqueda, vemos que nos da un error 400 especificando que el tag ingresado no se encuentra permitido:

Por este motivo, realizamos fuzzing usando la herramienta Intruder para identificar que tags se encuentran permitidos:

Como payloads, usamos los tags que se encuentran en el Cheat Sheet de XSS de PortSwigger:

Podemos observar que los tags permitidos son: <svg>, <title>, <image> y <animatetransform>:

El tag <animatetransform> es un tag que se puede usar en conjunto con <svg>, el cual, permite usar atributos que ejecutan scripts:

Usando el payload <svg><animatetransform onbegin=alert(1)> podemos explotar el XSS:

Reflected XSS en la etiqueta de enlace canónico

Al revisar el código fuente, apreciamos que se tiene un enlace canónico:

Si al enlace le agregamos algún string, este se ve reflejado en el enlace canónico:

Al agregar el payload ?'onload='alert(1), este se ve reflejado en el enlace, pero no se ejecuta la función alert():

Revisando la información de los research que posee PortSwigger, encontramos que tienen un post donde indican con qué payload podemos explotar los enlaces canónicos, por lo tanto, usando el payload ?'accesskey='x'onclick='alert(1), y la combinación de teclas ALT+SHIFT+X, salta el pop-up con el mensaje de la función alert():

La combinación de teclas en los diferentes OS son:

  • On Windows: ALT+SHIFT+X

  • On MacOS: CTRL+ALT+X

  • On Linux: Alt+X

Reflected XSS en una cadena de JavaScript con comillas simples y backslash escapado

Al ingresar un string en la barra de búsqueda, este se refleja en la variable searchTerms dentro del código JavaScript de la respuesta:

Si a este payload le agregamos una comilla simple ('), este carácter es escapado mediante un backslash (\):

Por este motivo, cerramos la etiqueta script para insertar una nueva con la función alert():

Reflected XSS en una cadena de JavaScript con paréntesis angulares y comillas dobles codificado en HTML y comillas simples escapadas

Validamos como el sitio procesa los caracteres enviados en la barra de búsqueda enviando el siguiente string a'b"c/d\e:f;g-h:

Como se puede apreciar, las ' son escapadas, mientras que, las " son codificadas usando HTML. Por este motivo, se manda un \ para escapar el símbolo de escape, y así poder usar la comilla simple, además, se mandan dos / para generar un comentario al final de nuestro string de JavaScript. El payload enviado es \-alert(1)//:

Reflected XSS en un template literal con escape Unicode en angle brackets, comillas simples, dobles, backslash y backticks

Se ingresan los siguientes caracteres 0`a'b"c/d\e:f;g-h{i}j$k<1>2 para validar como son procesados:

Como no escapa los caracteres $ y {}, podemos usar templates literales enviando el siguiente payload ${alert(1)}:

Last updated