WebSocket Security

๐Ÿ” Introduction

WebSocket์€ ๋น„ ์—ฐ๊ฒฐํ˜• ์š”์ฒญ์ธ HTTP์˜ ๋‹จ์ ์„ ๋ณด์™€ํ•˜์—ฌ ์„œ๋ฒ„์™€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ง„ ํ”„๋กœํ† ์ฝœ๋กœ HTTP ๊ธฐ๋ฐ˜์˜ Handshake ์ดํ›„ TCP/TLS๋ฅผ ํ†ตํ•ด ํ†ต์‹ ํ•˜๋ฉฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋น„์Šทํ•œ ๊ธฐ๋Šฅ์œผ๋กœ SSE (Server Sent Event)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. SSE์˜ ๊ฒฝ์šฐ ์ผ๋ฐฉํ–ฅ ํ†ต์‹ ์„ ์œ„ํ•œ ๊ธฐ์ˆ ์ด๊ณ , WebSocket์€ ์–‘๋ฐฉํ–ฅ ํ†ต์‹ ์„ ์œ„ํ•œ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค.

Handshake and Data transfer

WebSocket์˜ ํ†ต์‹  ๊ณผ์ •์€ Handshake ์™€ Data transfer๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Handshake

WebSocket์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์›น ์œ„์—์„œ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— HTTP ํ”„๋กœํ† ์ฝœ์„ ํ†ตํ•ด Handshake ๊ณผ์ •์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์›น ์„œ๋ฒ„๋กœ Upgrade Request๋ฅผ ์ „์†กํ•˜๊ฒŒ ๋˜๋ฉด, ์„œ๋ฒ„๋Š” ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ HTTP Response๋กœ ์ƒํƒœ๊ฐ’์„ ์ „๋‹ฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

  • 101 Switching Protocols
  • 400 Bad Request
  • 415 Unsupported Media Type
  • ๋“ฑ

์„ฑ๊ณต ์‹œ 101 Switching Protocols์„ ๋ฆฌํ„ดํ•˜๋ฉด์„œ upgrade ํ—ค๋”์— websocket์œผ๋กœ ๋ช…์‹œํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ WebSocket Connection์„ ์—ฐ๊ฒฐํ•˜์—ฌ Data transfer ๊ณผ์ •์œผ๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.

Data transfer

