c语言连接mysql_MySQL数据库审计核心实现(内有代码)

大家好,今天分享关于基于C语言的Mysql数据库审计核心实现。本篇首先介绍MySQL网络协议,然后再介绍代码如何通过旁路镜像的方式实现对数据库的审计(我写的是针对pcap包,如果你希望通过旁路镜像方式,稍微改造即可)。

目前业界有非常多的数据库审计产品,基本是以流量或者探针形式对数据库进行综合审计,功能包括:审计查询、攻击检测、越权访问等。其核心基本是建立在操作语句识别及返回结果识别基础上形成的不同功能场景,本文通过对mysql包进行解析,可识别客户端查询语句及服务端返回结果内容,让读者直观了解数据库审计的核心功能如何实现。

1.MySQL网络协议分析

在读者对第二节代码阅读时,建议读者先了解mysql的网络协议,以便更好读懂代码,如果读者非常了解mysql相关协议,可跳过该节。

mysql数据类型包括:整数型和字符串型。

整数型分为定长型,如:int<1>、int<2>、int<3>、int<4>等。变长型INT,所存储字节数大小取决于第一个字节的数值大小。

字符串型分为固定长度的字符串、NULL结束的字符串、可变的字符串、长度编码字符串、EOF。

Mysql协议包报文格式如下:

5be33de6fc5398debf660726befc082e.png

mysql报文格式

例如COM_INIT_DB(切换数据库)整包字节序列为:07 00 00 00 02,如下图:

647bff50f5ab7b9d3c212be583101824.png

COM_INIT_DB抓包

图中标识“74 72 73 61 70 70”十六进制转文本后为trsapp,即我们所使用的数据库名。

热身完毕后,我们来看Mysql是怎样交互的。如下图:

7c8a41b1440ffee850f2aa05bf397341.png

Mysql交互示意图

首先mysql是基于TCP协议,所以在建立连接与断开连接时需要三次握手和四次挥手。当客户端连接服务端时,首先TCP三次握手建立连接,随后客户端将用户信息(用户名、密码等)发送与服务端,服务端确认后返回ok_pack/error_pack包信息, OK后,客户端会发送指令至服务端,首先是use database信息,服务端返回ok信息,随后进行select、insert等指令操作。如下图:

0e640ee49eeb485824b808b1942ee52d.png

我本地查询抓包信息

客户端要与服务端断开时,发送COM_QUIT(0x01 )数据包,随后进行tcp四次挥手结束。

具体mysql状态码如下:

cfaa5a9c0fa3f058e547933101df7fd0.png

mysql状态码

当我们发送query查询语句时,其流程如下:

3b23e4b85b1a4cd1d3f401bacac2249c.png

query语句查询

客户端发起query查询后,如下图:

e58c74fdcb086cbc547e906b1f83a486.png

select查询

mysql返回内容格式为:field_cout字段信息+EOF+返回数据信息,如下图:

6ff1923ffff509f8d75d274af85e92b9.png

1.response返回-file_count字段信息

d07ea4831347d9909a7096d4bfa83bab.png

2.EOF包信息

9341371676812c46d28822aeb21901ce.png

3.返回数据信息

EOF Packet,表示结果数据完毕,若此包中的MORE_RESULT不为0 ,则说明接下来还有结果信息,又返回源头继续开始。

如果过程中读到任何一个error包后,读取将结束,并抛出错误。

以上是mysql协议核心介绍。想必你已经相对了解mysql的协议交互过程啦,如想深入了解,请参考mysql文献资料。

2.核心代码实现

本文基于C语言,通过对MySQL的协议进行解析,识别查询内容和返回结果。读者可通过搭建libpcap或者pf_ring环境,实时读取数据包内容进行识别输出(本文是读取pcap包),关于libcap、pf_ring,如果你感兴趣,我会抽时间单独写一篇文章。闲话少说,直接撸代码(代码我已注释比较详细)。

实现效果图:

448ead5f3c7771e86caf20fa5a7f6e09.png

表信息

8a7e586e4035791bafe3e977b1ad14fa.png

识别查询语句

48facad534cbf241ac13fed67f728c6c.png

识别列信息和字段信息

核心代码实现:

/*============================================================================Name:DatabaseAudit.cAuthor:wangfengVersion:Copyright:YourcopyrightnoticeDescription:DatabbaseAuditinC,Ansi-style============================================================================*/#include#include#include#include#include#include#include"DatabaseAudit.h"//字节流转换为十六进制字符串voidByteToHexStr(constunsignedchar*source,char*dest,intsourceLen){shorti;unsignedcharhighByte,lowByte;for(i=0;i>4;lowByte=source[i]&0x0f;highByte+=0x30;if(highByte>0x39)dest[i*2]=highByte+0x07;elsedest[i*2]=highByte;lowByte+=0x30;if(lowByte>0x39)dest[i*2+1]=lowByte+0x07;elsedest[i*2+1]=lowByte;}return;}voidHexStrToByte(constchar*source,unsignedchar*dest,intsourceLen){shorti;unsignedcharhighByte,lowByte;for(i=0;i0x39)highByte-=0x37;elsehighByte-=0x30;if(lowByte>0x39)lowByte-=0x37;elselowByte-=0x30;dest[i/2]=(highByte<<4)|lowByte;}return;}/*返回ch字符在sign数组中的序号*/intgetIndexOfSigns(charch){if(ch>='0'&&ch<='9'){returnch-'0';}if(ch>='A'&&ch<='F'){returnch-'A'+10;}if(ch>='a'&&ch<='f'){returnch-'a'+10;}return-1;}/*十六进制数转换为十进制数*/longhexToDecNew(char*source){longsum=0;longt=1;inti,len;len=strlen(source);for(i=len-1;i>=0;i--){sum+=t*getIndexOfSigns(*(source+i));t*=16;}returnsum;}voidanalysisMysql(){//define//pcap_file_head*pcapFileHead;pcap_head*pcapHead;frame_head*frameHead;ip_head*ipHead;tcp_head*tcpHead;mysql_request_head*mysqlHead,*mysqlCHHead;mysql_request_eof*mysqlRequestEof;intoffset=0,dataOffset=54;charsrc_ip[STRSIZE],dst_ip[STRSIZE];unsignedchar*mysqlTmp=(unsignedchar*)malloc(sizeof(unsignedchar));intsrc_port,dst_port,tcp_flags;inti;FILE*fp;//文件//初始化,动态内存分配//pcapFileHead=(pcap_file_head*)malloc(sizeof(pcap_file_head));pcapHead=(pcap_head*)malloc(sizeof(pcap_head));frameHead=(frame_head*)malloc(sizeof(frame_head));ipHead=(ip_head*)malloc(sizeof(ip_head));tcpHead=(tcp_head*)malloc(sizeof(tcp_head));mysqlHead=(mysql_request_head*)malloc(sizeof(mysql_request_head));mysqlCHHead=(mysql_request_head*)malloc(sizeof(mysql_request_head));mysqlRequestEof=(mysql_request_eof*)malloc(sizeof(mysql_request_eof));intmysqlEof=0;if((fp=fopen("/home/roo/eclipse-workspace/DatabaseAudit/src/mysql1.pcap

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值