MySQL任意文件读取
在之前有过类似的测试,但是测试比较浅
和这次测试的目的是不一样的
之前的测试
测试目的
MySQL的任意文件读取漏洞
是在数据库链接时触发的?
还是在数据库执行查询操作的时候触发的?
测试环境
php+mysql
测试模块
mysql.dll
变量
mysql_connect
函数mysql_select
函数
测试结果
MySQL
的任意文件读取是在查询或者插入操作时触发的
触发过程大概是
- 服务端:
greeting
握手包 - 客户端:
login
数据包 - 服务端:连接成功数据包
- 客户端:现在我要查询一下版本信息
- 服务端:好的,把
/etc/passwd
文件发过来吧 - 客户端:好的,这是我的
/etc/passwd
文件
整体来说,原生的MySQL
触发任意文件读取是没有太大的问题的
新的测试
在框架中,大多数据库操作的底层是调用PDO
处理
在实际的源码中,已经遇到多套CMS
存在任意文件读取漏洞,但是无法利用成功
72crm
wemall
- 几度
cms
- …….
以72crm
为例
上面的连接数据库的设置,下面通过execute
执行了select version()
由于进行了查询操作理论上应该是可以进行任意文件读取的
但是经过测试后,发现并不可以
可以看到这里只有连接的信息,并没有读取的文件
经过调式之后发现
在预处理出,发生了错误,返回值不再是一个PDO
的对象而是null
错误就是MySQL server has go away
既然牵扯到了预处理,那么就
提出问题
问题1:不同的预处理方式,是否对结果产生影响?
测试变量
MySQL
原生的预处理PDO
模拟预编译
测试
在ThinkPHP5
中采用的是原生的预处理
通过wireshark
进行数据包分析
发现这里存在一个prepare
的预处理数据包
开启模拟预编译后,可以发现并没有prepare的数据包
直接就是query
的数据包了
说明一点
- 当开启模拟预编译之后,操作在
PDO
内部完成,不牵扯数据库 $this->PDOStatement = $this->linkID->prepare($sql);
问题2:那这个数据包会不会成为影响读取成败的关键呢?
这个时候想起来,报的错误是服务丢失,那么存在两种情况
- 连接断开
- 没有返回包
测试
测试没有成功读取文件的,数据包
可以看到这里有预处理的数据包,下面一堆tcp
数据包,服务其实并没有断开
就是没有给客户端返回响应包
之前的脚本不成功的原因也就找到了
因为只有三次响应
greeting
响应包- 连接成功响应包
- 读取文件的响应包
我们需要在连接成功和读取文件中间添加预处理的响应包
编写脚本
需要看看预处理的响应包到底是什么?
编写脚本
1 | import socket |
运行测试
但仍然存在缺陷,就是PDO
默认是不支持文件读取的,所以需要添加
PDO::MYSQL_ATTR_LOCAL_INFILE => true,
成功读取文件
没有太大的意义,只能说是对MySQL
任意文件读取的一种探究
结论
碰到PDO
没办法设置参数的,就无法完成任意文件读取