近期白帽黑客达吾德·古伦斯基连续发布了三个mysql的安全漏洞——cve-2016-6662、cve-2016-6663、cve-2016-6664,导致mysql和mysql的分支mariadb、percona server、percona xtradb cluster主流版本纷纷中招。这三个安全漏洞单看起来危害程度一般,不过一旦组合使用则威力大增,就算拥有的是操作系统低权限用户、数据库低权限用户的双低身份,也可以通过组合利用漏洞获取数据库服务器的全部控制权。
比如,cve-2016-6663和cve-2016-6664的组合利用,可以逐步获得数据库服务器的root权限;cve-2016-6662和cve-2016-6663的组合利用,同样可在低权限情况下获得root权限
如果我们想通过cve-2016-6662、cve-2016-6663这两个漏洞的组合获取数据库服务器的控制权限,我们需要对这两个漏洞的目标稍加分解:cve-2016-6662的目标是通过mysql权限拿到rootshell,cve-2016-6663的目标是通过低权限用户拿下mysqlshell。
若想通过cve-2016-6662拿到rootshell,需要满足两点:1. mysql权限下允许对my.cnf文件进行写操作。2.my.cnf的写入内容需要追加在后面。不考虑用户设置的权限发生错误这种情况,虽然my.cnf文件有多个,但基本都需要在root权限下方可允许进行读写操作,mysql权限下都无法改写my.cnf,唯一的特例是data目录下的my.cnf(尽管目前很多版本已经没有这个文件了,但mysql启动的时候还是会加载)。这一my.cnf的读写权限是mysql,且加载顺序靠后,里面的配置内容不会被轻易冲掉。
那么,如何在data目录下创建属于mysql权限的恶意my.cnf文件呢?方式有两种:
1.通过select '恶意配置内容' into outfile '/var/lib/mysql/my.cnf' 这种形式创建my.cnf。创建后my.cnf权限为666,但是mysql一旦检测到666权限则不会在启动中加载my.dnf文件。只有将my.cnf权限改造为660,才能完成启动中的文件加载。
2.采用改写log日志的方式追加
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;
这种方式可以直接解决上述方式中的666权限问题,但同时也带来了一个新问题,即该漏洞需要mysql的root权限,否则无权限执行set global general_log等对全局日志操作的语句。
由此可见,cve-2016-6662漏洞虽然可以获取root权限,但因为其可用范围太窄、限制太多,所以给大家一种很鸡肋的感觉。
但cve-2016-6662一旦与cve-2016-6663结合发力,则会焕发全部能量。cve-2016-6663扮演了一个松绑者的角色,可以帮助cve-2016-6662解除诸多限制。mysql在修表过程中,因为系统调用过程中未对赋值文件或目录权限做全面检查,导致低权限用户控制了mysqlshell,cve-2016-6663正好可利用这一点,让黑客有机可乘,黑客仅需要有一组低权限操作系统账号和一组可以创建表的低权限数据库账号即可。具体做法是:利用系统低权限账号创建一个文件目录,把该目录指定为数据库文件存储的目录,然后给这组目录赋予低权限账号的777权限,例如:
attacker@debian:~$ mkdir /tmp/disktable
attacker@debian:~$ chmod 777 /tmp/disktable/
接下来,低权限数据库用户创建表并修复表。
创建指定数据库文件置于刚才的文件夹下:
create table poctab1 (txt varchar(50)) engine = 'myisam' data directory '/tmp/disktable';
修复刚创建的表系统,会在不检查poctab1.myd表文件权限的情况下,直接调用复制在创建repaired表时的临时文件chmod()权限。在repaired的过程中系统调用进程 lstat("/tmp/disktable/poctab1.myd", {st_mode=s_ifreg|0660,st_size=0, ...}) = 0和chmod("/tmp/disktable/poctab1.tmd", 0660) = 0之间产生了条件竞争漏洞。此时攻击者只要删除临时表poctab1.tmd,然后通过符号链接在chmod()操作前替换/var/lib/mysql,就能够完全控制mysql的data目录权限。但此时拿到的只能是mysqlshell,而非mysql用户。接下来,通过chmod漏洞复制一份bash shell用以执行命令。此时shell的权限是mysql权限,也就是说至此低权限用户可以使用mysql权限执行命令。此时执行cve-2016-6662需要的mysql命令,则可以完成由mysqlshell向rootshell的提权。
cve-2016-6663和cve-2016-6662打出的这套组合拳使得低权限用户获得操作系统全部控制权成为可能。
针对此次cve-2016-6662、cve-2016-6663、cve-2016-6664的安全威胁,安华金和从专业角度提出了安全防护建议,很显然防范本次mysql漏洞组合拳攻击的最佳方案就是用户能第一时间对可能存在问题的数据库打补丁,但是鉴于生产系统以及场景的复杂多样性,对数据库进行及时的补丁修正并非易事,所以,可以尝试使用数据库防火墙来保护数据库。
大部分数据库防火墙擅长做sql语句级的安全防护工作,不过,这三个漏洞主要利用的是数据库文件的某些漏洞,所以大多数数据库防火墙无法有效应对这种情况。而安华金和的数据库防火墙因为具备了数据库外联防护功能,因此可以有效阻止这类漏洞所带来的风险。当黑客入侵后,拿到的只是操作系统的rootshell,而并非root账号,尽管黑客采用shell反射技术让数据库服务器的rootshell主动向自己的机器发起请求,但防火墙的数据库外联防护功能可以及时阻断异常tcp链接,阻止黑客远程获得数据库服务器的rootshell。
安华金和数据库防火墙的工作模式为:首先捕获数据库服务器向外发送的tcp链接,然后通过判断特征值和特定算法,对不符合预期的tcp链接确认后,直接给数据库服务器返回拒绝服务,阻止该次shell的反射,防止黑客盗取或偷窥数据库服务器上的敏感信息。同时数据库防火墙会通过短信、邮件等方式向主管人员提交此次攻击的行为特征、入侵者特征以及安全分析报告等信息。
试用申请