1. 漏洞介绍
这两天,来自波兰的安全研究人员爆出了两个MySQL的0-day漏洞,影响到MySQL的所有版本(5.5、5.6和5.7)和所有分支(如Percona、MariaDB)。攻击者只需要FILE权限或Super权限即可实现ROOT提权,进而控制服务器。通过该漏洞,以ROOT权限执行代码,完全控制MySQL数据库所在的服务器,控制了服务器以后,就不光能脱库这么简单了。
由于该漏洞后果之严重,影响范围之广,已经搞得大家人人自危,惶惶不可終日。如果你还没有听说过这个漏洞,可能就要担心自己的数据是否还安全了。
2. 漏洞实施原理
该漏洞的危害虽然严重,但是原理却不复杂。为了让非技术人员也能理解,我尽量将复杂的问题简单来说:
- 首先,MySQL默认是以mysqld_safe脚本来启动数据库服务,并且,该脚本一般是用root用户来执行;
-
mysqld_safe脚本可以在命令行中指定
--malloc-lib
参数,与此同时,也可以将该参数的取值直接写到配置文件中;坏就坏在指定了
malloc-lib
参数时,mysqld_safe的处理方式上:- If
malloc-lib
is empty, do nothing and return - If
malloc-lib
is ‘tcmalloc’, look for tcmalloc shared library in /usr/lib - If
malloc-lib
is an absolute path, assume it is a malloc shared library
- If
- 攻击者如果具有FILE权限,先将自己的”恶意代码”编译完成以后,保存到被攻击的服务器上;
-
攻击者具有FILE权限,可以在数据库配置文件中(
my.cnf
)写入下面的配置;[mysqld] malloc_lib=/var/lib/mysql/mysql_hookandroot_lib.so ; 用户的"恶意代码"
将配置写入用户的配置文件其实非常简单,如下所示:
mysql> set global general_log_file = '/var/lib/mysql/my.cnf'; mysql> set global general_log = on; mysql> select ' '> '> ; injected config entry '> '> [mysqld] '> malloc_lib=/var/lib/mysql/mysql_hookandroot_lib.so '> '> [separator] '> '> '; 1 row in set (0.00 sec) mysql> set global general_log = off;
- 准备工作已经完成,当用户的数据库重启的时候(或者,攻击者有重启数据库的权限可以主动触发),就会去执行”恶意代码”;
- 恶意代码做一些清理工作,然后正常启动数据库,此外,还会fork一个子进程,启动一个
reverse shell
。完成以后,攻击者就能以root
用户登录了数据库所在的服务器,可以为所欲为。
3. 实施漏洞的重要条件
我们已经知道了漏洞的严重性和攻击的原理,那么,如何才能避免呢?
敏感的同学已经注意到,这个攻击有两个非常重要的条件:
- 数据库用户的权限
- 攻击者需要有数据库的账户和密码,数据库密码泄露时有爆出,所以,可以认为存在一定风险
- 攻击者需要有FILE权限,对于攻击者来说,这一点也不困难,有多少工程师没有按照规范对数据库账户授权,为了省事,直接对用户赋予所有权限
GRANT ALL PRIVILEGES ON *.* TO
- 此外,Super权限是被大家乱用最多的权限
- 再者,很多人没有意识到,如果一个数据库账户对
mysql.user
表具有修改权限,那么,他是可以通过修改这张表来增加自己的权限的
- 修改配置文件的权限
攻击者需要有配置文件的修改权限,这里有一点大家容易忽略的地方,在启动数据库的时候,如果没有通过
--defaults-file
显示地指定数据库的配置文件,那么,MySQL将会依次读取/etc/my.cnf
,/etc/mysql/my.cnf
,/usr/etc/my.cnf
,~/.my.cnf
,也就是说,只要启动mysql的用户,对这里的其中一个文件具有写权限就满足了攻击的第二个条件。
结论:这个漏洞不但危害大,影响范围广,而且,也容易实施,大多数MySQL都难以避免受到攻击。
4. 如何避免漏洞
前面说过,攻击的关键因素是“数据库账户权限”和“修改配置文件的权限”,也分析了为什么需要这两个关键因素。为了避免漏洞造成的损失,需要:
- 规范数据库账户的权限,不给账户赋予过多的权限;
- MySQL用户没有对任何配置文件的写权限;
- MySQL 5.7.15已经限制–malloc-lib参数的范围在系统目录,如/usr/lib, /usr/lib64,/usr/lib/i386-linux-gnu。并且,该参数只能在命令行指定,不能通过配置文件进行配置,可以一定程度上避免这个问题。
为了避免漏洞,只需要做好这两件事就行。虽然说起来简单,但是,实施起来还是有一定困难,这是因为:
- 并不是每位工程师都对MySQL了解得这么深入,知道这些注意事项;
- 权限规范固然是好,但是,为了规范也需要不少精力,而且,也免不了有疏忽的时候。
对于小公司来说,如果遇到问题只能等待官方修复后,升级数据库才得以彻底解决。然而,MySQL的官方修复或许并没有大家希望的那样迅速。据悉,此次漏洞需要10月份的版本才能彻底修复。因此,对于中小企业来说,不妨考虑把底层数据库交由专门的数据库服务公司来做,以便将更多精力集中在核心业务上。