MySQL提权/条件竞争漏洞分析和利用(37)
预备知识
漏洞描述
CVE编号:CVE-2016-6663 / CVE-2016-5616 && CVE-2016-6664-5617
漏洞级别:严重
漏洞影响:漏洞影响:
MariaDB < 5.5.52
< 10.1.18
< 10.0.28
MySQL <= 5.5.51
<= 5.6.32
<= 5.7.14
Percona Server < 5.5.51-38.2
< 5.6.32-78-1
< 5.7.14-8
Percona XtraDB Cluster < 5.6.32-25.17
< 5.7.14-26.17
< 5.5.41-37.0
漏洞发现人:Dawid Golunski
Dawid Golunski在 MySQl, MariaDB 和 PerconaDB 数据库中发现条件竞争漏洞,该漏洞允许本地用户使用低权限(CREATE/INSERT/SELECT权限)账号提升权限到数据库系统用户(通常是'mysql')执行任意代码。成功利用此漏洞,允许攻击者完全访问数据库。也有潜在风险通过(CVE-2016-6662 和 CVE-2016-6664漏洞)获取操作系统root权限。
本实验环境所用软版本:MariaDB 10.0.22-1.el7.centos.x86_64
MariaDB:https://mariadb.org
项目地址:https://github.com/MariaDB
相关课程:
竞态条件漏洞实验主页-合天网安实验室 http://hetianlab.com//expc.do?ec=ECID9d6c0ca797abec2016081015344000001
Tomcat本地权限提升漏洞:http://hetianlab.com/expc.do?ce=ef30f608-6c82-4193-acd7-7c86495705f7
参考资料:
MySQL-Maria-Percona-PrivEscRace-CVE-2016-6663-5616-Exploit :http://legalhackers.com/advisories/MySQL-Maria-Percona-PrivEscRace-CVE-2016-6663-5616-Exploit.html
MySQL-Maria-Percona-RootPrivEsc-CVE-2016-6664-5617: http://legalhackers.com/advisories/MySQL-Maria-Percona-RootPrivEsc-CVE-2016-6664-5617-Exploit.html
firebroo's Blog:http://www.firebroo.com/categorys/23/articles/23.html
【漏洞预警】MySQL / MariaDB / PerconaDB - 提权/条件竞争漏洞-安全客 - 有思想的安全新媒体 http://bobao.360.cn/learning/detail/3152.html
实验目的
1)漏洞复现
2)漏洞形成分析
3)漏洞修复建议
实验环境
操作系统: Centos 7 1511
网络拓扑见下图:
IP随机
实验步骤一
漏洞复现
环境准备:
启动数据库:systemctl start mysql
创建普通权限的mysql账号:attacker
//红色为命令
mysql -uroot
MariaDB [(none)]> create database attacker;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> insert into mysql.user(Host,User,Password)values("localhost","attacker",password("attacker"));
Query OK, 1 row affected, 4 warnings (0.00 sec)
MariaDB [(none)]> grant create,select,update,insert,delete,drop on attacker.* to attacker@localhost identified by 'attacker';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
A
MariaDB [(none)]> quit
1)漏洞复现/提权普通用户至为mysql
新建一个 /data/目录,给予777权限,用做数据库文件存储目录
新建attacker用户
切换到 attacker 用户
su attacker
默认情况下当前attacker用户是无法操作mysql的
下载攻击代码:
编译:
gcc mysql-privesc-race.c -o mysql-privesc-race `mysql_config --cflags --libs`
执行:
./mysql-privesc-race
按照提示加上mysql用户名,主机,密码和数据库等
进入条件竞争,等待完成:
时间根据系统不同所需时间不同,1分钟到10分钟不等。去喝杯茶,耐心等待一会儿。
………………………………….
经过较长时间的等待,可以得到一个shell:
查看一下当前的用户ID
已经变身为mysql用户了,之前没权限操作的事情,现在可以操作了
2)提权到系统root权限
利用CVE-2016-6664/CVE-2016-5617提取到root。主要利用符号链接攻击提权
查看mysql错误日志文件目录
切换到/tmp目录,因为现在是mysql,对当前目录(/home/attacker)无权限
下载poc.sh 文件
提权成功如下:
实验步骤二
漏洞形成分析
1)CVE-2016-6663 / CVE-2016-5616漏洞形成分析
基于Mysql的数据库允许用户在建表的时候指定存储目录。
示例如下:
PS:为了跟踪系统调用,以下步骤均在root用户下进行,如果你不跟踪系统调用,在普通用户下亦可操作
新建 /data/diskptable ,给予这个目录 777 权限
然后建表的时候可以通过data directory参数指定存储目录
//PS:之前获取root权限杀死了mysql进程,可能需要重启服务
systemctl restart mysql
mysql -uattacker -pattacker
MariaDB [(none)]> use attacker;
MariaDB [attacker]> CREATE TABLE poctab1 (txt varchar(50)) engine = 'MyISAM' data directory '/data/disktable';
MariaDB [attacker]> commit;
MariaDB [attacker]> quit
执行之后发现 目录权限已经变成mysql了。
低权限(SELECT/CREATE/INSERT权限)的MYSQL账户,在执行表修复过程中,存在执行了不安全的临时文件创建。
为了方便查看,先开启一个系统调用跟踪 ,先用 ps -aux | grep mysql ,找到mysqld的pid,然后使用 strace -p pid -f 跟踪。
再次以attacker进入数据库执行表修复。
退出数据库,来看系统调用跟踪到的数据
用vim 打开 nohup.out文件查找 chmod (vim 打开之后,敲 /chmod ,回车)
(lstat函数类似于stat.但是当命名的文件是一个符号链接时,lstat返回该符号链接的有关信息,而不是由该符号链接引用文件的信息)
第一个系统调用是
我们可以看到,在检验poctab1.MYD表文件权限的时候,也会复制在创建repaired表时的临时文件chmod()权限。因此在
和
系统调用之间,产生了条件竞争漏洞。
因此如果删除临时表poctab1.TMD,然后通过符号链接在chmod()操作前替换/var/lib/mysql,则能够完全控制MYSQL的data目录权限。
攻击者可以预设poctab1.MYD权限为04777(suid),然后通过有漏洞的chmod()调用有效的复制一个bash shell来执行命令。这里会有一个问题,suid shell将只会保留攻击者的UID,而不是'mysql'用户。因此攻击者需要复制bash shell到mysql用户的表文件,然而mysql表文件又不具有写权限。
可以通过新建一个具有组粘帖位(group sticky bit)的目录来绕过这个限制
新建/data/disktable/目录,并赋予组粘帖位(group sticky bit)
再次新建一个表。
mysql -uattacker -pattacker
CREATE TABLE poctab2 (txt varchar(50)) engine = 'MyISAM' data directory '/data/disktable';
再次查看/data/disktable/下文件权限
我们可以看到poctab2.MYD表已经是'mysql'权限了,但是属于'root'组。这样'root'就能够复制/bin/bash到poctab2.MYD文件了。(PS:如果以上步骤在普通用户attacker下操作, poctab2.MYD会是'mysql'权限,但是属于'attacker'组。这样'attacker'就能够复制/bin/bash到poctab2.MYD文件了。)
2)CVE-2016-6664/CVE-2016-5617漏洞形成分析
通常情况下 mysql的错误日志是存储在 /var/log/mysql 或者 /var/lib/mysql目录下
权限是这个样子的:
mysqld_safe通常用于启动MySQL守护进程和创建/重新打开error.log执行某些不安全的文件操作,可能允许攻击者获得root权限。
mysqld_safe中有一个while循环用来监测mysql进程,并在进程失败的情况下执行重启进程。重启过程中,如果发现syslog没有配置记录错误日志文件,则会重新创建error log 文件。
可以看到使用touch创建文件,并且使用chown将文件所有者授权给了运行mysql进程的用户(通常这个用户是mysql),这个操作容易受到受到符号链接攻击。
在上一步中利用CVE-2016-6663我们已经获取到了mysql的权限,可以对mysql的错误日志进行操作,包括删除。和将其替换为指向任意系统文件的符号链接并升级权限。
无需等待 mysql service 重启,只需要通过mysql用户杀死由mysqld_safe创建的mysqld的子进程,就可以触发这个权限升级。
利用这些,当整个mysqld进程被终止,mysqld_safe将会执行while循环,并创建一个属于mysql用户的文件在攻击者指定的位置。(通过符号链接指向),而且还可以升级权限。
这一段C 代码,实现geteuid 函数,并且把 $BACKDOORPATH (也就是/tmp/mysqlrootsh)设置权限为04777 ,也就是设置S_ISUID标志位,然后编译成.so 文件保存到/tmp 目录下
然后把/bin/bash 复制到 /tmp/mysqlrootsh
删除mysql错误日志,并把文件/etc/ld.so.preload链接到错误日志文件
当mysqld_safe执行重新创建错误文件的时候,然后利用mysqld_safe修改文件属主为mysql 用户。再把之前编译的.so 文件路径写到/etc/ld.so.preload 文件里。preloading的库函数将有优先加载的权利。
当geteuid 函数执行的时候,/tmp/mysqlrootsh 的属主属组变成了root,权限就变成了04777。
/tmp/mysqlrootsh文件具有s 位了,也就是说,当该程序执行的时候,就可以具有root 权限,所以我们也就得到了root 权限。
实验步骤三
漏洞修复建议
1)通过各系统发布的升级补丁进行升级
2)临时解决办法