最近有闲,对之前写的抓包工具进行了一波优化 (具体可点击查看之前的帖子),针对协议收发方式,对 tcp 和 websocket 的收发处理进行了整合,同时也将 socks5 代理方式加了进来,现在抓包工具既可以支持客户端配置方式,又可以支持 socks5 代理方式,既可以支持 tcp,也可以支持 websocket,另外,增加了一些小功能,比如弱网模拟,参数填写的方式生成协议封包等等,前段时间在 A_Jian 的推荐下,也学习了一下 pyecharts,然后把协议分析报表也加到工具中了,简单介绍一下实现思路
由于 tcp 和 websocket 的处理方式之前已经有介绍过,这里就不再赘述了
首先是启动前界面的改动,对比之前增加了 协议类型 和 代理方式 的组件,选择不同的协议类型,会分别调用不同的协议解析方式,选择配置代理方式,会跟之前一样,显示需要连接的指定目标服务器地址,而选择 sock5 的代理方式,服务器信息组件会被隐藏,如下图
sock5 模式下不显示服务器 ip 和端口填写框
sock5 代理方式与原来的处理方式有些不同,它不需要修改客户端的服务器列表配置,而是直接获取请求中的目标 ip 和端口,然后创建连接,但是在此之前,需要先跟客户端进行握手响应,代码如下,这里要感谢大佬 涤 帮忙解惑。
def socks_connect_server(self):
"""
与服务器创建连接,socks5代理方式通过请求获取
:return:
"""
# 握手
logger.info('开始与客户端握手')
self.client_socket.recv(1024)
self.client_socket.send(b"\x05\x00")
logger.info('开始与服务器创建链接')
# 接收客户端的请求
request = self.client_socket.recv(4096)
logger.info('request:', request)
# 解析请求,获取目标地址和端口
address_type = request[3]
logger.info('address_type', address_type)
if address_type == 1: # IPv4地址
target_address = socket.inet_ntoa(request[4:8])
target_port = int.from_bytes(request[8:10], byteorder='big')
elif address_type == 3: # 域名
address_length = request[4]
target_address = request[5:5 + address_length].decode()
target_port = int.from_bytes(request[5 + address_length:7 + address_length], byteorder='big')
else:
# 不支持的地址类型
logger.warning(f'地址类型{address_type}不支持,socket即将主动关闭,请检查或添加对应类型的处理办法')
self.client_socket.close()
return
logger.info(f'成功获取到服务器地址:{(target_address, target_port)}')
self.server_socket.connect((target_address, target_port))
# 响应客户端连接成功
response = b"\x05\x00\x00\x01" # 版本、响应码、保留字段、地址类型(IPv4)
response += socket.inet_aton("0.0.0.0") + (0).to_bytes(2, byteorder='big') # 绑定的地址和端口
self.client_socket.sendall(response)
logger.info('服务器连接创建完成')
代理启动之前,自定义功能进行了隐藏 (避免使用的同学手贱,在代理启动之前就进行方法调用) ,在代理正常启动之后,这些功能按钮才会进行显示,对比之前那版工具,针对产品的弱网测试需求,进行了一些尝试,经测试,能达到弱网效果,但不确定是不是跟实际的弱网结果完全一致。
弱网的原理是协议的延迟发送,在点击对应的按钮后,可以开启转发延迟功能,比如发包延迟,工具在收到客户端的发送协议之后,不会立即转发给服务器,而是在一定时间(可配置延迟时间)之后再进行发送,同理,收包延迟也是在工具收到服务器的返回协议之后,等待一定的时间再转发给客户端,从而达到模拟网络延迟的目的,闪断也是一样的原理,通过主动断开客户端的 socket 连接,触发客户端的断线重连功能,观察断线重连的逻辑是否正确。
另外一个改动,是增加了协议生成的参数填写方式,之前小伙伴在使用抓包工具的时候反馈生成协议的功能不是很便利,尤其是有的协议需要传入对象,不便于填写,所以新做了一个生成协议的界面,如图
填入一个协议号,点击调用,会自动列出这个协议所需要的参数,只要按照后面的参数类型进行填写,然后点击生成协议按钮,就可以生成这个协议的封包了
有的时候,协议参数不是基础参数类型,而是对象类型,对于这类协议,会有一个增加对象的按钮,点击增加对象按钮,会调用一个对象生成器(跟上面的协议生成器基本一致),填入对象参数并生成对象,就会自动将对象插入到对应的参数栏中。
这里用到了 pyqt5 的 tableWidget 组件,这个组件可以实现一些跟 excel 类似的功能。
最后的优化就是整合了 pyecharts 的图表功能,用来做协议分析,在我之前介绍游戏协议测试的时候,有在最后提到过协议的 有效性 和 冗余性(具体可以瞄一眼之前写的帖子 https://testerhome.com/topics/32820 ),分析协议的有效性和冗余性最重要的两个指标就是发送频率(次数)和协议长度,所以后来在进行工具优化的时候,增加了协议的发送和接收的图表统计,这个是直接照搬了 pyecharts 官网的例子,有兴趣的同学可以去 pyecharts 官方文档 查看更多例子,在下图中,有些协议比较出众的,就需要重点关注一下了,比如某条协议出现的次数特别多,长度特别长的,就需要分析一下,是否有必要这么频繁,是否有必要这么多内容等等,在满足必要功能的前提下减少协议次数,缩短协议长度,是一个优化方向。
抓包工具的优化内容暂时就这么多,后面想到其他点子的话,也会尝试去丰富它的功能,欢迎各位大佬进行指点和探讨。