# 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