hacktricks/pentesting-web/hacking-with-cookies/README.md

20 KiB

Hacking Cookies

Nauka hakowania AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Grupa Try Hard Security

{% embed url="https://discord.gg/tryhardsecurity" %}


Ciasteczka posiadają kilka atrybutów kontrolujących ich zachowanie w przeglądarce użytkownika. Oto przegląd tych atrybutów w bardziej biernym tonie:

Wygasa i Max-Age

Datę wygaśnięcia ciasteczka określa atrybut Expires. Z kolei atrybut Max-age definiuje czas w sekundach do momentu usunięcia ciasteczka. Wybierz Max-age, ponieważ odzwierciedla nowoczesne praktyki.

Domena

Hosty, które otrzymają ciasteczko, są określone przez atrybut Domain. Domyślnie jest ustawiony na host, który wydał ciasteczko, nie obejmując jego subdomen. Jednak gdy atrybut Domain jest jawnie ustawiony, obejmuje również subdomeny. Sprawia to, że określenie atrybutu Domain jest mniej restrykcyjną opcją, przydatną w sytuacjach, gdzie konieczne jest udostępnianie ciasteczek między subdomenami. Na przykład, ustawienie Domain=mozilla.org sprawia, że ciasteczka są dostępne na jego subdomenach, takich jak developer.mozilla.org.

Ścieżka

Konkretna ścieżka URL, która musi być obecna w żądanym URL-u, aby został wysłany nagłówek Cookie, jest wskazana przez atrybut Path. Ten atrybut traktuje znak / jako separator katalogów, umożliwiając dopasowania w podkatalogach.

Zasady kolejności

Gdy dwa ciasteczka mają tę samą nazwę, wybór ciasteczka do wysłania opiera się na:

  • Ciasteczku pasującemu do najdłuższej ścieżki w żądanym URL-u.
  • Najnowszym ciasteczku, jeśli ścieżki są identyczne.

SameSite

  • Atrybut SameSite określa, czy ciasteczka są wysyłane w żądaniach pochodzących z domen zewnętrznych. Oferuje trzy ustawienia:
  • Strict: Ogranicza wysyłanie ciasteczka w żądaniach zewnętrznych.
  • Lax: Pozwala na wysyłanie ciasteczka w żądaniach GET inicjowanych przez strony zewnętrzne.
  • None: Umożliwia wysyłanie ciasteczka z dowolnej domeny zewnętrznej.

Pamiętaj, że podczas konfigurowania ciasteczek zrozumienie tych atrybutów może pomóc w zapewnieniu, że zachowują się zgodnie z oczekiwaniami w różnych scenariuszach.

Typ żądania Przykładowy kod Wysyłane ciasteczka, gdy
Link <a href="..."></a> NotSet*, Lax, None
Prerender <link rel="prerender" href=".."/> NotSet*, Lax, None
Form GET <form method="GET" action="..."> NotSet*, Lax, None
Form POST <form method="POST" action="..."> NotSet*, None
iframe <iframe src="..."></iframe> NotSet*, None
AJAX $.get("...") NotSet*, None
Obraz <img src="..."> NetSet*, None

Tabela z Invicti i nieco zmodyfikowana.
Ciasteczko z atrybutem SameSite pomoże zmniejszyć ataki CSRF, gdy wymagana jest zalogowana sesja.

*Zauważ, że od Chrome 80 (luty 2019) domyślne zachowanie ciasteczka bez atrybutu SameSite będzie luźne (https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/).
Zauważ, że tymczasowo, po zastosowaniu tej zmiany, ciasteczka bez polityki SameSite w Chrome będą traktowane jako None podczas pierwszych 2 minut, a następnie jako Lax dla żądań POST z najwyższego poziomu między witrynami.

Flagi Ciasteczek

HttpOnly

Zapobiega to klientowi dostępu do ciasteczka (na przykład za pomocą Javascript np. document.cookie)

