WebSocket 协议爬虫

⚠️前言⚠️

本文仅用于学术交流。

学习探讨逆向知识,欢迎私信共享学习心得。

如有侵权,联系博主删除。

请勿商用,否则后果自负。

网址

aHR0cHM6Ly93d3cubHV4aS5nb3YuY24vY29sL2NvbDQ0NDQvaW5kZXguaHRtbA==
  • 本网站数据均通过webSocket协议传输

一. WebSocket简介 引用 -【K哥】WebSocket 协议爬虫

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,WebSocket 使得客户端和服务器之间的数据交换变得更加简单。
在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

WebSocket 协议简称为 WS 或者 WSS(WebSocket Secure),其发送请求的 URL 以 ws:// 或者 wss:// 开头,WSS 是 WS 的加密版本,
类似于 HTTP 与 HTTPS。

WebSocket 协议的最大特点就是:服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,
属于服务器推送技术的一种。
  • 数据传输对比图

二. 网站分析

1. 先来分析一下 webSocket 链接的构成,主要分析一下这两个字是怎么生成的,其他暂可固定
  • dGg2aCfMMK97Ro270mqBFu5qjC8TQbL2opnHvbEpM: 大概率是由session响应的加密信息解密之后得到
  • FW9uCWqlVzC22m1KfCMCjfvFHpRMsgt: 由session接口返回
  • session 接口
  • session 接口响应内容

三. session 接口 data

1. 参数密文生成逻辑分析
  • 加密位置,ajax断点调试,找到如下位置,h值即为加密data的生成位置

  • 参数T分析如下,其中 cid,tabId需要搞一下,其他可固定

  • 最终调用 this下的 _dynamicEncrypt 生成

2. 参数 T 中 cid 的生成
  • 需要注意的是 cid 其实就是 localStorage 中的 uuid 属性,调试之前清空浏览器缓存,找到值的生成逻辑

  • 最终 cid 其实就是这个 i 值

  • 代码改写一下

    function getCid(){
    return Math"random"'toString''slice'
    }

3. 参数 T 中 tabId 的生成
  • 回到参数 T 组装的位置看一下,发现 tabId 值存在于 对象 o 中
  • 通过堆栈找到 tabId 的生成位置
  • 生成逻辑
  • 至此 参数 T 组装完成
4. 加密方法 _dynamicEncrypt
  • 回到参数 data 的生成位置,我们来看一下这个加密方法
  • 就是这里了
  • 参数1:明文 T 参数
  • 参数2:priKey 加密 Key 固定
  • 参数3:iv 动态生成
  • js文件 ob 混淆 + webpack,根据webpack扣代码思路,缺那个模块补那个模块就可以
  • 7万多行代码758个模块,没有复杂的环境,这里扣代码细节就不多说了
  • 注意 :找对应模块的时候,可以把断点定位在加载器,找起来更方便
5. iv 值
  • 生成位置,就在刚才加密 方法的上方, _dynamicEncrypt 搞定之后,iv 微调一下也就出来了
  • 需要注意的是 session 请求发送时,请求头中有个 Etag 值,其实就是iv值,不对应的话请求会发送失败
6. 结果

四. session 接口响应解密

  • 参数 data 的加密方法 是 _dynamicEncrypt
  • 大胆猜测一下,在对象中可能会存在一个类似名称的解密 方法,这个方法有可能就是用来解密响应内容的
  • 果然,我们直接进方法调试一下看看
  • 参数 t 就是session中返回的密文,iv 和 data 生成时保持一致即可
  • 结果

五. WebSocket

1. 收发信息
  • 直接在network中看收发信息时以乱码的形式展示的

  • 所以我还需要找到js中 websocket 收发位置,看看是怎么加密与解密的

  • 我们可以用webSocket中的一些关键字通过全局检索的方式来定位:

  • 信息发送明文位置

  • 信息发送 位置,信息发送前通过 r.encode() 转化了一下,所以我们在 network 中看到的才是乱码

  • 信息接收 位置,最终通过 r.decode() 转化成明文

  • 信息接收 位置,日志断点

  • 收发日志信息

六. 模拟 webSocket 请求

1. nodejs 模拟简易代码
// 客户端
const WebSocket = require('ws');

const options = {
    headers: {
        "Sec-WebSocket-Version": "13",
        "Upgrade": "websocket",
        'Sec-WebSocket-Key': '5ZH2HCR7sxXbypI96Bixqg==',
        'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits'
    }
};

const socket = new WebSocket('wss链接', [], options);

// 当连接建立时触发
socket.onopen = () => {
    console.log('Connected to server');
    // 在此处添加发送消息的逻辑
   ...
   // 模拟心跳
    setInterval(() => {
        console.log('send ' + JSON.stringify([-1,["","",32,62,!1]]))
        socket.send(window.r.encode([-1,["","",32,62,!1]])); // 发送心跳消息以保持连接活跃
    }, 3000); // 每3秒发送一次心跳消息
};

// 当接收到服务器发送的消息时触发
socket.onmessage = (event) => {
    console.log(`Received: ${window.r.decode(event.data)}`);
};

// 当连接关闭时触发
socket.onclose = () => {
    console.log('Connection closed');
};
2. webSocket特殊 headers 字段说明
  • Upgrade: websocket:表明这是 WebSocket 类型请求;
  • Sec-WebSocket-Version:告诉服务器所使用的 Websocket Draft(协议版本),必须是 13;
  • Sec-WebSocket-Extensions:协议扩展,某类协议可能支持多个扩展,通过它可以实现协议增强;
  • Sec-WebSocket-Key:是 WebSocket 客户端发送的一个 base64 编码的密文,是浏览器随机生成的,要求服务端必须返回一个对应加密的 - Sec-WebSocket-Accept 应答,否则客户端会抛出 Error during WebSocket handshake 错误,并关闭连接。
3. 模拟心跳保持链接活跃,每 3s 一次,上述代码使用定时器实现
4. 模拟链接服务器
  • 这里不再过多展示了,需要获取特定数据的,可以根据日志模拟信息发送接收

没有来的及模拟真实数据接收那一块,来需求了,我要去当牛马了

欢迎私信交流。。。

相关推荐
邪恶的贝利亚1 小时前
神经网络之词嵌入模型(基于torch api调用)
python·nlp
L Jiawen2 小时前
【Python · Pytorch】Conda介绍 & DGL-cuda安装
pytorch·python·conda
Earth explosion4 小时前
Python的pdf2image库将PDF文件转换为PNG图片
python·pdf·pillow
Dxy12393102164 小时前
python把html网页转换成pdf标题没有乱码,正文都乱码
python·pdf·html
vvilkim5 小时前
JavaScript 数据类型和数据结构:从基础到实践
开发语言·前端·javascript
Y编程小白6 小时前
TCP的三握四挥
服务器·网络协议·tcp/ip
码界筑梦坊6 小时前
基于大数据的空气质量数据可视化分析系统
大数据·python·信息可视化·毕业设计
小明在码鱼7 小时前
vue3 + uniapp实现点击拨打电话、点击复制、点击导航的方法
javascript·vue.js·uni-app
bin91537 小时前
DeepSeek 助力 Vue3 开发:打造丝滑的网格布局(Grid Layout)
前端·javascript·vue.js·ecmascript·deepseek
小王不会写code8 小时前
js基础案例
javascript