WebSocket Handshake ์ดํ›„ Data transfer ๊ณผ์ •์€ ์ผ๋ฐ˜ Socket ํ†ต์‹ ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ํŠน์ •ํ•œ ํฌ๋งท ์—†์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†ก/์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Framework๋‚˜ Library์— ๋”ฐ๋ผ ์ถ”๊ฐ€์ ์ธ ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Œ€ํ‘œ์ ์œผ๋กœ Springboot์˜ STOMP ํ”„๋กœํ† ์ฝœ์ด ์žˆ์Šต๋‹ˆ๋‹ค.`

WS:// and WSS://

http:// https:// ์˜ ์ฐจ์ด์  ์ฒ˜๋Ÿผ WebSocket๋„ ws:// wss:// ์™€ ๊ฐ™์ด ๋น„ ์•”ํ˜ธํ™” ์†Œ์ผ“๊ณผ ์•”ํ˜ธํ™” ์†Œ์ผ“์œผ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค. ๋‹น์—ฐํžˆ https:// ์—์„œ๋Š” Mixed contents๋ฅผ ๊ธˆ์ง€ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ws://๋กœ ๊ฐ•์ œ ์—ฐ๊ฒฐ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

Example

if ('WebSocket' in window) {  
    var oSocket = new WebSocket("ws://localhost:80");

    oSocket.onmessage = function (e) { 
        console.log(e.data); 
    };

    oSocket.onopen = function (e) {
        console.log(โ€œopenโ€);
    };

    oSocket.onclose = function (e) {
        console.log(โ€œcloseโ€);
    };

    oSocket.send(โ€œmessageโ€);
    oSocket.close();
}

๐Ÿ—ก Offensive techniques

How to Testing

ZAP

WebSockets ์—์„œ ํ†ต์‹  ๊ณผ์ •์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์กฐ๊ฑด์— ๋งž์ถ”์–ด breakpoint๋ฅผ ๊ฑธ์–ด ๋””๋ฒ„๊น…ํ•˜๊ฑฐ๋‚˜, Open/Resend with Message Editor๋ฅผ ํ†ตํ•ด Manual testing์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋•Œ outgoing, incoming ๋ชจ๋‘ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์œ„์™€ ๊ฐ™์ด ๊ฐ Connection์€ # ์œผ๋กœ ๊ตฌ๋ณ„๋˜๋ฉฐ ํ†ต์‹  ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด outgoing, incoming ๋ชจ๋‘ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๋‚˜ ์„œ๋ฒ„๋กœ ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€๋กœ ZAP์˜ Scripts ๋‚ด WebSocket Passive Rules, WebSocket Sender์— ๋ณด๋ฉด ๋ฏธ๋ฆฌ ์ž‘์„ฑ๋œ ZAP Script๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์›น ์†Œ์ผ“ ํ†ต์‹ ์—์„œ๋„ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์‰ฝ๊ฒŒ ๊ฑธ๋Ÿฌ๋‚ด๊ณ  ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„ ์ด๋ฏธ์ง€๋Š” IDOR๋ฅผ ์‹๋ณ„ํ•˜๋Š” Passive Rules์ธ๋ฐ, ZAP Context์˜ User์— ๋“ฑ๋ก๋œ ๊ณ„์ • ์ด๋ฆ„๊ณผ ๊ทธ์— ๋Œ€ํ•œ Hash ๊ฐ’๋“ค์ด WebSocket ํ†ต์‹  ๊ณผ์ •์—์„œ ๋…ธ์ถœ๋˜๋Š”์ง€ ์ฒดํฌํ•ฉ๋‹ˆ๋‹ค. ๋…ธ์ถœ๋œ๋‹ค๋ฉด ์ด ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜์—ฌ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ…Œ์ŠคํŠธํ•  IDOR์˜ ํฌ์ธํŠธ๊ฐ€ ๋˜๊ฒ ์ฃ  :D

Burpsuite

Proxy > WebSockets history์—์„œ ํ†ต์‹  ๊ณผ์ •์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ZAP๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ Repeater๋กœ ๋ณด๋‚ด์„œ Manual testing์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CLI

wscat์ด๋ž€ ๋„๊ตฌ๋ฅผ ์ด์šฉํ•ด์„œ cli ๊ธฐ๋ฐ˜์œผ๋กœ WebSocket์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์ธ ์—ฐ๊ฒฐ, ์ดํ›„ ๋ฐ์ดํ„ฐ ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

npm install -g wscat

Browser Addon and Web

Chrome, Firefox ๋“ฑ์˜ Browser Addon(Extension)์ด๋‚˜ ์ผ๋ฐ˜ ์›น ํŽ˜์ด์ง€๋กœ๋„ ์‰ฝ๊ฒŒ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” Weasel์ด๋ž€ Firefox Addon์ž…๋‹ˆ๋‹ค.

Testing Method

Injections

WebSocket ์œผ๋กœ ํ†ต์‹ ๋˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋‹ค์‹œ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„์™€์˜ ํ†ต์‹  ๊ณผ์ •์ด๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„ ๋กœ์ง์— ๋”ฐ๋ผ์„œ SQL Injection, OS Command Injection ๋“ฑ ๋‹ค๋ฅธ ์—ฌ๋Ÿฌ๊ฐ€์ง€ Attack๊ณผ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์„œ๋น„์Šค์—์„œ ์‚ฌ์šฉํ•˜๋Š” WebSocket ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ”„๋กœํ† ์ฝœ์„ ํŒŒ์•…ํ•˜๊ณ  Injection ๋“ฑ์— ๋Œ€ํ•œ ๋ณด์•ˆ ํ…Œ์ŠคํŒ…์„ ์ง„ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

SEND:THIS_IS_DATA' OR sleep(5);#

IDOR

WebSocket์€ ๋ณ„๋„์˜ ์ฑ„๋„์ด๊ธฐ ๋•Œ๋ฌธ์— ์ดˆ๊ธฐ ํ•ธ๋“œ์‰์ดํฌ ์ดํ›„ ์›น์„œ๋น„์Šค์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ฟ ํ‚ค๋‚˜ ์„ธ์…˜๋“ฑ์˜ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (์‚ฌ์šฉ ํ•˜๋”๋ผ๋„ Handshake ๊ณผ์ •์—์„œ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค)

๋งŒ์•ฝ WebSocket ํ†ต์‹  ๊ณผ์ •์—์„œ ์‹๋ณ„์ž ์ •๋ณด ๋“ฑ์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ IDOR์— ์ทจ์•ฝํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.

SEND:ID=test1234:CMD=updatePW:value=1234
SEND:ID=admin**:**CMD=updatePW:value=1234

CSWSH

CSWSH(Cross-Site WebSocket Hijacking)์€ WebSocket ์—ฐ๊ฒฐ ์‹œ CORS ์ •์ฑ…์˜ ๋ฏธํก์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” SOP ์šฐํšŒ ์ทจ์•ฝ์ ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด์„œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์˜๋„ํ•˜์ง€ ์•Š๋Š” ์‚ฌ์ดํŠธ์—์„œ WebSocket ์—ฐ๊ฒฐ ๋ฐ ํ†ต์‹ ์ด ์ด๋ฃจ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

Cullinan > CSWSH(Cross-Site WebSocket Hijacking)

WebSocket Connection Smuggling

WebSocket Connection Smuggling์€ WebSocket Handshake์—์„œ ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ TCP/TLS ํ„ฐ๋„์ด ๊ตฌ์„ฑ๋˜๋Š” ์ทจ์•ฝ์ ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด์„œ Reverse Proxy ๋‹จ์˜ ๋ณด์•ˆ์ •์ฑ…์„ ํšŒํ”ผํ•˜๊ฑฐ๋‚˜ ๋‚ด๋ถ€ ์‹œ์Šคํ…œ ๋“ฑ์„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

Cullinan > WebSocket Connection Smuggling

Etc

์ด์™ธ์—๋„ Handshake, Data Transfer ๊ณผ์ •์—์„œ ๋ชจ๋“  ์›น ๊ณต๊ฒฉ์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

Protocol over WebSocket

STOMP

STOMP๋Š” Springboot์—์„œ ์‚ฌ์šฉ๋˜๋Š” WebSocket ํ”„๋กœํ† ์ฝœ๋กœ Data transfer ๊ณผ์ •์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค. ํฌ๊ฒŒ ์•„๋ž˜์™€ ๊ฐ™์€ COMMAND๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, Springboot๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์„œ๋น„์Šค์—์„  ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ณ„๋„๋กœ ๊ฒ€์ฆํ•˜์ง€ ์•Š๋Š” ์ด์ƒ COMMAND๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ์ฃผ์š” ํ…Œ์ŠคํŒ… ํฌ์ธํŠธ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

ABORT 
ACK 
BEGIN 
COMMIT 
CONNECT 
CONNECTED 
DISCONNECT 
ERROR 
MESSAGE 
NACK 
RECEIPT 
SEND 
STOMP 
SUBSCRIBE 
UNSUBSCRIBE

๋ณดํ†ต CONNECT > SUBSCRIBE๋ฅผ ํ†ตํ•ด ํ•˜์œ„ Topic(์›น์†Œ์ผ“ ๋‚ด ์ถ”๊ฐ€ ์ฑ„๋„)์„ ๊ตฌ๋…ํ•˜๊ณ , ์ดํ›„์— MESSAGE, SEND ๋“ฑ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๊ฒฐ๋œ ์„œ๋ฒ„์™€ ๊ตฌ์„ฑ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ WebSocket Client์—๊ฒŒ๋„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ›ก Defensive techniques

๊ฐ€์žฅ ๊ธฐ์ดˆ์ ์ธ ๋ฐฉ์–ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ์™ธ๋ถ€๋กœ ๋ถ€ํ„ฐ ์˜ค๋Š” ์š”์ฒญ์„ ๋ชจ๋‘ ์‹ ๋ขฐํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์›น์†Œ์ผ“์€ ์„ค์ •์— ๋”ฐ๋ผ์„œ ์ธ์ฆ๋˜๊ฑฐ๋‚˜, ์ธ์ฆ๋˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž๊ฐ€ ์˜ˆ์ธก ๋ถˆ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ์ธ์ง€ํ•˜๊ณ  ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š” ๋ฒ”์œ„์˜ ์š”์ฒญ์€ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋„๋ก ๋ณดํ˜ธ ๋กœ์ง์„ ๊ตฌ์„ฑํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ•น Tools

  • ZAP - WebSockets
  • Burp - Proxy > WebSockets History
  • wscat
  • WebSocket Weasel
  • https://github.com/hahwul/websocket-connection-smuggler
  • https://github.com/hahwul/websocket-connection-smuggling-go

๐Ÿ“š Articles