<form id="hz9zz"></form>
  • <form id="hz9zz"></form>

      <nobr id="hz9zz"></nobr>

      <form id="hz9zz"></form>

    1. 明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

      Mysql 協議嗅探是什么

      [摘要]需求監聽通過網卡的所有mysql流量,進行解析,可在不影響現有業務情況下,進行入侵檢測(IDS)或數據集成協議要點起初發現 用mysql-front訪問數據庫和mysql 的客戶端訪問時數據包格式不...

      需求

      監聽通過網卡的所有mysql流量,進行解析,可在不影響現有業務情況下,進行入侵檢測(IDS)或數據集成

      協議要點

      起初發現 用mysql-front訪問數據庫和mysql 的客戶端訪問時數據包格式不同,糾結很久,不明白,mysql-front源碼看了眼,delphi,不懂,棄

      壓縮解析

      當鏈接mysql時,若啟用-C參數表示,對于連接數據啟用壓縮,壓縮格式為zlib

      mysql的壓縮函數為:

      // mysql-source/mysys/my_compress.c
      
      my_bool my_compress(uchar *packet, size_t *len, size_t *complen)
      {
        DBUG_ENTER("my_compress");
        if (*len < MIN_COMPRESS_LENGTH)
        {
          *complen=0;
          DBUG_PRINT("note",("Packet too short: Not compressed"));
        }
        else
        {
          uchar *compbuf=my_compress_alloc(packet,len,complen);
          if (!compbuf)
            DBUG_RETURN(*complen ? 0 : 1);
          memcpy(packet,compbuf,*len);
          my_free(compbuf);
        }
        DBUG_RETURN(0);
      }
      
      
      uchar *my_compress_alloc(const uchar *packet, size_t *len, size_t *complen)
      {
        uchar *compbuf;
        uLongf tmp_complen;
        int res;
        *complen=  *len * 120 / 100 + 12;
      
        if (!(compbuf= (uchar *) my_malloc(key_memory_my_compress_alloc,
                                           *complen, MYF(MY_WME))))
          return 0;                    /* Not enough memory */
      
        tmp_complen= (uint) *complen;
        res= compress((Bytef*) compbuf, &tmp_complen, (Bytef*) packet, (uLong) *len);
        *complen=    tmp_complen;
      
        if (res != Z_OK)
        {
          my_free(compbuf);
          return 0;
        }
      
        if (*complen >= *len)
        {
          *complen= 0;
          my_free(compbuf);
          DBUG_PRINT("note",("Packet got longer on compression; Not compressed"));
          return 0;
        }
        /* Store length of compressed packet in *len */
        swap_variables(size_t, *len, *complen);
        return compbuf;
      }

      其中第35行調用了zlib中的compress()函數,但是該處僅對compress()進行了封裝,并沒有協議解析部分,我們繼續往下看。

      整個項目尋找目標代碼比較費勁,可以先在頭文件中尋找關鍵信息,于是找到了下面的代碼

      // mysql-source/include/sql_state.h
      { ER_NET_UNCOMPRESS_ERROR                 ,"08S01", "" }

      這是在mysql在解析壓縮的數據時如果出錯的提示信息和錯誤碼,依次可以查找其引用,發現了真正的數據包壓縮代碼

      // mysql-source/sql/net_serv.cc
      
      static uchar *
      compress_packet(NET *net, const uchar *packet, size_t *length)
      {
        uchar *compr_packet;
        size_t compr_length;
        const uint header_length= NET_HEADER_SIZE + COMP_HEADER_SIZE;
      
        compr_packet= (uchar *) my_malloc(key_memory_NET_compress_packet,
                                          *length + header_length, MYF(MY_WME));
      
        if (compr_packet == NULL)
          return NULL;
      
        memcpy(compr_packet + header_length, packet, *length);
      
        /* Compress the encapsulated packet. */
        if (my_compress(compr_packet + header_length, length, &compr_length))
        {
          /*
            If the length of the compressed packet is larger than the
            original packet, the original packet is sent uncompressed.
          */
          compr_length= 0;
        }
      
        /* Length of the compressed (original) packet. */
        int3store(&compr_packet[NET_HEADER_SIZE], static_cast<uint>(compr_length));
        /* Length of this packet. */
        int3store(compr_packet, static_cast<uint>(*length));
        /* Packet number. */
        compr_packet[3]= (uchar) (net->compress_pkt_nr++);
      
        *length+= header_length;
      
        return compr_packet;
      }

      從8-19行可以看到,壓縮數據的組包過程,前面分別加了NET_HEADER_SIZE + COMP_HEADER_SIZE 長的控制字段

      查找該宏,發現其定義如下

      1 // mysql-source/include/mysql_com.h
      2 
      3   /* Constants when using compression */
      4 #define NET_HEADER_SIZE 4        /* standard header size */
      5 #define COMP_HEADER_SIZE 3        /* compression header extra size */

      NET_HEADER_SIZE 字段中 長度字段存儲 數據部分 未解壓時的長度

      COMP_HEADER_SIZE 字段是用來存儲 解壓后的 數據的長度,我們可以依次申請內存,然后調用zlib對壓縮內容進行解析即可。

      如果不分析直接進行對wireshark抓到的數據進行zlib解析的話,由于控制字段的存在會解壓縮失敗,在python中的報錯如下

      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>zlib.error: Error -3 while decompressing data: incorrect data check

      起初看到這個錯誤很頭痛也不想看zlib解析細節,才有了從mysql找原因的本文,現在可以記錄zlib 壓縮字符串的開頭常常是\x78\x9c,出現同樣錯誤的可以看看是否正確

      以上就是Mysql 協議嗅探是什么的詳細內容,更多請關注php中文網其它相關文章!


      學習教程快速掌握從入門到精通的SQL知識。




      日韩精品一区二区三区高清