>  기사  >  데이터 베이스  >  MySQL 프로토콜 스니핑이란 무엇입니까?

MySQL 프로토콜 스니핑이란 무엇입니까?

一个新手
一个新手원래의
2017-10-13 10:14:401600검색

요구 사항

네트워크 카드를 통과하는 모든 mysql 트래픽을 모니터링하고 분석하며 기존 비즈니스에 영향을 주지 않고 침입 탐지(IDS) 또는 데이터 통합을 수행합니다.

프로토콜 포인트

처음에는 mysql-front를 사용하여 액세스합니다. 데이터베이스와 mysql 클라이언트가 접속할 때 데이터 패킷 형식이 달라서 오랫동안 고민했는데 이해가 안 가네요. mysql-front 소스 코드를 살펴보니 델파이가 없더군요. 이해하지 못하고 버렸습니다

압축 분석

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

Line 35는 zlib에서 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 분석의 세부 사항을 보고 싶지 않았습니다. 이제 zlib 압축 문자열의 시작 부분이 x78x9c인 경우가 많다고 기록할 수 있습니다. 맞는지 확인해보세요

위 내용은 MySQL 프로토콜 스니핑이란 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.