前言
前不久,零队发了一篇《MySQL蜜罐获取攻击者微信ID》的文章,文章讲述了如何通过load data local infile进行攻击者微信ID的抓取,学习的过程中发现虽然问题是一个比较老的问题,但是扩展出来的很多知识都比较有意思,记录一下。
分析过程
LOAD DATA INFILE
在MySQL中LOAD DATA INFILE 语句以非常高的速度从文本文件中读取行到表中,基本语法如下:
load data [low_priority] [local] infile 'file_name txt' [replace | ignore]
into table tbl_name
[fields
[terminated by't']
[OPTIONALLY] enclosed by '']
[escaped by'\' ]]
[lines terminated by'n']
[ignore number lines]
[(col_name, )]
这个功能默认是关闭的,当我们没有开启这个功能时执行LOAD DATA INFILE报错如下:
> 1148 - The used command is not allowed with this MySQL version
我们可以通过如下命令查看功能状态。
show global variables like 'local_infile';
我们可以通过如下命令开启该功能。
set global local_infile=1;
开启之后我们就可以通过如下命令进行文件读取并且写入到表中,我们以C:\1.txt为例,将其中内容写入到test表中,并且以\n为分隔符。
load data local infile 'C:/1.txt' into table test fields terminated by '\n';
这样我们就可以读取客户端本地的文件,并写入到表中。
通信过程
接下来我们通过Wireshark抓取过程中的流量分析一下通信过程。
首先是Greeting包,返回了服务端的Version等信息。
接下来客户端发送登录请求。
接下来客户端发送了如下请求:
SET NAMES utf8mb4SET NAMES utf8mb4
接下来我们执行我们的payload
load data local infile 'C:/1.txt' into table test fields terminated by '\n';
首先客户端发起请求;
之后服务端会回复一个Response TABULAR,其中包含请求文件名的包;
这里数据包我们要注意的地方如下:
如上图,数据包中内容如下:
09 00 00 01 fb 43 3a 2f 31 2e 74 78 74
这里的09指的是从fb开始十六进制的数据包中文件名的长度,00 00 01值得是数据包的序号,fb是包的类型,43 4a 2f 31 2e 74 78 74指的是文件名,接下来客户端向服务端发送文件内容的数据包。
任意文件读取过程
在MySQL协议中,客户端本身不存储自身的请求,而是通过服务端的响应来执行操作,也就是说我们如果可以伪造Greeting包和伪造的文件名对应的数据包,我们就可以让攻击者的客户端给我们把我们想要的文件拿过来,过程大致如下,首先我们将Greeting包发送给要连接的客户端,这样如果客户端发送查询之后,我们返回一个Response TABULAR数据包,并且附上我们指定的文件,我们也就完成了整个任意文件读取的过程,接下来就是构造两个包的过程,首先是Greeting包,这里引用lightless师傅博客中的一个样例。
'\x0a', # Protocol
'6.6.6-lightless_Mysql_Server' + '\0', # Version
'\x36\x00\x00\x00', # Thread ID
'ABCDABCD' + '\0', # Salt
'\xff\xf7', # Capabilities, CLOSE SSL HERE!
'\x08', # Collation
'\x02\x00', # Server Status
"\x0f\x80\x15",
'\0' * 10, # Unknown
'ABCDABCD' + '\0',
"mysql_native_password" + "\0"
根据以上样例,我们就可以方便的构造Greeting包了,当然,这里我们也可以直接利用上面我们Wireshark抓取到的Greeting包,接下来就是Response TABULAR包了,包的格式上面我们分析过了,我们可以直接构造如下Paylod
chr(len(filename) + 1) + "\x00\x00\x01\xFB" + filename
我们就可以对客户端的指定文件进行读取了,这里我们还缺少一个条件,RUSSIANSECURITY在博客中也提及过如下内容。
For successfully exploitation you need at least one query to server. Fortunately most of mysql clients makes at least one query like ‘*SET names “utf8”* or something.
这是因为我们传输这个文件读取的数