Bad news: MySQL can dish out root access to cunning miscreants
Good news: Oracle sneaked some patches out
Updated Security holes in MySQL can be abused to gain remote root access on poorly configured servers, it emerged on Monday.
Patches to fix up the programming blunders were quietly released last week. The flaws are present in all default installations of MySQL 5.5, 5.6 and 5.7. Grab versions 5.5.52, 5.6.33 and 5.7.15 to avoid any trouble.
The bugs were discovered by Dawid Golunski, who says he reported them to MySQL overseer Oracle on July 29.
He found that you can misuse an SQL command to write arbitrary text to the open-source database's configuration files. He has published limited proof-of-concept code showing how to open a remote root shell on a vulnerable installation.
How is this possible? Bear in mind that MySQL is launched by a script file called
mysqld_safe (unless you're using an RPM distribution with systemd, and MySQL 5.7.6 or later). This script runs as root even if you tell MySQL to run as a non-root user. It reads from the database's configuration files for a setting called
malloc_lib and dynamically loads the shared library referenced by this setting.
So if you can upload a malicious library onto a server and then tamper with one of MySQL's config files so that
mysqld_safe loads that library, and thus injects evil code into the server, you can get remote code execution as root when the database is next started.
That's a lot of ifs. You can, via SQL, abuse the database variable
general_log_file to write to a configuration file thus:
set global general_log_file = '/etc/my.cnf'; set global general_log = on; select ' [mysqld] malloc_lib=/tmp/mysql_exploit_lib.so [seperator] '; set global general_log = off;
But that requires you to be able to run arbitrary SQL on the victim's machine, and with permission to set
general_log_file. One way to do this would be to exploit an SQL injection vulnerability in a web app script to upload a malicious .so library and then fiddle with the config file via the logging system. Again, the attacked web app would need permission to do that, and any sane environment would turn that off.
Also, the hijacked configuration file would have to be writeable for the MySQL server, but not world writeable or the database would reject it for security reasons. Alternatively, a new config file could be created by the logging system in one of the various file system locations MySQL looks in for its settings.
If a web app can use the FILE SQL command, and has an SQLi vulnerability, a hacker can exploit that hole to upload a trigger file so that at some point in the future, such as when an INSERT command completes, the trigger script kicks in and the
general_log_file trick can be performed as the MySQL root user. The trigger file would look something like this:
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;
In his proof-of-concept exploit code, Golunski notes:
This is a limited version of the PoC exploit. It only allows appending to existing mysql config files with weak permissions.
Full PoC will be released at a later date, and will show how attackers could exploit the vulnerability on default installations of MySQL on systems with no writable my.cnf config files available.
The upcoming advisory CVE-2016-6663 will also make the exploitation trivial for certain low-privileged attackers that do not have FILE privilege.
If a miscreant can execute arbitrary SQL commands on your database, you're already in a world of pain. However, if your web app's permissions aren't locked down, and the MySQL user can write to or create new configuration files for itself, an SQL injection vulnerability will rapidly turn into a remote root shell via Golunski's CVE-2016-6663 and CVE-2016-6662 bugs.
From last week's MySQL updates, it appears Oracle has sneakily addressed at least some of the bugs reported by Golunski, by sanity checking the location of the malloc shared library and preventing the database from generating .ini or .cnf configuration files:
For mysqld_safe, the argument to --malloc-lib now must be one of the directories /usr/lib, /usr/lib64, /usr/lib/i386-linux-gnu, or /usr/lib/x86_64-linux-gnu. In addition, the --mysqld and --mysqld-version options can be used only on the command line and not in an option file. (Bug #24464380)
It was possible to write log files ending with .ini or .cnf that later could be parsed as option files. The general query log and slow query log can no longer be written to a file ending with .ini or .cnf. (Bug #24388753)
“This specific type of vulnerability can be exploited in different ways, since the attacker only requires a file-system writing permission at some level," explained Mordechai Guri, chief science officer of endpoint security biz Morphisec.
“This is considered to be an easy task on the attacker’s part. It’s important to note that these semi-logic vulnerabilities won't go away and are proof that new approaches, like moving target defense, should be developed and deployed in many strata of the computer security stack – including operating systems, the SQL language, etc.”
Oracle did not respond to a request for comment. ®
This article was updated after publication to add links to the patched MySQL versions.