【Python模拟websocket登陆-拆包封包】

news2024/11/17 7:57:22

Python模拟websocket登陆-拆包封包

  • 解析一个网站
  • 获取wss原始数据
  • 拆包wss数据
  • 封包wss数据
  • 发送接收websocket的常驻后台脚本
  • 总结

解析一个网站

这里所用的网站是我一个内测的网站,主要手段是chrome devtools,用得很多,但我玩的不深,这次上了点干货.

  • 首先在网络那一块,找到js或者index.html,右键点击,选择替换内容,在需要分析的地方写上自己的代码。
  • 对于ajax加载的js模块,把js在加载地址,换成离线下载到本地的地址,存入本地的服务,原来是http的,还还用http。原来https的必须也在https,本地web开启跨域允许。然后ajax加载部分js也就替换成可定制的了。
  • 虽然代码很难读,但是在适合的地方,可以随便写cosole.log.
  • 对于js的调试和中断不太懂,还没用,
  • 界面的记录器标签,可以记录一组点击,然后能看到json代码,用于回放。
  • 记录的动作可以用js实现插入在任何位置,只要调试通过就行。

获取wss原始数据

获取数据的两种方式,各种优缺点:

  • 在上一章中,可以看到websocket建立和sendBytes,onMessage之类的函数,在这里启动cosole.log就能得到逐条纪录。不论ws还是wss。这里可以看到语义,并可定制测试代码。
  • 在devtools网络标签下的wss://server:port/url地址,对应的respone可以取得全部的来往数据,和代码块所收发的字节按道理是完全一致的,可以做为一个验证和参考。

拆包wss数据

