最近有闲,对之前写的抓包工具进行了一波优化 (具体可点击查看之前的帖子),针对协议收发方式,对 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 官方文档 查看更多例子,在下图中,有些协议比较出众的,就需要重点关注一下了,比如某条协议出现的次数特别多,长度特别长的,就需要分析一下,是否有必要这么频繁,是否有必要这么多内容等等,在满足必要功能的前提下减少协议次数,缩短协议长度,是一个优化方向

  抓包工具的优化内容暂时就这么多,后面想到其他点子的话,也会尝试去丰富它的功能,欢迎各位大佬进行指点和探讨。


↙↙↙阅读原文可查看相关链接,并与作者交流