diff --git a/src/SUMMARY.md b/src/SUMMARY.md index abe382dcf..be4d4275a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -837,9 +837,14 @@ - [WWW2Exec - GOT/PLT](binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md) - [WWW2Exec - \_\_malloc_hook & \_\_free_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md) - [Common Exploiting Problems](binary-exploitation/common-exploiting-problems.md) -- [Linux kernel exploitation - toctou](binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md) - [Windows Exploiting (Basic Guide - OSCP lvl)](binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md) -- [iOS Exploiting](binary-exploitation/ios-exploiting.md) +- [iOS Exploiting](binary-exploitation/ios-exploiting/README.md) + - [ios CVE-2020-27950-mach_msg_trailer_t](binary-exploitation/ios-exploiting/CVE-2020-27950-mach_msg_trailer_t.md) + - [ios CVE-2021-30807-IOMobileFrameBuffer](binary-exploitation/ios-exploiting/CVE-2021-30807-IOMobileFrameBuffer.md) + - [ios Corellium](binary-exploitation/ios-exploiting/ios-corellium.md) + - [ios Heap Exploitation](binary-exploitation/ios-exploiting/ios-example-heap-exploit.md) + - [ios Physical UAF - IOSurface](binary-exploitation/ios-exploiting/ios-physical-uaf-iosurface.md) + # 🤖 AI - [AI Security](AI/README.md) diff --git a/src/pentesting-web/race-condition.md b/src/pentesting-web/race-condition.md index 40f789608..59202badf 100644 --- a/src/pentesting-web/race-condition.md +++ b/src/pentesting-web/race-condition.md @@ -1,58 +1,58 @@ -# Warunki Wyścigu +# Race Condition {{#include ../banners/hacktricks-training.md}} > [!WARNING] -> Aby uzyskać głębokie zrozumienie tej techniki, sprawdź oryginalny raport w [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine) +> Aby uzyskać dogłębne zrozumienie tej techniki, sprawdź oryginalny raport pod adresem [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine) -## Zwiększanie Ataków na Warunki Wyścigu +## Ulepszanie ataków Race Condition -Główną przeszkodą w wykorzystaniu warunków wyścigu jest zapewnienie, że wiele żądań jest obsługiwanych jednocześnie, z **bardzo małą różnicą w czasie ich przetwarzania—idealnie, mniej niż 1ms**. +Główną przeszkodą w wykorzystaniu race condition jest zapewnienie, że wiele żądań jest obsługiwanych jednocześnie, z **bardzo małą różnicą w czasie ich przetwarzania — najlepiej poniżej 1ms**. -Tutaj znajdziesz kilka technik synchronizacji żądań: +Poniżej znajdziesz kilka technik synchronizacji żądań: -#### Atak HTTP/2 Single-Packet vs. Synchronizacja Ostatniego Bajtu HTTP/1.1 +#### HTTP/2 Single-Packet Attack vs. HTTP/1.1 Last-Byte Synchronization -- **HTTP/2**: Obsługuje wysyłanie dwóch żądań przez jedno połączenie TCP, zmniejszając wpływ jittera sieciowego. Jednak z powodu wariacji po stronie serwera, dwa żądania mogą nie wystarczyć do spójnego wykorzystania warunku wyścigu. -- **HTTP/1.1 'Synchronizacja Ostatniego Bajtu'**: Umożliwia wstępne wysyłanie większości części 20-30 żądań, wstrzymując mały fragment, który jest następnie wysyłany razem, osiągając jednoczesne dotarcie do serwera. +- **HTTP/2**: Pozwala wysyłać dwa żądania przez jedno połączenie TCP, zmniejszając wpływ jittera sieciowego. Jednak ze względu na różnice po stronie serwera, dwa żądania mogą nie wystarczyć do stabilnego wykorzystania race condition. +- **HTTP/1.1 'Last-Byte Sync'**: Umożliwia wstępne wysłanie większości części 20–30 żądań, wstrzymując mały fragment, który następnie jest wysyłany razem, co pozwala na jednoczesne dotarcie do serwera. -**Przygotowanie do Synchronizacji Ostatniego Bajtu** obejmuje: +**Przygotowanie do Last-Byte Sync** obejmuje: -1. Wysłanie nagłówków i danych ciała z wyjątkiem ostatniego bajtu bez kończenia strumienia. -2. Wstrzymanie na 100ms po początkowym wysłaniu. +1. Wysłanie nagłówków i danych body z pominięciem ostatniego bajtu bez zamykania strumienia. +2. Wstrzymanie na 100ms po wysłaniu początkowym. 3. Wyłączenie TCP_NODELAY, aby wykorzystać algorytm Nagle'a do grupowania ostatnich ramek. -4. Pingowanie w celu rozgrzania połączenia. +4. Pingowanie, aby rozgrzać połączenie. -Następne wysłanie wstrzymanych ramek powinno skutkować ich dotarciem w jednej paczce, co można zweryfikować za pomocą Wireshark. Ta metoda nie ma zastosowania do plików statycznych, które zazwyczaj nie są zaangażowane w ataki RC. +Późniejsze wysłanie wstrzymanych ramek powinno spowodować ich dotarcie w jednej paczce, co można zweryfikować przez Wireshark. Metoda ta nie ma zastosowania do plików statycznych, które zwykle nie biorą udziału w atakach RC. -### Dostosowanie do Architektury Serwera +### Dostosowywanie do architektury serwera -Zrozumienie architektury celu jest kluczowe. Serwery front-end mogą różnie kierować żądania, co wpływa na czas. Prewencyjne rozgrzewanie połączeń po stronie serwera, poprzez nieistotne żądania, może znormalizować czas żądań. +Zrozumienie architektury celu jest kluczowe. Serwery front-end mogą kierować żądania w różny sposób, co wpływa na timing. Wstępne rozgrzewanie połączeń po stronie serwera poprzez nieistotne żądania może ujednolicić czasy przetwarzania żądań. -#### Obsługa Blokowania Opartego na Sesji +#### Obsługa blokowania opartego na sesji -Frameworki takie jak handler sesji PHP serializują żądania według sesji, co może zaciemniać luki. Wykorzystanie różnych tokenów sesji dla każdego żądania może obejść ten problem. +Frameworki takie jak PHP's session handler serializują żądania według sesji, co może ukrywać podatności. Użycie różnych tokenów sesji dla każdego żądania może obejść ten problem. -#### Pokonywanie Ograniczeń Częstotliwości lub Zasobów +#### Pokonywanie limitów szybkości lub zasobów -Jeśli rozgrzewanie połączeń jest nieskuteczne, celowe wywołanie opóźnień ograniczeń częstotliwości lub zasobów serwerów WWW poprzez zalewanie ich fałszywymi żądaniami może ułatwić atak single-packet, wywołując opóźnienie po stronie serwera sprzyjające warunkom wyścigu. +Jeśli rozgrzewanie połączeń jest nieskuteczne, wywołanie opóźnień po stronie serwera poprzez zalew fałszywymi żądaniami może ułatwić single-packet attack, wywołując serwerowe opóźnienia sprzyjające race condition. -## Przykłady Ataków +## Przykłady ataków -- **Tubo Intruder - atak HTTP2 single-packet (1 punkt końcowy)**: Możesz wysłać żądanie do **Turbo intruder** (`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`), możesz zmienić w żądaniu wartość, którą chcesz złamać dla **`%s`** jak w `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s` i następnie wybrać **`examples/race-single-packer-attack.py`** z rozwijanej listy: +- **Tubo Intruder - HTTP2 single-packet attack (1 endpoint)**: Możesz wysłać żądanie do **Turbo Intruder** (`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`), możesz zmienić w żądaniu wartość, którą chcesz brute-force'ować dla **`%s`** jak w `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s` a następnie wybrać **`examples/race-single-packer-attack.py`** z rozwijanego menu:
-Jeśli zamierzasz **wysłać różne wartości**, możesz zmodyfikować kod tym, który używa listy słów z schowka: +Jeśli zamierzasz wysyłać różne wartości, możesz zmodyfikować kod tym, który używa wordlisty ze schowka: ```python passwords = wordlists.clipboard for password in passwords: engine.queue(target.req, password, gate='race1') ``` > [!WARNING] -> Jeśli strona internetowa nie obsługuje HTTP2 (tylko HTTP1.1), użyj `Engine.THREADED` lub `Engine.BURP` zamiast `Engine.BURP2`. +> Jeśli serwis WWW nie obsługuje HTTP2 (tylko HTTP1.1), użyj `Engine.THREADED` lub `Engine.BURP` zamiast `Engine.BURP2`. -- **Tubo Intruder - atak pojedynczym pakietem HTTP2 (Kilka punktów końcowych)**: W przypadku, gdy musisz wysłać żądanie do 1 punktu końcowego, a następnie wiele do innych punktów końcowych, aby wywołać RCE, możesz zmienić skrypt `race-single-packet-attack.py` na coś takiego: +- **Tubo Intruder - HTTP2 single-packet attack (Several endpoints)**: W przypadku, gdy musisz wysłać żądanie do 1 endpointu, a następnie kilka do innych endpointów, aby wywołać RCE, możesz zmienić skrypt `race-single-packet-attack.py` na coś takiego: ```python def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, @@ -83,16 +83,16 @@ engine.queue(confirmationReq, gate=currentAttempt) # send all the queued requests for this attempt engine.openGate(currentAttempt) ``` -- Jest również dostępne w **Repeater** za pomocą nowej opcji '**Wyślij grupę równolegle**' w Burp Suite. -- Dla **limit-overrun** możesz po prostu dodać **ten sam żądanie 50 razy** w grupie. -- Dla **connection warming**, możesz **dodać** na **początku** **grupy** kilka **żądań** do nie statycznej części serwera webowego. -- Aby **opóźnić** proces **między** przetwarzaniem **jednego żądania a drugim** w 2 krokach substanu, możesz **dodać dodatkowe żądania między** obydwoma żądaniami. -- Dla **multi-endpoint** RC możesz zacząć wysyłać **żądanie**, które **idzie do ukrytego stanu**, a następnie **50 żądań** tuż po nim, które **wykorzystują ukryty stan**. +- Jest to także dostępne w **Repeater** przez nową opcję '**Send group in parallel**' w Burp Suite. +- Dla **limit-overrun** możesz po prostu dodać do grupy **to samo request 50 razy**. +- Dla **connection warming** możesz **dodać** na **początku** **grupy** kilka **requests** do niestatycznej części serwera WWW. +- Aby **opóźnić** proces **między** przetwarzaniem **jednego requesta i drugiego** w procesie z 2 substates, możesz **dodać dodatkowe requests pomiędzy** tymi żądaniami. +- Dla **multi-endpoint** RC możesz zacząć wysyłać **request**, który **przechodzi do ukrytego stanu**, a następnie **50 requests** zaraz po nim, które **wykorzystują ukryty stan**.
-- **Automatyczny skrypt python**: Celem tego skryptu jest zmiana adresu e-mail użytkownika przy jednoczesnym weryfikowaniu go, aż token weryfikacyjny nowego e-maila dotrze do ostatniego e-maila (to dlatego, że w kodzie widziano RC, gdzie możliwe było modyfikowanie e-maila, ale weryfikacja była wysyłana na stary, ponieważ zmienna wskazująca na e-mail była już wypełniona pierwszym).\ -Gdy słowo "objetivo" zostanie znalezione w otrzymanych e-mailach, wiemy, że otrzymaliśmy token weryfikacyjny zmienionego e-maila i kończymy atak. +- **Automated python script**: Celem tego skryptu jest zmiana adresu email użytkownika przy jednoczesnym ciągłym sprawdzaniu, aż token weryfikacyjny nowego adresu dotrze na ostatni email (to dlatego, że w kodzie występował RC, w którym możliwe było zmodyfikowanie emaila, ale wysłanie weryfikacji na stary adres, ponieważ zmienna wskazująca email była już wypełniona pierwszym adresem).\ +Gdy w odebranych wiadomościach znajduje się słowo "objetivo", wiemy, że otrzymaliśmy token weryfikacyjny zmienionego adresu i kończymy atak. ```python # https://portswigger.net/web-security/race-conditions/lab-race-conditions-limit-overrun # Script from victor to solve a HTB challenge @@ -217,21 +217,21 @@ h2_conn.close_connection() response = requests.get(url, verify=False) ``` -### Poprawa Ataku Pojedynczego Pakietu +### Ulepszanie Single Packet Attack -W oryginalnych badaniach wyjaśniono, że ten atak ma limit 1,500 bajtów. Jednak w [**tym poście**](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/) wyjaśniono, jak możliwe jest rozszerzenie ograniczenia 1,500 bajtów ataku pojedynczego pakietu do **65,535 B ograniczenia okna TCP poprzez użycie fragmentacji na poziomie IP** (dzielenie pojedynczego pakietu na wiele pakietów IP) i wysyłanie ich w różnej kolejności, co pozwala na zapobieżenie ponownemu złożeniu pakietu, aż wszystkie fragmenty dotrą do serwera. Ta technika pozwoliła badaczowi na wysłanie 10,000 żądań w około 166 ms. +W oryginalnym badaniu wyjaśniono, że atak ma ograniczenie do 1,500 bajtów. Jednak w [**this post**](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/) opisano, jak można rozszerzyć ograniczenie 1,500 bajtów single packet attack do **ograniczenia okna TCP 65,535 B poprzez użycie fragmentacji na warstwie IP** (podział pojedynczego pakietu na wiele pakietów IP) i wysyłanie ich w innej kolejności, co zapobiega ponownemu złożeniu pakietu, dopóki wszystkie fragmenty nie dotrą do serwera. Technika ta pozwoliła badaczowi wysłać 10,000 żądań w około 166 ms. -Zauważ, że chociaż ta poprawa sprawia, że atak jest bardziej niezawodny w RC, który wymaga, aby setki/tysiące pakietów dotarły w tym samym czasie, może również mieć pewne ograniczenia programowe. Niektóre popularne serwery HTTP, takie jak Apache, Nginx i Go, mają surowe ustawienie `SETTINGS_MAX_CONCURRENT_STREAMS` na 100, 128 i 250. Jednak inne, takie jak NodeJS i nghttp2, mają to ustawienie nieograniczone.\ -To zasadniczo oznacza, że Apache weźmie pod uwagę tylko 100 połączeń HTTP z jednego połączenia TCP (ograniczając ten atak RC). +Zauważ, że chociaż to ulepszenie sprawia, że atak jest bardziej niezawodny w przypadku RC, które wymaga, aby setki/tysiące pakietów dotarły jednocześnie, może też mieć pewne ograniczenia programowe. Niektóre popularne serwery HTTP, takie jak Apache, Nginx i Go, mają restrykcyjne ustawienie `SETTINGS_MAX_CONCURRENT_STREAMS` na 100, 128 i 250. Jednak inne, takie jak NodeJS i nghttp2, mają je nieograniczone.\ +To zasadniczo oznacza, że Apache będzie brać pod uwagę tylko 100 połączeń HTTP z jednego połączenia TCP (ograniczając ten atak RC). -Możesz znaleźć kilka przykładów używających tej techniki w repozytorium [https://github.com/Ry0taK/first-sequence-sync/tree/main](https://github.com/Ry0taK/first-sequence-sync/tree/main). +Przykłady użycia tej techniki można znaleźć w repo [https://github.com/Ry0taK/first-sequence-sync/tree/main](https://github.com/Ry0taK/first-sequence-sync/tree/main). -## Surowy BF +## Raw BF -Przed wcześniejszymi badaniami używano kilku ładunków, które po prostu próbowały wysłać pakiety tak szybko, jak to możliwe, aby spowodować RC. +Przed wcześniejszymi badaniami używano następujących payloadów, które po prostu próbowały wysyłać pakiety jak najszybciej, aby wywołać RC. -- **Repeater:** Sprawdź przykłady z poprzedniej sekcji. -- **Intruder**: Wyślij **żądanie** do **Intrudera**, ustaw **liczbę wątków** na **30** w **menu Opcje** i wybierz jako ładunek **Null payloads** i wygeneruj **30.** +- **Repeater:** Check the examples from the previous section. +- **Intruder**: Wyślij **request** do **Intruder**, ustaw **number of threads** na **30** w **Options menu**, wybierz jako payload **Null payloads** i wygeneruj **30**. - **Turbo Intruder** ```python def queueRequests(target, wordlists): @@ -279,75 +279,75 @@ print(results) asyncio.run(main()) ``` -## **RC Metodologia** +## **Metodologia RC** ### Limit-overrun / TOCTOU -To najprostszy typ warunków wyścigu, gdzie **luki** pojawiają się w miejscach, które **ograniczają liczbę razy, kiedy możesz wykonać akcję**. Na przykład używanie tego samego kodu rabatowego w sklepie internetowym kilka razy. Bardzo łatwy przykład można znaleźć w [**tym raporcie**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) lub w [**tym błędzie**](https://hackerone.com/reports/759247)**.** +To najprostszy typ race condition, gdzie **vulnerabilities** pojawiają się w miejscach, które **ograniczają liczbę razy, w których możesz wykonać daną akcję**. Na przykład użycie tego samego kodu rabatowego w sklepie internetowym wielokrotnie. Bardzo prosty przykład można znaleźć w [**this report**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) lub w [**this bug**](https://hackerone.com/reports/759247)**.** Istnieje wiele wariantów tego rodzaju ataku, w tym: -- Wykorzystanie karty podarunkowej wiele razy -- Ocena produktu wiele razy -- Wypłacanie lub transferowanie gotówki w nadmiarze ponad saldo konta +- Wykorzystanie karty podarunkowej wielokrotnie +- Ocena produktu wielokrotnie +- Wypłata lub przelanie środków przekraczających saldo konta - Ponowne użycie jednego rozwiązania CAPTCHA -- Ominięcie limitu szybkości anty-brute-force +- Omijanie anti-brute-force rate limit ### **Ukryte podstany** -Wykorzystywanie złożonych warunków wyścigu często polega na wykorzystaniu krótkich okazji do interakcji z ukrytymi lub **niezamierzonymi podstanami maszyny**. Oto jak podejść do tego: +Wykorzystywanie złożonych race condition często polega na wykorzystaniu krótkich okien czasowych do interakcji z ukrytymi lub **niezamierzonymi podstanami maszyny**. Oto jak do tego podejść: 1. **Zidentyfikuj potencjalne ukryte podstany** -- Zacznij od zlokalizowania punktów końcowych, które modyfikują lub interagują z krytycznymi danymi, takimi jak profile użytkowników lub procesy resetowania hasła. Skup się na: -- **Przechowywaniu**: Preferuj punkty końcowe, które manipulują danymi trwałymi po stronie serwera, zamiast tych obsługujących dane po stronie klienta. -- **Akcji**: Szukaj operacji, które zmieniają istniejące dane, które są bardziej prawdopodobne do stworzenia warunków do wykorzystania w porównaniu do tych, które dodają nowe dane. -- **Kluczowaniu**: Udane ataki zazwyczaj obejmują operacje kluczowane na tym samym identyfikatorze, np. nazwa użytkownika lub token resetowania. -2. **Przeprowadź wstępne badania** -- Testuj zidentyfikowane punkty końcowe za pomocą ataków warunków wyścigu, obserwując wszelkie odchylenia od oczekiwanych wyników. Nieoczekiwane odpowiedzi lub zmiany w zachowaniu aplikacji mogą sygnalizować lukę. -3. **Zademonstruj lukę** -- Zawęż atak do minimalnej liczby żądań potrzebnych do wykorzystania luki, często tylko dwóch. Ten krok może wymagać wielu prób lub automatyzacji z powodu precyzyjnego timingu. +- Zacznij od zlokalizowania endpoints, które modyfikują lub wchodzą w interakcję z krytycznymi danymi, takimi jak profile użytkowników lub procesy resetowania hasła. Skup się na: +- **Storage**: Preferuj endpoints, które manipulują trwałymi danymi po stronie serwera zamiast tych, które obsługują dane po stronie klienta. +- **Action**: Szukaj operacji, które zmieniają istniejące dane — mają większe szanse stworzyć warunki podatne na exploit w porównaniu z tymi, które dodają nowe dane. +- **Keying**: Udane ataki zazwyczaj dotyczą operacji kluczowanych tym samym identyfikatorem, np. username lub reset token. +2. **Przeprowadź wstępne sondowanie** +- Testuj zidentyfikowane endpoints pod kątem race condition, obserwując odchylenia od oczekiwanych wyników. Nieoczekiwane odpowiedzi lub zmiany w zachowaniu aplikacji mogą wskazywać na podatność. +3. **Zademonstruj podatność** +- Zredukuj atak do minimalnej liczby żądań potrzebnych do wykorzystania podatności, często są to zaledwie dwa. Ten krok może wymagać wielu prób lub automatyzacji z powodu precyzyjnego timingu. -### Ataki wrażliwe na czas +### Time Sensitive Attacks -Precyzja w timingu żądań może ujawnić luki, szczególnie gdy przewidywalne metody, takie jak znaczniki czasu, są używane do tokenów zabezpieczających. Na przykład generowanie tokenów resetowania hasła na podstawie znaczników czasu może pozwolić na identyczne tokeny dla równoczesnych żądań. +Precyzja w timingu żądań może ujawnić podatności, szczególnie gdy do tokenów bezpieczeństwa używa się przewidywalnych metod jak timestamps. Na przykład generowanie password reset tokenów na podstawie timestamps może skutkować identycznymi tokenami dla równoczesnych żądań. **Aby wykorzystać:** -- Użyj precyzyjnego timingu, jak atak jednego pakietu, aby złożyć równoczesne żądania resetowania hasła. Identyczne tokeny wskazują na lukę. +- Użyj precyzyjnego timingu, np. ataku pojedynczym pakietem, by wysłać równoległe password reset requests. Identyczne tokeny wskazują na podatność. **Przykład:** -- Złóż dwa żądania tokenów resetowania hasła w tym samym czasie i porównaj je. Pasujące tokeny sugerują błąd w generowaniu tokenów. +- Zażądaj jednocześnie dwóch password reset tokens i porównaj je. Pasujące tokeny sugerują błąd w generowaniu tokenów. -**Sprawdź to** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities) **aby to wypróbować.** +**Sprawdź ten** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities) **aby to wypróbować.** -## Przypadki studiów ukrytych podstanów +## Studia przypadków ukrytych podstanów ### Zapłać i dodaj przedmiot -Sprawdź to [**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation), aby zobaczyć, jak **zapłacić** w sklepie i **dodać dodatkowy** przedmiot, za który **nie będziesz musiał płacić**. +Sprawdź ten [**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation) aby zobaczyć, jak **zapłacić** w sklepie i **dodać dodatkowy** przedmiot, za który **nie będziesz musiał zapłacić**. -### Potwierdź inne e-maile +### Potwierdź inne adresy email -Pomysł polega na **zweryfikowaniu adresu e-mail i jednoczesnej zmianie go na inny**, aby sprawdzić, czy platforma weryfikuje nowy zmieniony. +Chodzi o to, by **zweryfikować adres email i jednocześnie zmienić go na inny**, aby sprawdzić, czy platforma weryfikuje nowo zmieniony adres. -### Zmień e-mail na 2 adresy e-mail oparte na ciasteczkach +### Zmień email na 2 adresy email (Cookie based) -Zgodnie z [**tym badaniem**](https://portswigger.net/research/smashing-the-state-machine) Gitlab był podatny na przejęcie w ten sposób, ponieważ mógł **wysłać** **token weryfikacji e-maila jednego e-maila do drugiego e-maila**. +Zgodnie z [**this research**](https://portswigger.net/research/smashing-the-state-machine) Gitlab był podatny na takeover w ten sposób, ponieważ mógł **wysłać** **email verification token jednego adresu email na inny adres email**. -**Sprawdź to** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **aby to wypróbować.** +**Sprawdź ten** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **aby to wypróbować.** ### Ukryte stany bazy danych / Ominięcie potwierdzenia -Jeśli **używane są 2 różne zapisy** do **dodania** **informacji** w **bazie danych**, istnieje mały okres czasu, w którym **tylko pierwsze dane zostały zapisane** w bazie danych. Na przykład, podczas tworzenia użytkownika **nazwa użytkownika** i **hasło** mogą być **zapisane**, a **następnie token** do potwierdzenia nowo utworzonego konta jest zapisywany. Oznacza to, że przez krótki czas **token do potwierdzenia konta jest pusty**. +Jeśli **2 różne zapisy** są używane do **dodania** **informacji** w **database**, istnieje krótki okres, w którym **tylko pierwsze dane zostały zapisane** w database. Na przykład przy tworzeniu użytkownika **username** i **password** mogą zostać najpierw **zapisane**, a dopiero potem zapisany zostaje **token** do potwierdzenia nowo utworzonego konta. Oznacza to, że przez krótki czas **token do potwierdzenia konta jest null**. -Dlatego **rejestrowanie konta i wysyłanie kilku żądań z pustym tokenem** (`token=` lub `token[]=` lub jakakolwiek inna wariacja) w celu natychmiastowego potwierdzenia konta mogłoby pozwolić na **potwierdzenie konta**, nad którym nie masz kontroli nad e-mailem. +W związku z tym **zarejestrowanie konta i wysłanie kilku żądań z pustym tokenem** (`token=` lub `token[]=` lub inną wariacją) w celu natychmiastowego potwierdzenia konta może pozwolić na **potwierdzenie konta**, którego nie kontrolujesz emaila. -**Sprawdź to** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) **aby to wypróbować.** +**Sprawdź ten** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) **aby to wypróbować.** ### Ominięcie 2FA -Poniższy pseudokod jest podatny na warunki wyścigu, ponieważ w bardzo krótkim czasie **2FA nie jest egzekwowane**, podczas gdy sesja jest tworzona: +Poniższy pseudo-code jest podatny na race condition, ponieważ przez bardzo krótki czas **2FA nie jest egzekwowane**, podczas gdy session jest tworzona: ```python session['userid'] = user.userid if user.mfa_enabled: @@ -357,22 +357,23 @@ session['enforce_mfa'] = True ``` ### OAuth2 wieczna persystencja -Istnieje kilka [**dostawców OAUth**](https://en.wikipedia.org/wiki/List_of_OAuth_providers). Te usługi pozwalają na stworzenie aplikacji i uwierzytelnienie użytkowników, których dostawca zarejestrował. Aby to zrobić, **klient** musi **zezwolić twojej aplikacji** na dostęp do niektórych swoich danych w **dostawcy OAUth**.\ -Więc, do tego momentu to tylko zwykłe logowanie za pomocą google/linkedin/github... gdzie pojawia się strona z komunikatem: "_Aplikacja \ chce uzyskać dostęp do twoich informacji, czy chcesz to umożliwić?_" +Istnieje kilka [**OAUth providers**](https://en.wikipedia.org/wiki/List_of_OAuth_providers). Te usługi pozwalają na utworzenie aplikacji i uwierzytelnienie użytkowników zarejestrowanych przez dostawcę. W tym celu **client** will need to **permit your application** to access some of their data inside of the **OAUth provider**.\ +Do tego momentu to zwykłe logowanie przez google/linkedin/github... gdzie pojawia się strona z komunikatem: "_Application \ wants to access you information, do you want to allow it?_" -#### Warunek wyścigu w `authorization_code` +#### Race Condition in `authorization_code` -**Problem** pojawia się, gdy **zaakceptujesz to** i automatycznie wysyła **`authorization_code`** do złośliwej aplikacji. Następnie ta **aplikacja nadużywa Warunku Wyścigu w usłudze OAUth, aby wygenerować więcej niż jeden AT/RT** (_Token Uwierzytelniający/Token Odświeżający_) z **`authorization_code`** dla twojego konta. W zasadzie nadużyje faktu, że zaakceptowałeś aplikację, aby uzyskać dostęp do swoich danych, aby **stworzyć kilka kont**. Następnie, jeśli **przestaniesz zezwalać aplikacji na dostęp do swoich danych, jedna para AT/RT zostanie usunięta, ale pozostałe będą nadal ważne**. +The **problem** appears when you **accept it** and automatically sends an **`authorization_code`** to the malicious application. Then, this **application abuses a Race Condition in the OAUth service provider to generate more that one AT/RT** (_Authentication Token/Refresh Token_) from the **`authorization_code`** for your account. Basically, it will abuse the fact that you have accept the application to access your data to **create several accounts**. Then, if you **stop allowing the application to access your data one pair of AT/RT will be deleted, but the other ones will still be valid**. -#### Warunek wyścigu w `Refresh Token` +#### Race Condition in `Refresh Token` -Gdy **uzyskasz ważny RT**, możesz spróbować **nadużyć go, aby wygenerować kilka AT/RT** i **nawet jeśli użytkownik anuluje uprawnienia** dla złośliwej aplikacji do uzyskania dostępu do jego danych, **kilka RT nadal będzie ważnych.** +Once you have **obtained a valid RT** you could try to **abuse it to generate several AT/RT** and **even if the user cancels the permissions** for the malicious application to access his data, **several RTs will still be valid.** -## **RC w WebSockets** +## **RC in WebSockets** -W [**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC) możesz znaleźć PoC w Javie do wysyłania wiadomości websocket w **równoległych** w celu nadużycia **Warunków Wyścigu również w Web Sockets**. +- In [**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC) you can find a PoC in Java to send websocket messages in **parallel** to abuse **Race Conditions also in Web Sockets**. +- With Burp’s WebSocket Turbo Intruder you can use the **THREADED** engine to spawn multiple WS connections and fire payloads in parallel. Start from the official example and tune `config()` (thread count) for concurrency; this is often more reliable than batching on a single connection when racing server‑side state across WS handlers. See [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py). -## Referencje +## References - [https://hackerone.com/reports/759247](https://hackerone.com/reports/759247) - [https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html](https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html) @@ -380,5 +381,8 @@ W [**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC) - [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine) - [https://portswigger.net/web-security/race-conditions](https://portswigger.net/web-security/race-conditions) - [https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/) +- [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine) +- [WebSocketTurboIntruder – GitHub](https://github.com/d0ge/WebSocketTurboIntruder) +- [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/websocket-attacks.md b/src/pentesting-web/websocket-attacks.md index 5a8daa18f..335a814d0 100644 --- a/src/pentesting-web/websocket-attacks.md +++ b/src/pentesting-web/websocket-attacks.md @@ -1,22 +1,22 @@ -# Ataki WebSocket +# Ataki na WebSockety {{#include ../banners/hacktricks-training.md}} ## Czym są WebSockety -Połączenia WebSocket są nawiązywane poprzez początkowe **HTTP** handshake i są zaprojektowane do bycia **długoterminowymi**, co pozwala na dwukierunkowe przesyłanie wiadomości w dowolnym momencie bez potrzeby systemu transakcyjnego. To sprawia, że WebSockety są szczególnie korzystne dla aplikacji wymagających **niskiej latencji lub komunikacji inicjowanej przez serwer**, takich jak strumienie danych finansowych na żywo. +Połączenia WebSocket są nawiązywane poprzez początkowy **HTTP** handshake i są zaprojektowane jako **długotrwałe**, umożliwiając dwukierunkową komunikację w dowolnym momencie bez potrzeby systemu transakcyjnego. Dzięki temu WebSockety są szczególnie korzystne dla aplikacji wymagających **niskich opóźnień lub komunikacji inicjowanej przez serwer**, takich jak strumienie danych finansowych w czasie rzeczywistym. -### Nawiązywanie Połączeń WebSocket +### Nawiązywanie połączeń WebSocket -Szczegółowe wyjaśnienie nawiązywania połączeń WebSocket można znaleźć [**tutaj**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc). Podsumowując, połączenia WebSocket są zazwyczaj inicjowane za pomocą JavaScript po stronie klienta, jak pokazano poniżej: +A detailed explanation on establishing WebSocket connections can be accessed [**here**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc). In summary, WebSocket connections are usually initiated via client-side JavaScript as shown below: ```javascript var ws = new WebSocket("wss://normal-website.com/ws") ``` -Protokół `wss` oznacza połączenie WebSocket zabezpieczone **TLS**, podczas gdy `ws` wskazuje na **niezabezpieczone** połączenie. +Protokół `wss` oznacza połączenie WebSocket zabezpieczone przy użyciu **TLS**, podczas gdy `ws` wskazuje na połączenie **niezabezpieczone**. -Podczas nawiązywania połączenia wykonywane jest uzgadnianie między przeglądarką a serwerem za pomocą HTTP. Proces uzgadniania polega na tym, że przeglądarka wysyła żądanie, a serwer odpowiada, co ilustrują poniższe przykłady: +Podczas nawiązywania połączenia wykonywany jest handshake między przeglądarką a serwerem przez HTTP. Proces handshake polega na wysłaniu przez przeglądarkę requestu i odpowiedzi serwera, jak pokazano w poniższych przykładach: -Przeglądarka wysyła żądanie uzgadniania: +Przeglądarka wysyła handshake request: ```javascript GET /chat HTTP/1.1 Host: normal-website.com @@ -33,46 +33,46 @@ Connection: Upgrade Upgrade: websocket Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk= ``` -Po nawiązaniu połączenia pozostaje ono otwarte do wymiany wiadomości w obu kierunkach. +Po nawiązaniu połączenie pozostaje otwarte, umożliwiając wymianę wiadomości w obu kierunkach. -**Kluczowe punkty handshake WebSocket:** +**Kluczowe punkty negocjacji WebSocket:** -- Nagłówki `Connection` i `Upgrade` sygnalizują rozpoczęcie handshake WebSocket. -- Nagłówek `Sec-WebSocket-Version` wskazuje pożądaną wersję protokołu WebSocket, zazwyczaj `13`. -- W nagłówku `Sec-WebSocket-Key` wysyłana jest losowa wartość zakodowana w Base64, co zapewnia, że każdy handshake jest unikalny, co pomaga zapobiegać problemom z proxy pamięci podręcznej. Ta wartość nie służy do uwierzytelniania, ale do potwierdzenia, że odpowiedź nie jest generowana przez źle skonfigurowany serwer lub pamięć podręczną. -- Nagłówek `Sec-WebSocket-Accept` w odpowiedzi serwera jest hashem `Sec-WebSocket-Key`, weryfikującym zamiar serwera do otwarcia połączenia WebSocket. +- Nagłówki `Connection` i `Upgrade` sygnalizują rozpoczęcie negocjacji WebSocket. +- Nagłówek `Sec-WebSocket-Version` wskazuje żądaną wersję protokołu WebSocket, zwykle `13`. +- W nagłówku `Sec-WebSocket-Key` wysyłana jest losowa wartość zakodowana w Base64, zapewniając unikalność każdej negocjacji, co pomaga zapobiegać problemom z proxy buforującymi. Ta wartość nie służy do uwierzytelniania, lecz potwierdza, że odpowiedź nie została wygenerowana przez źle skonfigurowany serwer lub cache. +- Nagłówek `Sec-WebSocket-Accept` w odpowiedzi serwera jest hashem wartości `Sec-WebSocket-Key`, potwierdzając intencję serwera otwarcia połączenia WebSocket. -Te funkcje zapewniają, że proces handshake jest bezpieczny i niezawodny, torując drogę do efektywnej komunikacji w czasie rzeczywistym. +Te mechanizmy zapewniają, że proces negocjacji jest bezpieczny i niezawodny, co umożliwia efektywną komunikację w czasie rzeczywistym. ### Konsola Linux -Możesz użyć `websocat`, aby nawiązać surowe połączenie z websocketem. +Możesz użyć `websocat`, aby nawiązać surowe połączenie z WebSocket. ```bash websocat --insecure wss://10.10.10.10:8000 -v ``` -Lub aby utworzyć serwer websocat: +Albo utworzyć serwer websocat: ```bash websocat -s 0.0.0.0:8000 #Listen in port 8000 ``` -### MitM websocket connections +### MitM połączenia websocket -Jeśli odkryjesz, że klienci są połączeni z **HTTP websocket** z twojej bieżącej lokalnej sieci, możesz spróbować ataku [ARP Spoofing Attack](../generic-methodologies-and-resources/pentesting-network/index.html#arp-spoofing), aby przeprowadzić atak MitM między klientem a serwerem.\ -Gdy klient próbuje się połączyć, możesz wtedy użyć: +Jeśli stwierdzisz, że klienci są połączeni z **HTTP websocket** z twojej bieżącej sieci lokalnej możesz spróbować [ARP Spoofing Attack ](../generic-methodologies-and-resources/pentesting-network/index.html#arp-spoofing) aby przeprowadzić atak MitM pomiędzy klientem a serwerem.\ +Gdy klient będzie próbował połączyć się z tobą, możesz wtedy użyć: ```bash websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v ``` ### Websockets enumeration -Możesz użyć **narzędzia** [**https://github.com/PalindromeLabs/STEWS**](https://github.com/PalindromeLabs/STEWS) **do automatycznego odkrywania, identyfikacji i wyszukiwania znanych** **vulnerabilities** w websockets. +Możesz użyć **narzędzia** [**https://github.com/PalindromeLabs/STEWS**](https://github.com/PalindromeLabs/STEWS) **aby odkryć, fingerprint i wyszukać znane** **vulnerabilities** w websockets automatycznie. ### Websocket Debug tools -- **Burp Suite** obsługuje komunikację MitM w websockets w bardzo podobny sposób, jak robi to dla zwykłej komunikacji HTTP. -- Rozszerzenie [**socketsleuth**](https://github.com/snyk/socketsleuth) **Burp Suite** pozwoli Ci lepiej zarządzać komunikacją Websocket w Burp, uzyskując **historię**, ustawiając **reguły przechwytywania**, używając reguł **match and replace**, korzystając z **Intruder** i **AutoRepeater.** -- [**WSSiP**](https://github.com/nccgroup/wssip)**:** Skrót od "**WebSocket/Socket.io Proxy**", to narzędzie, napisane w Node.js, zapewnia interfejs użytkownika do **przechwytywania, przechwytywania, wysyłania niestandardowych** wiadomości i przeglądania wszystkich komunikacji WebSocket i Socket.IO między klientem a serwerem. -- [**wsrepl**](https://github.com/doyensec/wsrepl) to **interaktywny websocket REPL** zaprojektowany specjalnie do testów penetracyjnych. Zapewnia interfejs do obserwowania **przychodzących wiadomości websocket i wysyłania nowych**, z łatwym w użyciu frameworkiem do **automatyzacji** tej komunikacji. -- [**https://websocketking.com/**](https://websocketking.com/) to **strona do komunikacji** z innymi stronami za pomocą **websockets**. -- [**https://hoppscotch.io/realtime/websocket**](https://hoppscotch.io/realtime/websocket) wśród innych typów komunikacji/protokółów, zapewnia **stronę do komunikacji** z innymi stronami za pomocą **websockets.** +- **Burp Suite** obsługuje komunikację websockets z MitM w sposób bardzo podobny do zwykłej komunikacji HTTP. +- The [**socketsleuth**](https://github.com/snyk/socketsleuth) **Burp Suite extension** pozwoli lepiej zarządzać komunikacją Websocket w Burp poprzez dostęp do **history**, ustawianie **interception rules**, używanie reguł **match and replace**, oraz korzystanie z **Intruder** i **AutoRepeater.** +- [**WSSiP**](https://github.com/nccgroup/wssip)**:** Skrót od "**WebSocket/Socket.io Proxy**", to narzędzie napisane w Node.js zapewnia interfejs użytkownika do **capture, intercept, send custom** messages i przeglądania wszystkich komunikacji WebSocket i Socket.IO między klientem a serwerem. +- [**wsrepl**](https://github.com/doyensec/wsrepl) to **interactive websocket REPL** zaprojektowane specjalnie dla penetration testing. Zapewnia interfejs do obserwowania **incoming websocket messages and sending new ones**, z łatwym w użyciu frameworkiem do **automating** tej komunikacji. +- [**https://websocketking.com/**](https://websocketking.com/) to aplikacja webowa do komunikacji z innymi stronami przy użyciu **websockets**. +- [**https://hoppscotch.io/realtime/websocket**](https://hoppscotch.io/realtime/websocket) — oprócz innych typów komunikacji/protokółów, udostępnia narzędzie webowe do komunikacji z innymi stronami przy użyciu **websockets.** ## Decrypting Websocket @@ -81,33 +81,150 @@ Możesz użyć **narzędzia** [**https://github.com/PalindromeLabs/STEWS**](http ## Websocket Lab -W [**Burp-Suite-Extender-Montoya-Course**](https://github.com/federicodotta/Burp-Suite-Extender-Montoya-Course) masz kod do uruchomienia strony używającej websockets, a w [**tym poście**](https://security.humanativaspa.it/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3/) znajdziesz wyjaśnienie. +W [**Burp-Suite-Extender-Montoya-Course**](https://github.com/federicodotta/Burp-Suite-Extender-Montoya-Course) masz kod do uruchomienia aplikacji webowej używającej websockets, a w [**this post**](https://security.humanativaspa.it/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3/) znajdziesz wyjaśnienie. ## Websocket Fuzzing -Rozszerzenie burp [**Backslash Powered Scanner**](https://github.com/PortSwigger/backslash-powered-scanner) teraz pozwala również na fuzzing wiadomości WebSocket. Możesz przeczytać więcej informacji na ten temat [**tutaj**](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner). +Rozszerzenie Burp [**Backslash Powered Scanner**](https://github.com/PortSwigger/backslash-powered-scanner) teraz pozwala fuzzować także wiadomości WebSocket. Więcej informacji możesz przeczytać [**here**](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner). + +### WebSocket Turbo Intruder (Burp extension) + +WebSocket Turbo Intruder od PortSwiggera wprowadza skryptowanie w stylu Turbo Intruder w Pythonie oraz high‑rate fuzzing dla WebSockets. Zainstaluj z BApp Store lub ze źródła. Zawiera dwa komponenty: + +- Turbo Intruder: high‑volume messaging do pojedynczego WS endpointu przy użyciu custom engines. +- HTTP Middleware: udostępnia lokalny endpoint HTTP, który przekazuje ciała jako WS messages przez utrzymywane połączenie, dzięki czemu każdy skaner oparty na HTTP może testować backendy WS. + +Podstawowy wzorzec skryptu do fuzzowania WS endpointu i filtrowania istotnych odpowiedzi: +```python +def queue_websockets(upgrade_request, message): +connection = websocket_connection.create(upgrade_request) +for i in range(10): +connection.queue(message, str(i)) + +def handle_outgoing_message(websocket_message): +results_table.add(websocket_message) + +@MatchRegex(r'{\"user\":\"Hal Pline\"') +def handle_incoming_message(websocket_message): +results_table.add(websocket_message) +``` +Użyj dekoratorów takich jak `@MatchRegex(...)` aby zredukować szum, gdy pojedyncza wiadomość wywołuje wiele odpowiedzi. + +### Bridge WS behind HTTP (HTTP Middleware) + +Obuduj trwałe połączenie WS i przekazuj treści HTTP jako wiadomości WS do automatycznego testowania za pomocą skanerów HTTP: +```python +def create_connection(upgrade_request): +connection = websocket_connection.create(upgrade_request) +return connection + +@MatchRegex(r'{\"user\":\"You\"') +def handle_incoming_message(websocket_message): +results_table.add(websocket_message) +``` +Następnie wyślij HTTP lokalnie; ciało jest przekazywane jako wiadomość WS: +```http +POST /proxy?url=https%3A%2F%2Ftarget/ws HTTP/1.1 +Host: 127.0.0.1:9000 +Content-Length: 16 + +{"message":"hi"} +``` +Umożliwia to sterowanie backendami WS przy jednoczesnym filtrowaniu „interesujących” zdarzeń (np. SQLi errors, auth bypass, command injection behavior). + +### Obsługa Socket.IO (handshake, heartbeats, events) + +Socket.IO dodaje własne ramkowanie nad WS. Wykryjesz to przez obowiązkowy parametr zapytania `EIO` (np. `EIO=4`). Utrzymuj sesję żywą za pomocą Ping (`2`) i Pong (`3`), rozpocznij rozmowę od `"40"`, a następnie emituj zdarzenia takie jak `42["message","hello"]`. + +Przykład Intruder: +```python +import burp.api.montoya.http.message.params.HttpParameter as HttpParameter + +def queue_websockets(upgrade_request, message): +connection = websocket_connection.create( +upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4"))) +connection.queue('40') +connection.queue('42["message","hello"]') + +@Pong("3") +def handle_outgoing_message(websocket_message): +results_table.add(websocket_message) + +@PingPong("2", "3") +def handle_incoming_message(websocket_message): +results_table.add(websocket_message) +``` +Wariant adaptera HTTP: +```python +import burp.api.montoya.http.message.params.HttpParameter as HttpParameter + +def create_connection(upgrade_request): +connection = websocket_connection.create( +upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4"))) +connection.queue('40') +connection.decIn() +return connection + +@Pong("3") +def handle_outgoing_message(websocket_message): +results_table.add(websocket_message) + +@PingPong("2", "3") +def handle_incoming_message(websocket_message): +results_table.add(websocket_message) +``` +### Wykrywanie prototype pollution po stronie serwera przez Socket.IO + +Zgodnie z bezpieczną metodą wykrywania PortSwiggera, spróbuj zanieczyścić wewnętrzne mechanizmy Express, wysyłając payload taki jak: +```json +{"__proto__":{"initialPacket":"Polluted"}} +``` +If greetings or behavior change (e.g., echo includes "Polluted"), prawdopodobnie zanieczyściłeś prototypy po stronie serwera. Wpływ zależy od osiągalnych sinków; skoreluj to z gadgetami w sekcji Node.js o prototype pollution. Zobacz: + +- Check [NodeJS – __proto__ & prototype Pollution](deserialization/nodejs-proto-prototype-pollution/README.md) for sinks/gadgets and chaining ideas. + +### WebSocket race conditions with Turbo Intruder + +Domyślny silnik grupuje wiadomości na jednym połączeniu (świetna przepustowość, słabe dla race’ów). Użyj silnika THREADED, aby wystartować wiele WS connections i wysyłać payloady równolegle, żeby wywołać race’y w logice (double‑spend, token reuse, state desync). Zacznij od przykładowego skryptu i dostosuj concurrency w `config()`. + +- Learn methodology and alternatives in [Race Condition](race-condition.md) (see “RC in WebSockets”). + +### WebSocket DoS: malformed frame “Ping of Death” + +Sporządź WS frames, których header deklaruje ogromny payload length, ale nie wysyłaj body. Niektóre WS serwery ufają tej długości i pre‑alokują buffery; ustawienie jej blisko `Integer.MAX_VALUE` może spowodować Out‑Of‑Memory i zdalny unauth DoS. Zobacz przykładowy skrypt. + +### CLI and debugging + +- Headless fuzzing: `java -jar WebSocketFuzzer-.jar ` +- Enable the WS Logger to capture and correlate messages using internal IDs. +- Use `inc*`/`dec*` helpers on `Connection` to tweak message ID handling in complex adapters. +- Decorators like `@PingPong`/`@Pong` and helpers like `isInteresting()` reduce noise and keep sessions alive. + +### Operational safety + +Fuzzing WS na wysokim natężeniu może otworzyć wiele połączeń i wysyłać tysiące wiadomości na sekundę. Malformed frames i wysokie częstotliwości mogą spowodować realny DoS. Używaj tylko tam, gdzie jest to dozwolone. ## Cross-site WebSocket hijacking (CSWSH) -**Cross-site WebSocket hijacking**, znane również jako **cross-origin WebSocket hijacking**, jest identyfikowane jako specyficzny przypadek **[Cross-Site Request Forgery (CSRF)](csrf-cross-site-request-forgery.md)** wpływający na handshake WebSocket. Ta luka występuje, gdy handshake WebSocket autoryzuje wyłącznie za pomocą **ciasteczek HTTP** bez **tokenów CSRF** lub podobnych środków bezpieczeństwa. +**Cross-site WebSocket hijacking**, also known as **cross-origin WebSocket hijacking**, jest traktowane jako specyficzny przypadek **[Cross-Site Request Forgery (CSRF)](csrf-cross-site-request-forgery.md)** dotyczący handshake’ów WebSocket. Ta luka pojawia się, gdy handshake’y WebSocket uwierzytelniają wyłącznie za pomocą **HTTP cookies** bez **CSRF tokens** lub podobnych środków ochrony. -Napastnicy mogą to wykorzystać, hostując **złośliwą stronę internetową**, która inicjuje połączenie WebSocket między witrynami do podatnej aplikacji. W konsekwencji to połączenie jest traktowane jako część sesji ofiary z aplikacją, wykorzystując brak ochrony CSRF w mechanizmie obsługi sesji. +Atakujący mogą to wykorzystać, hostując złośliwą stronę, która inicjuje cross-site WebSocket connection do podatnej aplikacji. W rezultacie to połączenie jest traktowane jako część sesji ofiary w aplikacji, wykorzystując brak ochrony CSRF w mechanizmie obsługi sesji. -Aby ten atak zadziałał, muszą być spełnione następujące wymagania: +Aby ten atak mógł zadziałać, muszą być spełnione wymagania: -- **autoryzacja websocket musi być oparta na ciasteczkach** -- ciasteczko musi być dostępne z serwera napastnika (zwykle oznacza to **`SameSite=None`**) i nie może być włączona **Firefox Total Cookie Protection** w Firefoxie oraz nie mogą być **blokowane ciasteczka stron trzecich** w Chrome. -- serwer websocket nie może sprawdzać pochodzenia połączenia (lub to musi być możliwe do ominięcia) +- The websocket **authentication must be cookie based** +- The cookie must be accessible from the attackers server (this usually means **`SameSite=None`**) and no **Firefox Total Cookie Protection** enabled in Firefox and no **blocked third-party cookies** in Chrome. +- The websocket server must not check the origin of the connection (or this must be bypasseable) -Również: +Also: -- Jeśli autoryzacja opiera się na lokalnym połączeniu (do localhost lub do lokalnej sieci), atak **będzie możliwy**, ponieważ obecne zabezpieczenia tego nie zabraniają (sprawdź [więcej informacji tutaj](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/)) +- If the authentication is based on a local connection (to localhost or to a local network) the attack **will be possible** as no current protection forbids it (check [more info here](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/)) ### Simple Attack -Zauważ, że podczas **nawiązywania** połączenia **websocket** **ciasteczko** jest **wysyłane** do serwera. **Serwer** może go używać do **powiązania** każdego **konkretnego** **użytkownika** z jego **sesją websocket** na podstawie wysłanego ciasteczka. +Zauważ, że podczas **establishing** a **websocket** connection **cookie** jest **sent** do serwera. **Server** może używać go do **relate** każdego **specific** **user** z jego **websocket** **session based on the sent cookie**. -Jeśli na przykład **serwer websocket** **wysyła z powrotem historię rozmowy** użytkownika, gdy wysyłana jest wiadomość z "**READY"**, to **prosty XSS** nawiązujący połączenie (**ciasteczko** zostanie **wysłane** **automatycznie** w celu autoryzacji użytkownika ofiary) **wysyłając** "**READY**" będzie w stanie **odzyskać** historię **rozmowy**. +Następnie, jeśli na przykład **websocket** **server** **sends back the history of the conversation** użytkownika kiedy zostanie wysłany msg z "**READY**", to proste XSS, które ustanowi połączenie (the **cookie** zostanie **sent** **automatically** aby autoryzować użytkownika‑ofiarę) wysyłające "**READY**" będzie w stanie **retrieve** historię **conversation**. ```html ``` -### Cross Origin + Cookie with a different subdomain +### Cross Origin + Cookie z inną subdomeną -W tym wpisie na blogu [https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/](https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/) atakujący zdołał **wykonać dowolny Javascript w subdomenie** domeny, w której odbywała się komunikacja przez web socket. Ponieważ była to **subdomena**, **ciasteczko** było **wysyłane**, a ponieważ **Websocket nie sprawdzał poprawnie Origin**, możliwe było komunikowanie się z nim i **kradzież tokenów**. +W tym wpisie na blogu [https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/](https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/) atakujący zdołał **wykonać dowolny Javascript w subdomenie** domeny, w której odbywała się komunikacja websocket. Ponieważ była to **subdomena**, **cookie** było **wysyłane**, a ponieważ **Websocket nie sprawdzał poprawnie Origin**, możliwa była komunikacja z nim i **ukraść z niego tokeny**. -### Stealing data from user +### Kradzież danych od użytkownika -Skopiuj aplikację webową, którą chcesz naśladować (na przykład pliki .html) i wewnątrz skryptu, w którym odbywa się komunikacja przez websocket, dodaj ten kod: +Skopiuj aplikację webową, którą chcesz podszyć (np. pliki .html) i w miejscu w skrypcie, gdzie zachodzi komunikacja websocket, dodaj ten kod: ```javascript //This is the script tag to load the websocket hooker ; @@ -148,42 +265,51 @@ xhttp.send() return messageEvent } ``` -Teraz pobierz plik `wsHook.js` z [https://github.com/skepticfx/wshook](https://github.com/skepticfx/wshook) i **zapisz go w folderze z plikami webowymi**.\ -Ekspozycja aplikacji webowej i zmuszenie użytkownika do połączenia się z nią pozwoli ci ukraść wysyłane i odbierane wiadomości za pomocą websocket: +Pobierz teraz plik `wsHook.js` z [https://github.com/skepticfx/wshook](https://github.com/skepticfx/wshook) i **zapisz go w folderze z plikami aplikacji webowej**.\ +Udostępniając aplikację webową i skłaniając użytkownika do połączenia się z nią, będziesz w stanie przechwycić wysyłane i odbierane wiadomości przez websocket: ```javascript sudo python3 -m http.server 80 ``` -### Ochrony CSWSH +### Zabezpieczenia CSWSH -Atak CSWSH opiera się na fakcie, że **użytkownik połączy się z złośliwą stroną**, która **otworzy połączenie websocket** do strony internetowej, na której użytkownik jest już zalogowany i uwierzytelni się jako on, ponieważ żądanie wyśle ciasteczka użytkownika. +Atak CSWSH opiera się na tym, że **użytkownik połączy się ze złośliwą stroną**, która **otworzy websocket connection** do strony, z którą użytkownik jest już połączony, i uwierzytelni się w jego imieniu, ponieważ żądanie prześle cookies użytkownika. -Obecnie bardzo łatwo jest zapobiec temu problemowi: +Obecnie bardzo łatwo zapobiec temu problemowi: -- **Serwer websocket sprawdzający pochodzenie**: Serwer websocket powinien zawsze sprawdzać, skąd użytkownik się łączy, aby zapobiec nieoczekiwanym stronom łączącym się z nim. -- **Token uwierzytelniający**: Zamiast opierać uwierzytelnienie na ciasteczku, połączenie websocket mogłoby być oparte na tokenie generowanym przez serwer dla użytkownika, który jest nieznany atakującemu (jak token anty-CSRF). -- **Atrybut ciasteczka SameSite**: Ciasteczka z wartością `SameSite` jako `Lax` lub `Strict` nie będą wysyłane z zewnętrznej strony atakującego do serwera ofiary, dlatego uwierzytelnienie oparte na ciasteczkach nie będzie skuteczne. Należy zauważyć, że Chrome teraz ustawia wartość **`Lax`** dla ciasteczek bez tego flagi, co czyni to bardziej bezpiecznym domyślnie. Chociaż przez pierwsze 2 minuty po utworzeniu ciasteczka będzie miało wartość **`None`**, co czyni je podatnym w tym ograniczonym okresie czasu (oczekuje się również, że ten środek zostanie w pewnym momencie usunięty). -- **Całkowita ochrona ciasteczek w Firefoxie**: Całkowita ochrona ciasteczek działa poprzez izolowanie ciasteczek do strony, na której zostały utworzone. W zasadzie każda strona ma swoją własną partycję przechowywania ciasteczek, aby zapobiec łączeniu historii przeglądania użytkownika przez osoby trzecie. To sprawia, że **CSWSH jest nieużyteczne**, ponieważ strona atakującego nie będzie miała dostępu do ciasteczek. -- **Blokada ciasteczek stron trzecich w Chrome**: To również może zapobiec wysyłaniu ciasteczka uwierzytelnionego użytkownika do serwera websocket, nawet przy `SameSite=None`. +- **Websocket server checking the origin**: Serwer websocket powinien zawsze sprawdzać, skąd użytkownik się łączy, aby zapobiec łączeniu się nieoczekiwanych stron. +- **Authentication token**: Zamiast opierać uwierzytelnianie na cookie, websocket connection może być oparta na tokenie generowanym przez serwer dla użytkownika, nieznanym atakującemu (np. token anti-CSRF). +- **SameSite Cookie attribute**: Cookies z wartością `SameSite` `Lax` lub `Strict` nie będą wysyłane ze strony zewnętrznego atakującego do serwera ofiary, więc uwierzytelnianie oparte na cookie nie będzie skuteczne. Zauważ, że Chrome domyślnie przypisuje wartość **`Lax`** do cookies, którym nie określono tego flagi, co czyni to bezpieczniejszym domyślnie. Jednak przez pierwsze 2 minuty po utworzeniu cookie będzie miało wartość **`None`**, co czyni je podatnym w tym ograniczonym okresie czasu (oczekuje się też, że środek ten zostanie w pewnym momencie usunięty). +- **Firefox Total Cookie Protection**: Total Cookie Protection działa poprzez izolowanie cookies do strony, na której zostały utworzone. Każda strona ma własną partycję do przechowywania cookies, aby zapobiec łączeniu historii przeglądania użytkownika przez podmioty trzecie. To sprawia, że **CSWSH jest bezużyteczny**, ponieważ strona atakującego nie będzie miała dostępu do cookies. +- **Chrome third-party cookies block**: To również może uniemożliwić wysyłanie cookies uwierzytelnionego użytkownika do websocket server nawet przy `SameSite=None`. -## Warunki wyścigu +## Race Conditions -Warunki wyścigu w WebSocketach to również problem, [sprawdź te informacje, aby dowiedzieć się więcej](race-condition.md#rc-in-websockets). +Race Conditions w WebSockets też występują, [sprawdź te informacje, aby dowiedzieć się więcej](race-condition.md#rc-in-websockets). ## Inne podatności -Ponieważ WebSockety są mechanizmem do **wysyłania danych do strony serwera i klienta**, w zależności od tego, jak serwer i klient obsługują informacje, **WebSockety mogą być używane do wykorzystywania kilku innych podatności, takich jak XSS, SQLi lub jakiekolwiek inne powszechne podatności webowe, wykorzystując dane wejściowe użytkownika z websocketu.** +Ponieważ Web Sockets są mechanizmem do **wysyłania danych po stronie serwera i klienta**, w zależności od tego, jak serwer i klient przetwarzają te informacje, **Web Sockets mogą być użyte do wykorzystania wielu innych podatności, takich jak XSS, SQLi czy inne typowe webowe podatności, wykorzystując dane wejściowe użytkownika przesyłane przez websocket.** -## **Przemyt WebSocketów** +## **WebSocket Smuggling** + +Ta podatność może umożliwić **obejście ograniczeń reverse proxies** przez sprawienie, że będą one wierzyć, iż **nawiązano komunikację websocket** (nawet jeśli to nieprawda). To może pozwolić atakującemu na **dostęp do ukrytych endpointów**. Aby uzyskać więcej informacji sprawdź następującą stronę: -Ta podatność może pozwolić na **obejście ograniczeń reverse proxy**, sprawiając, że uwierzą, że **komunikacja websocket została nawiązana** (nawet jeśli to nieprawda). To może pozwolić atakującemu na **dostęp do ukrytych punktów końcowych**. Aby uzyskać więcej informacji, sprawdź następującą stronę: {{#ref}} h2c-smuggling.md {{#endref}} -## Odniesienia +## References - [https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages](https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages) - [https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/) +- [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine) +- [WebSocket Turbo Intruder – BApp Store](https://portswigger.net/bappstore/ba292c5982ea426c95c9d7325d9a1066) +- [WebSocketTurboIntruder – GitHub](https://github.com/d0ge/WebSocketTurboIntruder) +- [Turbo Intruder background](https://portswigger.net/research/turbo-intruder-embracing-the-billion-request-attack) +- [Server-side prototype pollution – safe detection methods](https://portswigger.net/research/server-side-prototype-pollution#safe-detection-methods-for-manual-testers) +- [WS RaceCondition PoC (Java)](https://github.com/redrays-io/WS_RaceCondition_PoC) +- [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py) +- [PingOfDeathExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/PingOfDeathExample.py) {{#include ../banners/hacktricks-training.md}}