所谓的拆包是理解数据的意义,我还没有修炼到靠数据读含义的深度,只能靠代码,也就js,顺眼化处理的代码,比如以下的登陆数据代码,从1万行里拽出来的。

  • 消息头4表字节
    u.prototype.addHeader = function(e, t, n, a) {
        return void 0 === n && (n = 0),
        void 0 === a && (a = 0),
        e | t << 4 | n << 12 | a << 23
    

4个参数在长度 e->4bit, t ->,8bit,n->11bit a->9bit.
含义e=command ,t=action, n=length,a=ext

  • 登陆消息的主体
           
        var a = new z.SyncLogonDto;
        a.account = e.account,
        a.sn = e.sn,
        a.token = e.token,
        a.uid = e.userID,
        a.localHost = 0,
        4 == a.sn.length && 0 < a.uid && "" != a.token ? this.sendMsg(a.getBody(), 
        z.ServiceType.HALL_CMD, z.ServiceType.HALL_LOGIN_ACT, 2 =            
          
                      o.prototype.getBody = function() {
        var e = new t.BGByteArray;
        return e.writeUnsignedInt(this.major),
        e.writeUnsignedInt(this.minor),
        e.writeUTFBytes(this.sn),
        e.writeUnsignedInt(this.localHost),
        e.writeLongUint(this.uid),
                  
        var a = new z.SyncLogonDto;
        a.account = e.account,
        a.sn = e.sn,
        a.token = e.token,
        a.uid = e.userID,
        a.localHost = 0,
        4 == a.sn.length && 0 < a.uid && "" != a.token ? this.sendMsg(a.getBody(), 
        z.ServiceType.HALL_CMD, z.ServiceType.HALL_LOGIN_ACT, 2 =            
          
                      o.prototype.getBody = function() {
        var e = new t.BGByteArray;
        return e.writeUnsignedInt(this.major),
        e.writeUnsignedInt(this.minor),
        e.writeUTFBytes(this.sn),
        e.writeUnsignedInt(this.localHost),
        e.writeLongUint(this.uid),
        e.writeFixedLenthString(this.account, 32),
        e.writeFixedLenthString(this.token, 32),
        e
    }
    ,
    a = o,
    t.SyncLogonDto = a
        e.writeFixedLenthString(this.token, 32),
        e
    }
    ,
    a = o,
    t.SyncLogonDto = a

主要的处理逻辑在·o.prototype.getBody = function()
这里的writeUnsigedInt是四字节无符号整数,而且是小头的。就是低位在前,高位在后,相同还有,
writeFixedLenthString(this.account, 32),补充位,也是先写入数据,后填充‘\x00’,在python的bytes使用bytes.ljust(),后面有详细介绍。

这是消息的主体

封包wss数据

根据上面在js可以生成一些python代码用于数据组织

def addHeader(bodyl,command,action=0,ext=0):
    # Data---\x3e command:" + t + " action:" + n + "   size: 4+len(e),ext:a
           
    num=   command | action << 4 | bodyl << 12 | ext << 23
    #num.to_bytes(length=32,byteorder='little')
    return num.to_bytes(length=4,byteorder='little')

def parseHeader(hex4='11c08500'):
   
 #   little_byte = b'\x01\x00\x00\x00\x00\x00\x00\x00'
    hex4=int.from_bytes(bytes.fromhex(hex4),byteorder='little')
    command=hex4 &int('F',16)
    action=hex4>>4 & int('FF',16)
    l=hex4>>12 &  int('7FF',16)  #only 11bit
    ext=hex4>>23 
    print (f'command:{command},action:{action},len:{l},ext:{ext}')
    

def loginbytes(sn,lh,uid,account,token):
    re=bytes()
    re+=int(b'01',16).to_bytes(4,byteorder='little')
    re+=int(b'01',16).to_bytes(4,byteorder='little')
    re+=sn.encode()
    re+=int(lh).to_bytes(4,byteorder='little')
    re+=int(uid).to_bytes(8,byteorder='little')
    re+=account.encode().ljust(32,b'\x00')
    re+=token.encode().ljust(32,b'\x00')
   # print(len(re))
   # print (re.hex())
    return re

解释
addHeader使用按位或,在返回时byteorder='little')这是比较原始数据得出的。
parseHeader用按位与,移位来排除前,与来排除后,只留对照有用的。
这两个函数处理4字节32位的头部信息。
loginbytes 是改写的js中的SyncLogonDto getBody其中account.encode().ljust(32,b'\x00')是对account补足32,int(uid).to_bytes(8,byteorder='little')是将uid转为长整数8字节长,低位在前高位在后的bytes。

发送接收websocket的常驻后台脚本

本段代码,pip install websocket-client, 版本号1.18,websocket协议13

import websocket
import threading
import time
import os
import login
#os.path+=['../']
# 定义当接收到消息时调用的回调函数
def on_message(ws, message):
    print(f"Received message: {message}")
 
# 定义当连接关闭时调用的回调函数
def on_close(ws, close_status_code, close_msg):
    print(f"### Closed ###")
 
# 定义当出现错误时调用的回调函数
def on_error(ws, error):
    print(f"### Error ### {error}")

if __name__ == "__main__":
    # websocket服务地址
    ws_service_address = "ws://your_websocket_server"
    ws_service_address = "wss://alidr-311.klwgt.com/data"

 
    # 创建websocket应用实例
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp(ws_service_address,
                                on_message=on_message,
                                on_close=on_close,
                                on_error=on_error)
 
    # 创建一个线程用于运行websocket客户端
    wst = threading.Thread(target=ws.run_forever)
    wst.daemon = True
    wst.start()
    time.sleep(3)
    mss=login.getlogin()
    ws.send_bytes(mss)
 
    # 主线程做其他事情...
    # 例如,主线程可以发送消息到websocket服务器
    # ws.send("Your message here")
 
    # 主线程在此处等待,否则程序会立即退出
    # 如果你的程序需要在后台运行,则不需要这一行
    wst.join()

其实主要就是来自百度AI的一段代码。稍加调整假入了延时的登陆调用。然后就成功登陆了。实现和浏览器js登陆websocket的一样的效果。

总结

虽然这段代码,没有什么业务功能,细节也是基本的类型转换,但是它是从怀疑中不断产生的。因为我开始时怀疑python在websocket库是否能完全仿真js在websocket。在查看js的建立连接的请求头时,发现协议版本是2011年的13,然后查看了websocket-client在pypi,也是支持到这个版本,只是还没有实现gzip功能的扩展。
既然如此,wss的 建立也没要求cookie和其实token。那就用python跑一下。基于开始处对于网站数据的整理,要是没有原本的js脚本,这也是一个不可能完成的事情了。但是虽然登陆成了,以后的业务逻辑还不知道怎么处理。最少,分步骤,实现批处理,是可以的。这就由python建立 了 一个,js代码的客户端。
好吧纯属有病。
再见

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2242043.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nginx server_name配置错误导致路由upstream超时问题

一、问题描述 某次本平台和外部平台接口调用&#xff0c;同样Nginx location配置&#xff0c;测试环境调用正常&#xff0c;生产环境调用返回失败&#xff1b; 相关链接&#xff1a;Nginx官方文档、server_name、How nginx processes a request 二、排查处理 1&#xff09…

Android Studio 控制台输出的中文显示乱码

1. Android Studio 控制台输出的中文显示乱码 1.1. 问题 安卓在调试阶段&#xff0c;需要查看app运行时的输出信息、出错提示信息。乱码&#xff0c;会极大的阻碍开发者前进的信心&#xff0c;不能及时的根据提示信息定位问题&#xff0c;因此我们需要查看没有乱码的打印信息。…

linux001.在Oracle VM VirtualBox中ubuntu虚拟系统扩容

1.打开终端切换到virtualBox安装目录 2.输入命令扩容 如上终端中的代码解释&#xff1a; D:\Program Files\Oracle\VirtualBox>.\VBoxManage modifyhd D:\ubuntu18.04\Ubuntu18.04\Ubuntu18.04.vdi --resize 40960如上代码说明&#xff1a;D:\Program Files\Oracle\Virtual…

【桌面应用程序】Vue-Electron 环境构建、打包与测试(Windows)

前言 Vue 与 Electron 环境构建、打包与测试。 目录 前言 一、基本环境准备 二、配置npm源 三、创建Vue项目 四、添加Electron支持 五、应用启动 ​六、添加UI框架 ElementUI ​七、打包 一、基本环境准备 npm版本&#xff1a;8.6.0node版本&#xff1a;v18.0.0Vue/…

C#获取视频第一帧_腾讯云媒体处理获取视频第一帧

一、 使用步骤&#xff1a; 第一步、腾讯云开启万象 第二步、安装Tencent.QCloud.Cos.Sdk 包 第三步、修改 腾讯云配置 图片存储目录配置 第四步、执行获取图片并保存 二、封装代码 using System.Text; using System.Threading.Tasks;using COSXML.Model.CI; using COSXML.A…

Jav项目实战II基于微信小程序的助农扶贫的设计与实现(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在当前社会…

ffmpeg+D3D实现的MFC音视频播放器,支持录像、截图、音视频播放、码流信息显示等功能

一、简介 本播放器是在vs2019 x86下开发&#xff0c;通过ffmpeg实现拉流解码功能&#xff0c;通过D3D实现视频的渲染功能。截图功能采用libjpeg实现&#xff0c;可以截取jpg图片&#xff0c;图片的默认保存路径是在C:\MYRecPath中。录像功能采用封装好的类Mp4Record实现&#x…

springboot 之 整合springdoc2.6 (swagger 3)

版本 springboot 3.3.5 jdk 17 springdoc 2.6.0 依赖pom <dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.6.0</version> </dependency>注解对比…

ADS学习笔记 5. 微带天线设计

基于ADS2023 update2 参考书籍&#xff1a;卢益锋老师《ADS射频电路设计与仿真学习笔记》 更多笔记&#xff1a;ADS学习笔记 1. 功率放大器设计ADS学习笔记 2. 低噪声放大器设计ADS学习笔记 3. 功分器设计ADS学习笔记 4. 微带分支定向耦合器设计 目录 0、设计指标 1、微带…

TypeORM在Node.js中的高级应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 TypeORM在Node.js中的高级应用 TypeORM在Node.js中的高级应用 TypeORM在Node.js中的高级应用 引言 TypeORM 基本概念 1. 实体&am…

【软件测试】一个简单的自动化Java程序编写

文章目录 自动化自动化概念回归测试常见面试题 自动化测试金字塔 Web 自动化测试驱动 Selenium一个简单的自动化示例安装 selenium 库使⽤selenium编写代码 自动化 自动化概念 自动的代替人的行为完成操作。自动化在生活中处处可见 生活中的自动化可以减少人力的消耗&#x…

【云岚到家】-day10-2-冷热处理及统计

【云岚到家】-day10-2-冷热处理及统计 3.7 历史订单3.7.1 冷热分离方案1&#xff09;冷热分离需求2&#xff09;分布式数据库3&#xff09;冷热分离方案 3.7.2 订单同步1&#xff09;创建历史订单数据库2&#xff09;订单同步3&#xff09;测试订单同步4&#xff09;小结 3.7.3…

Python学习------第八天

函数 函数的传入参数 掌握函数返回值的作用 掌握函数返回值的定义语法 函数的嵌套调用&#xff1a; 函数的局部变量和全局变量 局部变量的作用&#xff1a;在函数体内部&#xff0c;临时保存数据&#xff0c;即当函数调用完成后&#xff0c;则销毁局部变量。 money 5000000 n…

新人如何做好项目管理?|京东零售技术人成长

“管理是一种实践&#xff0c;其本质不在于知&#xff0c;而在于行”——彼得德鲁克 作为一名初入职场的校招生&#xff0c;你是否有过这样的疑问&#xff1a;项目经理究竟扮演着怎样的角色&#xff1f;是老板的传声筒&#xff0c;单纯地传达上级的指令&#xff1f;还是团队的…

MySQL社区版的启动与连接

1.启动&#xff1a; 注意&#xff1a;MySQL是默认开机自启的 方式一&#xff1a; 1.WinR 的命令行中直接输入services.msc 2.在服务中找到数据库名称&#xff0c;然后鼠标右键点击启动 方式二&#xff1a; 1.在开始选项中搜索“cmd”命令提示符&#xff0c;使用管理员身份运行 …

FFmpeg 4.3 音视频-多路H265监控录放C++开发十四,总结编码过程,从摄像头获得数据后,转成AVFrame,然后再次转成AVPacket,

也就是将摄像头采集到的YUV 的数据换成 AVFrame&#xff0c;然后再次转成 AVPacket&#xff0c;那么这AVPakcet数据要怎么办呢&#xff1f;分为三种情况&#xff1a; 一种是将AVPacket存储成h264文件&#xff0c;由于h264编码器在将avframe变成avpacket的时候就是按照h264的格…

TCP(下):三次握手四次挥手 动态控制

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持! TCP(上)&#xff1a;成熟可靠的传输层协议-CSDN博客 &#x1f95d;在上篇博客中&#xff0c;我们针对TCP的特性,报文结构,连接过程以及相对于其他协议的区别进行了探讨&#xff0c;提供了初步的理解和概览。本…

24 年第十届数维杯国际数模竞赛赛题浅析

本次万众瞩目的数维杯国际大学生数学建模赛题已正式出炉&#xff0c;无论是赛题难度还是认可度&#xff0c;该比赛都是数模届的独一档&#xff0c;含金量极高&#xff0c;可以用于综测加分、保研、简历添彩等各方面。考虑到大家解题实属不易&#xff0c;为了帮助大家取得好成绩…

菲涅耳全息图

菲涅耳全息图&#xff1a;记录介质在物光波场的菲涅耳衍射区(物体到记录介质表面的距离在菲涅耳衍射区内)。 一、点源全息图的记录和再现 1.1 记录 设物光波和参考光波是从点源O(xo, yo, zo)和点源 R(xr, yr, zr)发出的球面波, 波长为λ1, 全息底片位于z0 的平面上, 与两个点源…

Pygame坦克大战游戏开发实验报告

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…