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:

Site

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

Envío de datos

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

Datos reflejados
Datos reflejados

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

Payload codificado

Vemos que el payload no es codificado en la respuesta:

El payload no se codifica 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:

Resultado de la función alert()

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:

Site

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

Datos enviados

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

Datos reflejados
Datos reflejados

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

Payload 01

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

Angle Brackets codificados

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):

Payload 02

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

Payload reflejado

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:

Payload reflejado

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:

Sitio
Datos enviados
Datos reflejados
Datos reflejados

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

Payload 01

Los angle brackets se encuentran codificados en la respuesta:

Datos reflejados

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

Payload 02

Vemos que el payload no se codifica en la respuesta:

Datos reflejados

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():

XSS

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:

Envío a Intruder

En este, seleccionamos donde necesitamos agregar el payload:

Payload Positions

Ahora, desde la web de PortSwigger copiamos los tags:

Cheat Sheet

Estos los agregamos a la lista de payloads:

Payloads a usar

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:

Responses

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

Payload Positions
Payloads a usar

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

Responses

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:

XSS

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:

Status Code 400

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

Tag personalizado

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:

XSS

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:

Sitio Web
Payload de prueba

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

Payload positions

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

Payload settings

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

Tags permitidos

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

Validación de atributos
Atributos permitidos

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

Envío del payload
XSS

Reflected XSS en la etiqueta de enlace canónico

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

Enlace canónico

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

Modificación del 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():

Payload 01

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():

Payload 02
XSS

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:

Sitio web
Datos reflejados

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

Carácter escapado

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

Payload
XSS

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:

Web Site
Caracteres escapados

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)//:

Payload
XSS

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:

Web Site
Caracteres escapados

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

Payload
XSS

Last updated