面对0-day漏洞,你MySQL还好吗

1. 漏洞介绍

image_20160929111153.png-120.6kB

这两天,来自波兰的安全研究人员爆出了两个MySQL的0-day漏洞,影响到MySQL的所有版本(5.5、5.6和5.7)和所有分支(如Percona、MariaDB)。攻击者只需要FILE权限或Super权限即可实现ROOT提权,进而控制服务器。通过该漏洞,以ROOT权限执行代码,完全控制MySQL数据库所在的服务器,控制了服务器以后,就不光能脱库这么简单了。

由于该漏洞后果之严重,影响范围之广,已经搞得大家人人自危,惶惶不可終日。如果你还没有听说过这个漏洞,可能就要担心自己的数据是否还安全了。

2. 漏洞实施原理

该漏洞的危害虽然严重,但是原理却不复杂。为了让非技术人员也能理解,我尽量将复杂的问题简单来说:

  1. 首先,MySQL默认是以mysqld_safe脚本来启动数据库服务,并且,该脚本一般是用root用户来执行;
  2. 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
  3. 攻击者如果具有FILE权限,先将自己的”恶意代码”编译完成以后,保存到被攻击的服务器上;
  4. 攻击者具有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;
    
  5. 准备工作已经完成,当用户的数据库重启的时候(或者,攻击者有重启数据库的权限可以主动触发),就会去执行”恶意代码”;
  6. 恶意代码做一些清理工作,然后正常启动数据库,此外,还会fork一个子进程,启动一个reverse shell。完成以后,攻击者就能以root用户登录了数据库所在的服务器,可以为所欲为。

3. 实施漏洞的重要条件

我们已经知道了漏洞的严重性和攻击的原理,那么,如何才能避免呢?

敏感的同学已经注意到,这个攻击有两个非常重要的条件:

  • 数据库用户的权限
    1. 攻击者需要有数据库的账户和密码,数据库密码泄露时有爆出,所以,可以认为存在一定风险
    2. 攻击者需要有FILE权限,对于攻击者来说,这一点也不困难,有多少工程师没有按照规范对数据库账户授权,为了省事,直接对用户赋予所有权限GRANT ALL PRIVILEGES ON *.* TO
    3. 此外,Super权限是被大家乱用最多的权限
    4. 再者,很多人没有意识到,如果一个数据库账户对mysql.user表具有修改权限,那么,他是可以通过修改这张表来增加自己的权限的
  • 修改配置文件的权限 攻击者需要有配置文件的修改权限,这里有一点大家容易忽略的地方,在启动数据库的时候,如果没有通过--defaults-file显示地指定数据库的配置文件,那么,MySQL将会依次读取/etc/my.cnf, /etc/mysql/my.cnf, /usr/etc/my.cnf, ~/.my.cnf,也就是说,只要启动mysql的用户,对这里的其中一个文件具有写权限就满足了攻击的第二个条件。

结论:这个漏洞不但危害大,影响范围广,而且,也容易实施,大多数MySQL都难以避免受到攻击。

4. 如何避免漏洞

前面说过,攻击的关键因素是“数据库账户权限”和“修改配置文件的权限”,也分析了为什么需要这两个关键因素。为了避免漏洞造成的损失,需要:

  1. 规范数据库账户的权限,不给账户赋予过多的权限;
  2. MySQL用户没有对任何配置文件的写权限;
  3. MySQL 5.7.15已经限制–malloc-lib参数的范围在系统目录,如/usr/lib, /usr/lib64,/usr/lib/i386-linux-gnu。并且,该参数只能在命令行指定,不能通过配置文件进行配置,可以一定程度上避免这个问题。

为了避免漏洞,只需要做好这两件事就行。虽然说起来简单,但是,实施起来还是有一定困难,这是因为:

  1. 并不是每位工程师都对MySQL了解得这么深入,知道这些注意事项;
  2. 权限规范固然是好,但是,为了规范也需要不少精力,而且,也免不了有疏忽的时候。

对于小公司来说,如果遇到问题只能等待官方修复后,升级数据库才得以彻底解决。然而,MySQL的官方修复或许并没有大家希望的那样迅速。据悉,此次漏洞需要10月份的版本才能彻底修复。因此,对于中小企业来说,不妨考虑把底层数据库交由专门的数据库服务公司来做,以便将更多精力集中在核心业务上。

赖明星 /
Published under (CC) BY-NC-SA in categories 编程语言  tagged with MySQL  漏洞