LOAD DATA LOCAL INFILE在phpmyadmin4.0.10版本后的应用
@ s1ye · Saturday, Feb 29, 2020 · 3 · Feb 29, 2020

LOAD DATA LOCAL INFILE

很早之前就出现的问题了,文章中不会过多的复述相关知识,谷歌关键词搜索“mysql 客户端任意文件读取”。

介绍

# 简单来了解一下官方文档吧。

The LOAD DATA statement can load a file located on the server host, or, if the LOCAL keyword is specified, on the client host.

There are two potential security issues with the LOCAL version of LOAD DATA:

1. The transfer of the file from the client host to the server host is initiated by the MySQL server. 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. Such a server could
access any file on the client host to which the client user has read access. (A patched server could in fact reply with a file-transfer request to any 
statement, not just LOAD DATA LOCAL, so a more fundamental issue is that clients should not connect to untrusted servers.)

2. In a Web environment where the clients are connecting from a Web server, a user could use LOAD DATA LOCAL to read any files that the Web server process 
has read access to (assuming that a user could run any statement against the SQL server). In this environment, the client with respect to the MySQL server 
actually is the Web server, not a remote program being run by users who connect to the Web server.

重点看这两个潜在的安全问题,简单来说就是:

  • 利用该语句可以访问客户端用户具有读取访问权限的客户端主机上的任何文件。
  • 在客户端是从web服务器进行连接的web环境中(例如:phpmyadmin),利用该语句可以读取Web服务器进程具有读取权限的任何文件。

文档中也有解释,在web充当客户端这种web环境中,相对于mysql服务器的客户端是web服务器。说的再简单一些,利用load data local infile读取文件的权限,等同于你php的权限(php为后端语言的情况),php能读/etc/passwd那用改语句也可以读。因此就产生了两个利用条件:

  • php.ini:open_basedir
  • my.ini:local_infile = 1

mysql客户端中的利用

可以看到默认secure_file_priv的value是NULL,需要我们手动去改才能使用load data infile,但是加了local后可以直接读文件,并不受这个限制。

phpmyadmin中的问题

环境为phpmyadmin5.0.1,官方最新版了吧

可以看到,插入了0行。同样是root,同样是使用了local,php也并没有设置open_basedir,很好奇为什么读不到数据。问了同事他说也没遇到过,同事通过查看phpmyadmin的源代码告诉我可以绕过(感谢我老铁的帮助Orz),同时我在phpmyadmin的官方github commit中找到了问题。

绕过限制

github 中2016年的commit

Enable LOAD DATA LOCAL INFILE only when needed

可以发现由于客户端文件读取那个漏洞,phpmyadmin将默认不能使用local infile这个功能,而是将他放入了LDI这个插件中,只有导入了该插件才可以使用该功能。(但是我发现默认并没有这个插件,也有可能后面的版本给移除了,但是功能还在?)

再来看一下修改的代码部分:

没有什么验证,只要post format=1即可define PMA_ENABLE_LDI =1。我下载了最新版的phpmyadmin看了一下源代码,依旧如此。

因此当可以登陆phpmyadmin却不知道根路径或者无法写文件时,也许我们又至少多了一条路可以走

最后

还跟同事开玩笑说让他赶紧交了phpmyadmin 0day,不过顶多算一个bug吧。另外如果文中出现笔误,或者哪里理解错误还望及时指出联系我更改,以免误人子弟。

关于我

s1ye的❤️博客

平时会记录一些学习笔记或分享有趣的姿势

即将毕业🏫的大四学生

职业是一个热爱技术的普通网络安全从业者

目前就职于暗泉信息

团队

所在团队🌈 :ChaBug

ID:s1ye(撕夜,)

可以通过qq1联系我,

- 2020 年 2 月 8 日更新


  1. 1062316154 ↩︎

其他

如果喜欢我的文章,或者有幸某篇文章对您有所帮助。

可以送我一杯咖啡~

我的微信赞赏码

wx

欢迎救济平困人民,非常感谢🙏。