Home  >  Article  >  Database  >  What is Mysql protocol sniffing?

What is Mysql protocol sniffing?

一个新手
一个新手Original
2017-10-13 10:14:401656browse

Requirements

Monitor all mysql traffic passing through the network card, analyze it, and perform intrusion detection (IDS) or data integration without affecting existing business

Protocol points

At first I found that the data packet format was different when using mysql-front to access the database and when mysql client accessed it. I struggled for a long time and didn’t understand. I took a look at the mysql-front source code and found Delphi. I didn’t understand and abandoned it

Compression analysis

When linking mysql, if the -C parameter is enabled, compression is enabled for the connection data, and the compression format is zlib

The compression function of mysql is:

// 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;
}

where Line 35 calls the compress() function in zlib, but only compress() is encapsulated there, and there is no protocol analysis part. Let’s continue looking down.

It is difficult to find the target code in the entire project. You can first look for key information in the header file, so I found the following code

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

This is when mysql makes an error when parsing the compressed data. Prompt information and error codes can be searched for their references in turn, and the real data packet compression code

// 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;
}

can be seen from lines 8-19. The packaging process of compressed data is preceded by . NET_HEADER_SIZE + COMP_HEADER_SIZE Long control field

Look for this macro and find that its definition is as follows

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 */

The length field in the NET_HEADER_SIZE field stores the length of the undecompressed data part

The COMP_HEADER_SIZE field is used to store the length of the decompressed data. We can apply for memory in sequence, and then call zlib to parse the compressed content.

If you directly perform zlib analysis on the data captured by wireshark without analysis, the decompression will fail due to the existence of the control field. The error reported in python is as follows

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

I saw this error at first I have a headache and don’t want to read the details of zlib parsing, so I came up with this article to find the reason from mysql. Now I can record that the beginning of the zlib compressed string is often \x78\x9c. If the same error occurs, you can check whether it is correct

The above is the detailed content of What is Mysql protocol sniffing?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn