You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解码基于Socket.io的WebSocket负载:Wireshark抓包分析求助

解码Socket.io的WebSocket掩码负载步骤

首先,我们分三步来搞定这个问题:先解码WebSocket的掩码,再处理压缩(你的帧启用了permessage-deflate),最后解析Socket.io的协议格式。

1. 基础:解码WebSocket掩码负载

客户端发送的WebSocket帧会用4字节的掩码密钥对负载进行异或加密,解码规则很直接:

  • 提取掩码密钥:你的帧里是435cfdf7,转成字节数组就是[0x43, 0x5C, 0xFD, 0xF7]
  • 提取掩码后的负载字节:把Wireshark里的2*(\312OJ\005\000转成原始字节(比如\312是八进制,对应十六进制0xCA,\005是0x05,\000是0x00,最终字节数组是b'2*(\xcaOJ\x05\x00')
  • 逐字节异或:对于负载的第i个字节,解码后的字节 = 掩码字节 XOR 掩码密钥的第i%4个字节

你可以用这段Python代码快速完成这一步:

mask_key = bytes.fromhex('435cfdf7')
masked_payload = bytes(b'2*(\xcaOJ\x05\x00')
decoded_compressed = bytearray()
for i, b in enumerate(masked_payload):
    decoded_compressed.append(b ^ mask_key[i % 4])

2. 处理permessage-deflate压缩

注意到你的WebSocket帧里Reserved: 0x4,这表示启用了permessage-deflate扩展(WebSocket的压缩机制),所以第一步解码后的字节是压缩过的,需要解压缩才能得到原始数据。

用zlib库处理就行,注意要设置wbits=-15(因为permessage-deflate的压缩数据不带zlib头):

import zlib
try:
    decoded_uncompressed = zlib.decompress(decoded_compressed, wbits=-15)
    decoded_str = decoded_uncompressed.decode('utf-8')
    print("原始Socket.io数据:", decoded_str)
except Exception as e:
    print("解压缩失败,可能是压缩参数不匹配:", str(e))

3. 解析Socket.io数据包格式

Socket.io在WebSocket之上定义了自己的协议,解码后的字符串格式很清晰:

  • 第一个字符是数据包类型(数字):
    • 0: 连接握手数据(包含sid、pingInterval等)
    • 1: 断开连接
    • 2: 事件(最常见,格式为2["事件名", 参数1, 参数2...])
    • 3: 确认响应
    • 4: 错误信息
    • 5/6: 二进制事件/确认

比如如果解码后得到2["chat message", "Hello Socket.io"],就表示这是一个chat message事件,参数是Hello Socket.io。你可以用JSON解析后面的内容:

import json
if decoded_str.startswith('2'):
    event_data = json.loads(decoded_str[1:])
    print(f"事件名称:{event_data[0]}")
    print(f"事件参数:{event_data[1:]}")

总结

你的情况因为启用了permessage-deflate压缩,所以比普通的WebSocket解码多了一步解压缩。按照上面的步骤,你就能得到客户端发送给Socket.io服务器的原始数据了。

内容的提问来源于stack exchange,提问作者Haoxi Tan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:25:10