Maison  >  Article  >  base de données  >  Qu’est-ce que le protocole Mysql qui renifle ?

Qu’est-ce que le protocole Mysql qui renifle ?

一个新手
一个新手original
2017-10-13 10:14:401600parcourir

Exigences

Surveillez tout le trafic MySQL passant par la carte réseau, analysez-le et effectuez une détection d'intrusion (IDS) ou une intégration de données sans affecter les activités existantes

Points de protocole

Au début, j'ai trouvé que le format des paquets de données était différent lors de l'utilisation de mysql-front pour accéder à la base de données et de l'accès client mysql. J'ai eu du mal pendant longtemps et je n'ai pas compris le code source de mysql-front. et j'ai trouvé Delphi. Je n'ai pas compris et je l'ai abandonné

Analyse de compression

Lors de la liaison vers mysql, si le paramètre -C est activé, la compression est activée pour les données de connexion. est zlib

La fonction de compression de mysql est :

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

Parmi eux, la ligne 35 appelle la fonction compress() dans zlib, mais seul compress() y est encapsulé, et il n'y a pas de partie analyse de protocole.

Il est difficile de trouver le code cible dans l'ensemble du projet. Vous pouvez d'abord rechercher les informations clés dans le fichier d'en-tête, j'ai donc trouvé le code suivant

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

Voici ce qui se passe. lorsque MySQL analyse les données compressées. Vous pouvez rechercher tour à tour le message d'erreur et le code d'erreur et trouver le véritable code de compression des paquets de données

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

À partir des lignes 8 à 19, vous pouvez voir que le processus de mise en paquet des données compressées est effectué. est précédé de l'ajout NET_HEADER_SIZE + COMP_HEADER_SIZE Champ de contrôle long

Recherchez cette macro et constatez que sa définition est la suivante

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

Le champ de longueur dans le NET_HEADER_SIZE Le champ stocke la longueur de la partie des données non décompressées

Le champ COMP_HEADER_SIZE est utilisé pour stocker la longueur des données décompressées. Nous pouvons demander de la mémoire en séquence, puis appeler zlib pour analyser le contenu compressé.

Si vous effectuez directement une analyse zlib sur les données capturées par Wireshark sans analyse, la décompression échouera en raison de l'existence du champ de contrôle. L'erreur signalée en python est la suivante

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>zlib.error: Error -3 while decompressing data: incorrect data check
À première vue, cette erreur est un casse-tête et je ne veux pas lire les détails de l'analyse zlib, j'ai donc créé cet article pour trouver la cause à partir de MySQL. Je peux maintenant enregistrer que le début de la chaîne compressée zlib est. souvent x78x9c Si la même erreur se produit, vous pouvez vérifier si elle est correcte

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn