• MySQL协议分析(2)


    MySQL协议分析(2)

    此阶段是在压缩传输无加密条件下进行的协议分析

    思路

    结合Oracle官网的说明和自己用wireshark加python进行数据包分析

    步骤

    1. 客户端与服务器端是否压缩的协商阶段

    2. 压缩传输的数据包格式

    3. 数据包解压缩分析过程

    压缩协商阶段

    • 首先,用户发起连接数据库的请求,并添加了压缩的参数-C进行传输,此时在网络中TCP建立后,服务器端会给客户端一个Greeting,其中包括了服务器端的MySQL版本、协议版本、支持的能力(其中就包括是否支持压缩)等。

    • 然后,客户端会发送给服务器端一个登陆请求,其中包括:能力标志(里面包括了是否要进行压缩传输,若是压缩传输,则标志位置为1)、字符集、用户名、密码(md5加密)等。

    数据包如下:

    MySQL Protocol
        Packet Length: 58
        Packet Number: 1
        Login Request
            Client Capabilities: 0xa6a5
                .... .... .... ...1 = Long Password: Set
                .... .... .... ..0. = Found Rows: Not set
                .... .... .... .1.. = Long Column Flags: Set
                .... .... .... 0... = Connect With Database: Not set
                .... .... ...0 .... = Don't Allow database.table.column: Not set
                .... .... ..1. .... = Can use compression protocol: Set
                .... .... .0.. .... = ODBC Client: Not set
                .... .... 1... .... = Can Use LOAD DATA LOCAL: Set
                .... ...0 .... .... = Ignore Spaces before '(': Not set
                .... ..1. .... .... = Speaks 4.1 protocol (new flag): Set
                .... .1.. .... .... = Interactive Client: Set
                .... 0... .... .... = Switch to SSL after handshake: Not set
                ...0 .... .... .... = Ignore sigpipes: Not set
                ..1. .... .... .... = Knows about transactions: Set
                .0.. .... .... .... = Speaks 4.1 protocol (old flag): Not set
                1... .... .... .... = Can do 4.1 authentication: Set
            Extended Client Capabilities: 0x0003
            MAX Packet: 1073741824
            Charset: utf8 COLLATE utf8_general_ci (33)
            Username: root
            Password: 3dad2597af36922c753c7ef0d0f22c18ee0af0bf
    
    

    具体的能力标志位如下:

    共16位,值为0xa6a5,即1010011010100101,其中,第11位的 Can use compression protocol: Set就是是否压缩,若为1,则压缩传输,若为0,则不压缩。

    • 服务器端发送确认,开始压缩传输,规则见下面的压缩传输的数据包格式。

    压缩传输的数据包格式说明

    压缩数据包主要分为压缩数据包头和压缩后的数据包(或者未压缩的数据包,这种情况在后面说明)

    压缩数据包头

    压缩数据包头共占7字节,分为3段,格式如下:

    第一段: 压缩后的mysql数据包的长度。它的值的计算方法是TCP总数据包的长度-7,也就是总长度减去压缩数据包头剩下的就是mysql数据包压缩后的长度,占3字节;

    第二段: sequence id,序列id,占1字节;

    第三段: 压缩前/解压缩后的mysql数据包的长度,占3字节。

    压缩传输的数据包

    分为两种情况:

    第一种情况是数据包长度小于50字节,这种情况下即使选择了压缩传输,由于数据包太短,兼顾效率问题,就不会被压缩传输;同时在上述的压缩数据包头的第三个字段会为0.

    第二种情况是数据包长度大于50字节,这种情况下就会对数据包进行压缩传输,且压缩数据包头的第三个字段会大于0.

    解压缩

    在官网中说明了压缩过程选用的是zlib进行的压缩,所以我们需要找到zlib的解压缩方法。本次采用的是Python中的zlib库。

    • 请求的压缩

    (从客户端发起一个SQL语句的请求,保证此请求的长度大于50bytes,会产生压缩)

    执行SQL语句如下:

    select ID,USERID,USERNAME,BIRTHDAY,SALARY from smalltable where ID = 999 and USERNAME = 'fdsfsdfdsdsafs'
    

    在wireshark中抓到此次请求的包,右键,复制为转移字符串,然后粘贴到Python中,定义一个字符串s。

    import zlib
    
    s = "x78x9cxcbx64x60x60x60x2ex4excdx49x4dx2ex51xf0x74xd1x09x0dx76x0dx82x52x7ex8exbexaex3ax4ex9ex41x21x1ex2ex8ex91x3axc1x8ex3ex8ex41x91x0ax69x45xf9xb9x0axc5xb9x89x39x39x25x89x49x39xa9x0axe5x19xa9x45xa9x40x8dx0axb6x0ax96x96x96x0ax89x79x29x0ax30xbdx40x21xf5xb4x94xe2xb4xe2x14x20x99x52x9cx98x56xacx0ex00xcdx25x21x24"
    
    un_c  = zlib.decompress(s)
    print un_c
    

    观察到输出为iselect ID,USERID,USERNAME,BIRTHDAY,SALARY from smalltable where ID = 999 and USERNAME = 'fdsfsdfdsdsafs'

    验证了分析过程的正确性。

    问题:在语句前有一个字符'i',猜测可能为校验码之类的值,未验证。

    • 响应的压缩

    (从客户端发起个SQL语句的请求,保证得到的响应结果大于50bytes,且大于1514,大于1514是为了验证当响应结果特别长,发生了分包时的情况)

    执行SQL语句

    select * from smalltable where ID < 100
    

    类似于上面的步骤,将所有响应的TCP包中的TCP payload右键,复制为转义字符串,粘贴到Python中,通过这种方式手动把多个包拼在一起。(因为这个包太长了,这里就不放了)程序也与上面相同。验证后正确解压缩,只是结果与我们查看的结果的格式有些许的不同。

    压缩无加密的MySQL协议分析结束。

  • 相关阅读:
    Vue.js——60分钟组件快速入门(下篇)三
    ASP.NET Core 中的 ORM 之 Dapper
    .Net Core中Dapper的使用详解
    .NetCore与Vue
    Vue 导入文件import、路径@和.的区别
    Git常见命令
    JVM垃圾回收补充知识点
    Java虚拟机垃圾回收(三): 7种垃圾收集器(转载)
    Java虚拟机垃圾回收(二) :垃圾回收算法(转载)
    Java虚拟机垃圾回收:基础点(转载)
  • 原文地址:https://www.cnblogs.com/qjx-2016/p/10178510.html
Copyright © 2020-2023  润新知