Ominięcia

  • Jeśli strona wysyła ciasteczka jako odpowiedź na żądania (na przykład na stronie PHPinfo), możliwe jest wykorzystanie XSS do wysłania żądania do tej strony i ukradzenia ciasteczek z odpowiedzi (sprawdź przykład w https://hackcommander.github.io/posts/2022/11/12/bypass-httponly-via-php-info-page/.
  • To można ominąć za pomocą żądań HTTP TRACE jako odpowiedź serwera (jeśli ta metoda HTTP jest dostępna) odzwierciedli wysłane ciasteczka. Ta technika nazywa się Śledzenie między witrynami.
  • Ta technika jest unikana przez nowoczesne przeglądarki, które nie zezwalają na wysyłanie żądania TRACE z JS. Jednak znaleziono pewne sposoby obejścia tego w określonym oprogramowaniu, takie jak wysyłanie \r\nTRACE zamiast TRACE do IE6.0 SP2.
  • Innym sposobem jest wykorzystanie podatności zero/dnia przeglądarek.
  • Możliwe jest nadpisanie ciasteczek HttpOnly poprzez przeprowadzenie ataku przepełnienia Cookie Jar:

{% content-ref url="cookie-jar-overflow.md" %} cookie-jar-overflow.md {% endcontent-ref %}

Secure

Żądanie tylko wyśle ciasteczko w żądaniu HTTP, jeśli żądanie jest przesyłane przez bezpieczny kanał (zazwyczaj HTTPS).

Prefiksy Ciasteczek

Ciasteczka z prefiksem __Secure- muszą być ustawione razem z flagą secure na stronach zabezpieczonych protokołem HTTPS.

Dla ciasteczek z prefiksem __Host- muszą być spełnione kilka warunków:

  • Muszą być ustawione z flagą secure.
  • Muszą pochodzić z strony zabezpieczonej protokołem HTTPS.
  • Nie wolno im określać domeny, co uniemożliwia ich przesyłanie do subdomen.
  • Ścieżka dla tych ciasteczek musi być ustawiona na /.

Ważne jest zauważenie, że ciasteczka z prefiksem __Host- nie mogą być wysyłane do naddomen ani subdomen. To ograniczenie pomaga w izolowaniu ciasteczek aplikacji. Dlatego stosowanie prefiksu __Host- dla wszystkich ciasteczek aplikacji można uznać za dobrą praktykę w celu zwiększenia bezpieczeństwa i izolacji.

Nadpisywanie ciasteczek

Więc jedną z ochron przed ciasteczkami z prefiksem __Host- jest zapobieganie ich nadpisywaniu z subdomen. Zapobieganie na przykład atakom Cookie Tossing. W prezentacji Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities (dokument) przedstawiono, że było możliwe ustawienie ciasteczek z prefiksem __HOST- z subdomeny, oszukując parser, na przykład dodając "=" na początku lub na początku i na końcu...:

W PHP było również możliwe dodanie innych znaków na początku nazwy ciasteczka, które miały zostać zamienione na podkreślenia, umożliwiając nadpisanie ciasteczek __HOST-:

Ataki na Ciasteczka

Jeśli niestandardowe ciasteczko zawiera wrażliwe dane, sprawdź je (szczególnie jeśli bierzesz udział w CTF), ponieważ może być podatne na ataki.

Dekodowanie i Manipulowanie Ciasteczkami

Wrażliwe dane osadzone w ciasteczkach powinny zawsze być dokładnie sprawdzane. Ciasteczka zakodowane w Base64 lub podobnych formatach często mogą być zdekodowane. Ta podatność pozwala atakującym zmieniać zawartość ciasteczka i podszywać się pod innych użytkowników, kodując zmodyfikowane dane z powrotem do ciasteczka.

Przechwycenie Sesji

Ten atak polega na kradzieży ciasteczka użytkownika w celu uzyskania nieautoryzowanego dostępu do jego konta w aplikacji. Korzystając z ukradzionego ciasteczka, atakujący może podszywać się pod prawowitego użytkownika.

Ustalanie Sesji

W tym scenariuszu atakujący oszukuje ofiarę, aby użyła określonego ciasteczka do zalogowania się. Jeśli aplikacja nie przypisuje nowego ciasteczka po zalogowaniu, atakujący, posiadając oryginalne ciasteczko, może podszyć się pod ofiarę. Ta technika polega na tym, że ofiara loguje się za pomocą ciasteczka dostarczonego przez atakującego.

Jeśli znalazłeś XSS w subdomenie lub masz kontrolę nad subdomeną, przeczytaj:

{% content-ref url="cookie-tossing.md" %} cookie-tossing.md {% endcontent-ref %}

Darowizna Sesji

Tutaj atakujący przekonuje ofiarę do użycia ciasteczka sesji atakującego. Ofiara, wierząc, że jest zalogowana do swojego konta, nieumyślnie wykonuje czynności w kontekście konta atakującego.

Jeśli znalazłeś XSS w subdomenie lub masz kontrolę nad subdomeną, przeczytaj:

{% content-ref url="cookie-tossing.md" %} cookie-tossing.md {% endcontent-ref %}

JWT Cookies

Kliknij na poprzedni link, aby uzyskać dostęp do strony wyjaśniającej możliwe wady w JWT.

Tokeny JSON Web (JWT) używane w ciasteczkach mogą również zawierać podatności. Aby uzyskać szczegółowe informacje na temat potencjalnych wad i jak je wykorzystać, zaleca się zapoznanie się z podlinkowanym dokumentem dotyczącym hakowania JWT.

Podrobienie Żądania Międzywitrynowego (CSRF)

Ten atak zmusza zalogowanego użytkownika do wykonania niechcianych działań w aplikacji internetowej, w której aktualnie jest uwierzytelniony. Atakujący mogą wykorzystać ciasteczka, które są automatycznie wysyłane z każdym żądaniem do podatnej strony.

Puste Ciasteczka

(Sprawdź dalsze szczegóły w oryginalnym badaniu) Przeglądarki pozwalają na tworzenie ciasteczek bez nazwy, co można zademonstrować za pomocą JavaScriptu, jak pokazano poniżej:

document.cookie = "a=v1"
document.cookie = "=test value;" // Setting an empty named cookie
document.cookie = "b=v2"

Wynikiem w nagłówku cookie wysłanym jest a=v1; test value; b=v2;. Co ciekawe, umożliwia to manipulowanie ciasteczkami, jeśli ustawiono puste ciasteczko o nazwie, potencjalnie kontrolując inne ciasteczka poprzez ustawienie pustego ciasteczka na określoną wartość:

function setCookie(name, value) {
document.cookie = `${name}=${value}`;
}

setCookie("", "a=b"); // Setting the empty cookie modifies another cookie's value

To prowadzi do przeglądarki wysyłającej nagłówek cookie interpretowany przez każdy serwer WWW jako cookie o nazwie a o wartości b.

Błąd w Chrome: Problem z kodem zastępczym Unicode

W Chrome, jeśli kod zastępczy Unicode jest częścią ustawionego ciasteczka, document.cookie zostaje uszkodzone, zwracając później pusty ciąg znaków:

document.cookie = "\ud800=meep";

To prowadzi do wyniku document.cookie wypisującego pusty ciąg znaków, co wskazuje na trwałe uszkodzenie.

Przemyt ciasteczek z powodu problemów z parsowaniem

(Sprawdź szczegóły w oryginalnym badaniu) Kilka serwerów internetowych, w tym te oparte na Java (Jetty, TomCat, Undertow) i Pythonie (Zope, cherrypy, web.py, aiohttp, bottle, webob), błędnie obsługuje ciasteczka ze względu na przestarzałe wsparcie dla RFC2965. Odczytują wartość ciasteczka w podwójnych cudzysłowach jako pojedynczą wartość, nawet jeśli zawiera średniki, które normalnie powinny oddzielać pary klucz-wartość:

RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";

Wrażliwość na Wstrzykiwanie Ciasteczek

(Sprawdź dalsze szczegóły w oryginalnym badaniu) Nieprawidłowe parsowanie ciasteczek przez serwery, w szczególności Undertow, Zope oraz te korzystające z http.cookie.SimpleCookie i http.cookie.BaseCookie w Pythonie, tworzy możliwości ataków wstrzykiwania ciasteczek. Te serwery niepoprawnie ograniczają początek nowych ciasteczek, pozwalając atakującym na podszywanie się pod ciasteczka:

  • Undertow oczekuje nowego ciasteczka natychmiast po wartości w cudzysłowiu bez średnika.
  • Zope szuka przecinka, aby rozpocząć parsowanie kolejnego ciasteczka.
  • Klasy ciasteczek w Pythonie zaczynają parsowanie od znaku spacji.

Ta wrażliwość jest szczególnie niebezpieczna w aplikacjach internetowych polegających na ochronie przed CSRF opartej na ciasteczkach, ponieważ pozwala atakującym na wstrzykiwanie sfałszowanych ciasteczek z tokenem CSRF, potencjalnie omijając środki bezpieczeństwa. Problem jest pogłębiony przez sposób obsługi przez Python zduplikowanych nazw ciasteczek, gdzie ostatnie wystąpienie zastępuje wcześniejsze. Wzbudza to również obawy dotyczące ciasteczek __Secure- i __Host- w niebezpiecznych kontekstach oraz może prowadzić do pomijania autoryzacji, gdy ciasteczka są przekazywane do serwerów back-endowych podatnych na podszywanie.

Dodatkowe Sprawdzenia Wrażliwych Ciasteczek

Podstawowe sprawdzenia

  • Ciasteczko jest zawsze takie samo podczas logowania.
  • Wyloguj się i spróbuj użyć tego samego ciasteczka.
  • Spróbuj zalogować się na 2 urządzeniach (lub przeglądarkach) na to samo konto, używając tego samego ciasteczka.
  • Sprawdź, czy ciasteczko zawiera jakieś informacje i spróbuj je zmodyfikować.
  • Spróbuj utworzyć kilka kont o prawie takiej samej nazwie użytkownika i sprawdź, czy można zauważyć podobieństwa.
  • Sprawdź opcję "zapamiętaj mnie", jeśli istnieje, aby zobaczyć, jak działa. Jeśli istnieje i może być podatne, zawsze używaj ciasteczka z opcji zapamiętaj mnie bez żadnego innego ciasteczka.
  • Sprawdź, czy poprzednie ciasteczko działa nawet po zmianie hasła.

Zaawansowane ataki na ciasteczka

Jeśli ciasteczko pozostaje takie samo (lub prawie takie samo) po zalogowaniu, oznacza to prawdopodobnie, że ciasteczko jest powiązane z pewnym polem twojego konta (prawdopodobnie z nazwą użytkownika). W takim przypadku możesz:

  • Spróbuj utworzyć wiele kont z bardzo podobnymi nazwami użytkowników i spróbuj odgadnąć, jak działa algorytm.
  • Spróbuj przeprowadzić atak brutalnej siły na nazwę użytkownika. Jeśli ciasteczko służy tylko jako metoda uwierzytelniania dla twojej nazwy użytkownika, możesz utworzyć konto o nazwie użytkownika "Bmin" i przeprowadzić atak brutalnej siły na każdy bit ciasteczka, ponieważ jedno z ciasteczek, które spróbujesz, będzie należeć do "admin".
  • Spróbuj Padding Oracle (możesz odszyfrować zawartość ciasteczka). Użyj padbuster.

Padding Oracle - Przykłady Padbuster

padbuster <URL/path/when/successfully/login/with/cookie> <COOKIE> <PAD[8-16]>
# When cookies and regular Base64
padbuster http://web.com/index.php u7bvLewln6PJPSAbMb5pFfnCHSEd6olf 8 -cookies auth=u7bvLewln6PJPSAbMb5pFfnCHSEd6olf

# If Base64 urlsafe or hex-lowercase or hex-uppercase --encoding parameter is needed, for example:
padBuster http://web.com/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 8 -encoding 2

Padbuster będzie podejmował kilka prób i zapyta, która z nich jest warunkiem błędu (ten, który nie jest prawidłowy).

Następnie rozpocznie deszyfrowanie ciasteczka (może to potrwać kilka minut).

Jeśli atak zakończył się sukcesem, możesz spróbować zaszyfrować wybrany ciąg znaków. Na przykład, jeśli chciałbyś zaszyfrować user=administrator

padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator

To wykonanie da Ci poprawnie zaszyfrowane i zakodowane ciasteczko z ciągiem user=administrator wewnątrz.

CBC-MAC

Być może ciasteczko mogłoby mieć jakąś wartość i być podpisane za pomocą CBC. Wtedy integralność wartości to podpis utworzony za pomocą CBC z tą samą wartością. Ponieważ zaleca się użycie wektora zerowego jako IV, ten rodzaj sprawdzania integralności może być podatny na atak.

Atak

  1. Uzyskaj podpis nazwy użytkownika administ = t
  2. Uzyskaj podpis nazwy użytkownika rator\x00\x00\x00 XOR t = t'
  3. Ustaw w ciasteczku wartość administrator+t' (t' będzie poprawnym podpisem (rator\x00\x00\x00 XOR t) XOR t = rator\x00\x00\x00

ECB

Jeśli ciasteczko jest szyfrowane za pomocą ECB, może być podatne na atak.
Po zalogowaniu otrzymywane ciasteczko musi być zawsze takie samo.

Jak wykryć i zaatakować:

Utwórz 2 użytkowników z prawie takimi samymi danymi (nazwa użytkownika, hasło, e-mail, itp.) i spróbuj odkryć jakiś wzorzec w danym ciasteczku

Utwórz użytkownika o nazwie na przykład "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" i sprawdź, czy istnieje jakiś wzorzec w ciasteczku (ponieważ ECB szyfruje każdy blok tym samym kluczem, te same zaszyfrowane bajty mogą się pojawić, jeśli nazwa użytkownika jest zaszyfrowana).

Powinien być jakiś wzorzec (o wielkości używanego bloku). Więc, znając sposób zaszyfrowania grupy "a", możesz utworzyć nazwę użytkownika: "a"*(rozmiar bloku)+"admin". Następnie możesz usunąć zaszyfrowany wzorzec bloku "a" z ciasteczka. I będziesz mieć ciasteczko użytkownika "admin".

Referencje

Try Hard Security Group

{% embed url="https://discord.gg/tryhardsecurity" %}

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

Inne sposoby wsparcia HackTricks: