8

MySQL客户端任意文件读取

 3 years ago
source link: https://www.mi1k7ea.com/2021/04/23/MySQL%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E8%AF%BB%E5%8F%96/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

MySQL客户端任意文件读取

2021-04-23 /

0x00 前言

之前学习Jackson一条Gadget的时候涉及过,HW期间又发现类似的恶意利用工具和漏洞,就再补充一些细节。

0x01 MySQL客户端任意文件读取

LOAD DATA LOCAL INFILE

具体可参考:https://dev.mysql.com/doc/mysql-security-excerpt/5.7/en/load-data-local-security.html

MySQL支持使用LOAD DATA LOCAL INFILE语句,即可将客户端本地的文件中的数据insert到MySQL的某张表中。

注意,还有个LOAD DATA INFILE语句,这是加载服务端的文件而非客户端的。

LOAD DATA LOCAL INFILE的工作过程大致如下:

  1. 用户在客户端输入:load data local file “/data.txt” into table test;
  2. 客户端->服务端:我想把我本地的/data.txt文件插入到test表中;
  3. 服务端->客户端:把你本地的/data.txt文件发给我;
  4. 客户端->服务端:/data.txt文件的内容;

测试看下LOAD DATA LOCAL INFILE语句,用Kali作为客户端远程连接MySQL服务,然后执行如下SQL语句来将/etc/passwd文件中的内容插入到MySQL的users表中:

load data local infile "/etc/passwd" into table users FIELDS TERMINATED BY '\n';

1.png

上述过程存在一个问题,即客户端发送哪个文件的内容,取决于第三步即服务端响应的想要的哪个文件,如果服务端是个恶意的MySQL,那么它可以读取客户端的任意文件内容,比如读取/etc/passwd:

  1. 用户在客户端输入:load data local file “/data.txt” into table test;
  2. 客户端->服务端:我想把我本地的/data.txt文件插入到test表中;
  3. 服务端->客户端:把你本地的/etc/passwd文件发给我;
  4. 客户端->服务端:/etc/passwd文件的内容;

而且,在大部分客户端(比如MySQL Connect/J)的实现里,第一步和第二部并非是必须的,客户端发送任意查询给服务端,服务端都可以返回文件发送的请求。而大部分客户端在建立连接之后,都会有一些查询服务器配置之类的查询,所以使用这些客户端,只要创建了到恶意MySQL服务器的连接,那么客户端所在的服务器上的所有文件都可能泄露。

注意:如果使用MySQL客户端直接连接的话,是需要添加--enable-local-infile选项的,而其他大部分MySQL客户端实现中,是默认开启的,比如allowLoadLocalInfile是MySQL的JDBC驱动的一个创建连接的配置项、用来控制是否允许从本地读取文件,默认值为True,具体的MySQL客户端实现得具体看。

攻击流程如下:

  1. 攻击者开启伪造的恶意MySQL服务器,诱使受害者MySQL客户端访问;
  2. 受害者向恶意MySQL服务器发起请求,并尝试进行身份认证;
  3. 恶意MySQL服务器接受到受害者的连接请求后,发送正常的问候、身份验证正确并且发送LOAD DATA LOCAL INFILE语句来读取受害者客户端本地敏感文件;
  4. 受害者的MySQL客户端认为身份验证正确,执行攻击者的发来的请求,通过LOAD DATA LOCAL INFILE语句将本地文件内容发给恶意MySQL服务器;
  5. 恶意MySQL服务器接受到客户端敏感文件,Done;

GitHub上恶意MySQL服务相关项目:

开启恶意MySQL服务后,受害者尝试使用MySQL客户端连接恶意服务端(这里metasploitable机子的MySQL版本为5.0.51a-3ubuntu5,无需添加--enable-local-infile选项即可成功):

2.png

恶意MySQL服务端窃取到了/etc/passwd文件内容:

3.png

针对LOAD DATA LOCAL INFILE的安全问题,MySQL官方给出如下说明:

为了避免连接到不受信任的服务器,客户端可以建立安全连接并通过使用--ssl-mode=VERIFY_IDENTITY选项和适当的CA证书进行连接来验证服务器身份 。

为避免出现LOAD DATA问题,客户应避免使用LOCAL

管理员和应用程序可以配置是否允许本地数据加载,如下所示:

  • 在服务器端:

    • 所述local_infile系统变量控制服务器端LOCAL 的能力。根据 local_infile设置,服务器会拒绝或允许请求本地数据加载的客户端加载本地数据。
    • 默认情况下,它local_infile 是禁用的。要显式地使服务器拒绝或允许LOAD DATA LOCAL语句(无论在构建时或运行时如何配置客户端程序和库),请在 禁用或启用的情况下启动mysqldlocal_infilelocal_infile也可以在运行时设置。
  • 在客户端:

或者:

>     [client]
> loose-local-infile=1
>
  • 在所有情况下,LOCAL 客户端成功使用加载操作还需要服务器允许本地加载。

如果LOCAL禁用了此功能,则在服务器或客户端上,尝试发出LOAD DATA LOCAL语句的客户端都会 收到以下错误消息:

> ERROR 1148: The used command is not allowed with this MySQL version
>

0x02 MySQL蜜罐

利用该漏洞可以制作MySQL蜜罐来诱使攻击者连接,从而窃取攻击者主机上的敏感信息。GitHub上已有可以读取攻击者微信ID的MySQL蜜罐,具体参见:https://github.com/qigpig/MysqlHoneypot


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK