Rogue Mysql Server 简单分析

首先起环境。我这里使用的是 mysql5.7。

mysql在本地连接默认使用的是本地 sock,不方便抓包,需要手动指定 -h 127.0.0.1。

并且 mysql 默认使用了 ssl。抓包不方便看,所以 客户端连接的时候 采用 –ssl=0 的方式强制让 mysql 不使用 ssl

客户端连接 mysql:

1
mysql -h 127.0.0.1 -u root -p123456  --ssl=0

分析 Mysql 流程

配置好后,Wireshark抓包时就可以看到明文传输的数据了:



LOAD DATA LOCAL INFILE 的作用是将客户端本地的文件导入到 mysql 数据库中,简单用法如下:

1
load data local infile "/PATH/XX.sql" into table TABLE_NAME

这条语句中 /PATH/XX.sql 为读取导入的文件。而 TABLE_NAME 为导入到哪张表中。


为了测试正常 mysql 服务如何处理 LOAD DATA LOCAL INFILE,我们先在 Mysql中创建一个库和一张表:

1
2
3
4
5
6
7
8
9
create database tmp;

use tmp;

create table t(

content text

);

开启抓包并输入SQL语句:

1
load data local infile "/tmp/1.txt" into table tmp.t;


其中红色字体为 客户端请求蓝色字体为 服务端响应。


从这里可以得知 Mysql LOAD DATA LOCAL INFILE 的大致流程:

1、客户端向服务端发送SQL语句,表示需要 LOAD DATA LOCAL INFILE。

2、服务端返回要读取的本地文件路径

3、客户端读取本地文件将内容返回至服务端


而恶意Mysql服务器读取本地文件的原理是,这里第二步骤是可以伪造的。也就是说 Mysql 服务端发送了第二步骤的响应,Mysql客户端就会乖乖的把自己的本地文件读取上交。


Rogue Mysql Server

恶意Mysql服务器的项目在 github 中有:https://github.com/allyshka/Rogue-MySql-Server

clone 下来后,修改下主文件 rogue_mysql_server.py

1
2
3
4
5
PORT = 3307   #端口号

filelist = (
'/tmp/1.txt', #读取文件路径
)

注意 rogue_mysql_server 是使用 python2.7 运行的。


直接 python rogue_mysql_server.py 即可运行


使用 mysql 客户端连接并抓包,对比正常的 LOAD DATA

红框之前的都是登陆包。在 红框中可以看到:虽然客户端发出的请求是 select version。但是服务端却响应了 ”读取本地文件“ 的指令,于是客户端便读取本地文件并上传内容。


这里值得注意的是 ,Mysql 客户端需要发送一次 QUERY 请求,方可读取文件。不知是 Mysql 机制如此还是什么,之后可以瞄一瞄。


Mysqli Client 登陆时自动会发送 select version 请求,但是使用 PHP 连接 Rogue Mysql server 就需要注意了,需要手动添加一个 QUERY 操作: