MENU

WebScocket简析

2021 年 07 月 15 日 • 阅读: 70 • 阅读设置

WebScocket简析

前几天渗透某个站的时候发现这个站用burp抓包会成乱码,我以为是我的burp出现了问题,仔细研究后发现这个站用了WebSocket协议,与HTTP协议既有联系又有区别。经过学习,WebSocket协议会不会成为下一个流行的安全协议呢?

注意:以下内容整理于RFC6455文档,感谢HJava的翻译

What is WebSocket?

WebSocket是一种基于TCP协议,复用HTTP协议的全双工的网络通信技术,具体的RFC定义请阅读RFC6455文档。通过将HTTP协议升级到WebSocket协议后,WebSocket相比较HTTP协议的优点有:支持了实时双向通信、更小的控制开销、支持扩展、支持文本和二进制数据、无同源限制。

How to handshake?

因为WebSocket复用了HTTP协议,所以WebSocket也是通过HTTP协议实现握手的,实现方式为协商协议升级,协议升级成功后,所有数据通过WebSocket协议传输。

Request

客户端通过浏览器对WebSocket服务端发起HTTP请求,客户端通过该HTTP请求与服务端协商升级到WebSocket协议。下面的请求包是一个真实环境下的HTTP升级到WebSocket的协商请求头,首先强调一点,HTTP升级到WebSocket必须使用GET请求。相信任何人都能发现该HTTP请求相比较其他HTTP请求多出了Sec-WebSocket-VersionSec-WebSocket-KeyUpgradeSec-WebSocket-Extensions请求头字段,我们只需要关注前3种请求头字段即可,第四种请求头字段为扩展。下表详细解释了HTTP升级到WebSocket协议需要的请求头字段含义:

请求头字段含义
Connection:Upgrade表示该HTTP请求为协议升级请求
Upgrade:websocket表示HTTP协议升级到WebSocket协议
Sec-WebSocket-Version: 13表示WebSocket协议版本
Sec-WebSocket-Key: 1mJ7j65K03/x4qTLgm1Sjw==客户端生成一个16字节的base64编码的随机数
GET / HTTP/1.1
Host: xxx.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: http://xxx.com
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: 1mJ7j65K03/x4qTLgm1Sjw==
Connection: keep-alive, Upgrade
Cookie: 123
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

Response

服务端在接收到HTTP升级WebSocket请求后会返回状态码为101表示协议升级成功,下面的响应包是一个真实环境下的HTTP升级到WebSocket的协商响应包,其中包含了UpgradeSec-WebSocket-Accept两个关键响应头字段,其中Sec-WebSocket-Accept是根据客户端的请求头中的Sec-WebSocket-Key计算而来。

计算的方式是,将请求头中的Sec-WebSocket-Key与服务端已配置好的密钥拼接做SHA1摘要,转换成base64。其中服务端配置的密钥形似258EAFA5-E914-47DA-95CA-C5AB0DC85B11

HTTP/1.1 101 Switching Protocols
Server: nginx
Date: Tue, 13 Jul 2021 06:47:37 GMT
Connection: upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 3xuGoaKWflZ2lv2NNpvTTUqsYjg=

基础帧协议

下图是WebScoket数据帧的基础格式

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 80 1
+-+-+-+-+-------+-+----------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended paylolength    |
|I|S|S|S|  (4)  |A|     (7)     |             (64)           |
|N|V|V|V|       |S|             |   (if payload len==1127)   |
| |1|2|3|       |K|          |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - -- +
|     Extended payload length continued, if payload len 127  |
+ - - - - - - - - - - - - - -+-------------------------------+
|                               |Masking-key, if MASK set 1  |
+----------------------------+-------------------------------+
| Masking-key (continued)       |          PayloData         |
+-------------------------------- - - - - - - - - - - - - -- +
:                     Payload Data continued.                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
|                     Payload Data continued.                |
+------------------------------------------------------------+

详细解释如下:

大小 含义
FIN 1bit 表示这是消息的最后一个片段。
RSV1、RSV2、RSV3 各1bit 必须设置为0,除非扩展了非0值含义的扩展。如果收到了一个非0值且没有扩展的含义,服务端必须断开WebSocket
opcode 4bit 定义“有效负载数据”的解释。如果收到一个位置的操作码,服务端必须断开WebSocket连接。如下的值是定义过的:
•%x0:表示一个延续帧,当opcode为0时,表示本次数据传输采用了数据分片,当前收到的数据帧为其中一个数据分片。
•%x1:表示这是一个文本帧
•%x2:表示这是一个二进制帧
•%x3-7:保留的操作代码,用于后续定义的非控制帧。
•%x8:表示连接断开。
•%x9:表示这是一个ping操作。
•%xA:表示这是一个pong操作。
•%xB-F:保留的操作代码,用于后续定义的控制帧
MASK 1bit 表示是否要对数据载荷进行掩码操作。从客户端向服务端发送数据时,需要对数据进行掩码操作;从服务端向客户端发送数据时,不需要对数据进行掩码操作。
payload length 不固定 数据载荷的长度,单位是字节。为7位,或者7+16位,或者1+64位。
masking-key 0-4bit 所有从客户端传送到服务端的数据帧,数据载荷都进行了掩码操作,Mask为1,且携带了4字节的Masking-key。如果Mask为0,则没有Masking-key。
payload data 扩展数据+应用数据 扩展数据:如果没有协商使用扩展的话,扩展数据数据为0字节。所有的扩展都必须声明扩展数据的长度,或者可以如何计算出扩展数据的长度。此外,扩展如何使用必须在握手阶段就协商好。如果扩展数据存在,那么载荷数据长度必须将扩展数据的长度包含在内。
应用数据:任意的应用数据,在扩展数据之后(如果存在扩展数据),占据了数据帧剩余的位置。载荷数据长度 减去 扩展数据长度,就得到应用数据的长度。
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码