Mysql 協議嗅探是什么
發表時間:2023-07-18 來源:明輝站整理相關軟件相關文章人氣:
[摘要]需求監聽通過網卡的所有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知識。