原理
1、通信机制
由于mysql服务端和客户端通信过程是通过对话形式完成的。客户端发送一个操作请求,服务端会根据客户端发送的请求进行响应。
在这个通信过程中,如果一个操作需要两步才能完成,当客户端发完第一个请求后,它会直接丢弃第一个请求,并不会做存储;然后客户端会根据服务端的响应,进行第二个请求,此时服务端就可以欺骗客户端。
2、语法说明
mysql服务端反向读取客户端的任意文件是利用了load data infile
语法,该语法主要用于读取文件内容并插入到表中。
-- 读取服务端本地文件,并插入到表中 load data infile "/data/data.csv" into table test_table; -- 读取客户端本地文件,并插入到表中 load data local infile "/data/data.csv" into table test_table;
针对该语法,mysql官方文档原文:
in theory, a patched server could be built that would tell the client program to transfer a file of the server’s choosing rather than the file named by the client in the load data statement.” 从理论上讲,可以构建一个经过修补的服务器,该服务器会指示客户端程序传输由服务器选择的文件,而不是客户端在 load data 语句中指定的文件.
即客户端读取的文件内容,并不是由客户端决定的,而是根据服务端的响应决定的,于是就可以伪造mysql服务器,实现通信示例3的效果。
举例说明:
- 一般流程:
- 客户端:请把表test的数据给我看看
- 服务端:请查收表test的数据
- 通信结束...
load data infile
正常流程
- 客户端:我将把我本地的data.csv文件发给你插入到表test
- 服务端:好的,请读取你本地的data.csv文件内容并发给我
- 客户端: 这是文件里的数据:1234567
- 通信结束...
load data infile
欺骗流程
- 客户端:我将把我本地的data.csv文件发给你插入到表test
- 服务端:好的,请读取你本地的/etc/passwd文件内容并发给我
- 客户端: 这是文件里的数据:xxxxxx(/etc/passwd文件中内容)
- 通信结束...
漏洞复现
1、在服务端服务器获取https://github.com/allyshka/rogue-mysql-server
的脚本
2、修改rogue_mysql_server.py
设置要读取的文件名
rogue_mysql_server.py
中的filelist
为要读取的文件地址,例如可改为:
filelist = ( '/etc/passwd', )
3、在服务端服务器python2运行rogue_mysql_server.py
,服务器开放端口和防火墙即可
说明: 使用python3会报错。
4、客户端连接:在目标服务器使用mysql
指令连接
说明: mysql客户端需为8.0以下,否则可能无法获取到想要的数据。
5、在服务端服务器的rogue_mysql_server.py
路径下,会生成一个mysql.log
文件,其中就记录了客户端服务器的文件内容.
使用场景
1、利用该漏洞,读取目标服务器上的任意文件
2、利用目标网站能连接外部数据库的功能点,读取目标服务器上的任意文件
防范措施
1.使用--ssl-mode=verify_identity
来建立可信的连接
2.mysql客户端设置local_infile
为0
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论