Hacker News new | past | comments | ask | show | jobs | submit login
MySQL Remote Root Code Execution/Privilege Escalation Exploit (legalhackers.com)
149 points by dawid_golunski on Sept 12, 2016 | hide | past | favorite | 48 comments

I think this is poorly framed as RCE when it's just privilege escalation. The user already needs MySQL login access, shell access, and the ability to upload a malicious library that can be added to LD_PRELOAD through a setting in my.cnf. They do propose a trick to overwrite my.cnf with a logging function, but still...

This doesn't seem very threatening at all. If you're not already running services with strict file permissions this is the least of your worries.

edit: appears shell access isn't required to upload the malicious library, but you still need valid MySQL creds. Just because a SQLi might be there doesn't mean you can upgrade this to "remote code execution". That's just chaining vulns together; it doesn't magically upgrade the severity of this.

You're arguing authenticated vs unauthenticated remote code execution.

Given MySQL creds and a (fairly common) file write primitive (file upload functionality, log injection, etc) that in itself should not qualify as a vulnerability, you can execute remote code on the server with just this vulnerability.

I think RCE is a fair description here.

Giving FILE permissions to MySQL users is "fairly common"? Google it and you'll find that the first page of results are all about people complaining that their piece of software did not grant them such permissions by default. Hence, I totally challenge your assertion.

This is an important issue to consider, but it has been WAY overblown as presented here.

To be perferctly clear: if you are running mysql in your production stack, you are most likely NOT affected by this whole ordeal at all. Now, with the initial panick blown off, please read the article and assess wether you are one of the few affected users out there or not (in short: only worry if you have regular users with the FILE privilege enabled).

Spreading FUD doesn't help anybody...

> Giving FILE permissions to MySQL users is "fairly common"?

When... did I say that? I said: a file write primitive on a server is fairly common. e.g. a PHP web app that lets you upload a file to some directory on the server. An attacker could use such a feature to upload a .so file to load into mysqld.

I'm just arguing that the title of RCE is accurate here. In a non-trivial amount of configurations you can abuse this vulnerability to remotely compromise a machine you otherwise couldn't get a shell on. Hence RCE.

If you read it, you'd find you need to be either admin on mysql already(and that's a bad thing), or have FILE permission on mysql. It's not about file upload primitive, the exploit is very specifically about the FILE permission on MYSQL allowing the user to add a new trigger as "root".

I certainly did read the writeup. Did you read my comments? I'm not sure what exactly you're disagreeing with.

I can see this leading to RCE in a number of scenarios:

- default/abandoned mysql install with default root creds. If you also have a file write primitive on the server (which IS common in LAMP stacks), now you can get RCE with it.

- mysql install with weak superuser creds that you've bruteforced. If you also have a file write primitive on the server (which IS common in LAMP stacks), now you can get RCE with it.

- db superuser uses the same db password as the app's connection. If you also have a file write primitive on the server (which IS common in LAMP stacks), now you can get RCE with it.

Are these super-common scenarios? No, but they are most certainly out there. Yes, you can say "this obvious mitigation would have prevented it", but that doesn't change the facts. You can abuse this in some set of circumstances to get RCE, so "RCE" is an accurate label, and THAT'S ALL I'M SAYING.

No, it is not. That's just the third of three ways that it gives in which one can arrange to inject the malicious shared library into the server process. The first and second ways do not involve FILE privilege, nor OUTFILE/DUMPFILE.

The first way involves setting "global general_log_file", which requires SUPER, which is frankly worse having FILE. The second way ALSO involves "global general_log_file", but is incomplete because "One problem will remain however. MySQL will refuse files that do not start with a valid [section] header with the message:" It's stated that there is a workaround, but this still requires SUPER. So yeah, you may not need FILE, you just need SUPER instead, but if you are running a webapp with a mysql user that has SUPER, you are still doing it all wrong...

For shared hosting providers, or any configuration where mysql access control is actually used for anything, this appears fairly critical. Especially for the upcoming PoC that doesn't need /etc/mysql/my.cnf to be writable.

It also means that an SQLi vulnerability suddenly becomes a potential remote root shell.

If a shared hosting provider is giving you FILE permission, you should close your account and leave, cause they don't understand trivial basics of database security.

i agree with that .. this isn't remote at all.

The point is that it is exploitable from SQL, therefore is also exploitable from the application that is creating the database.

This would be a target for a sql injection exploit and so is remotely exploitable

That requires your application to be vulnerable to two types of exploit in order to pull off RCE - if you are vulnerable to SQLi there are likely a whole raft of other issues which would give you a remote shell.

As a standalone issue I agree with the GP comment - this bug is not a RCE issue, it's privilege escalation.

I'm sorry I disagree , you're assuming that the "application" is vulnerable to sql injection and others.

Not everyone limits mysql to just localhost.

Some setups serve mysql over tcp/ip, sometimes even on the internet. Maybe you wouldn't trust mysql's ssl usage or username/password auth mechanisms, but they are there, and some people use those features. So this should certainly be considered a remote vulnerability, as long as the exploit can be launched from the client side of a mysql connection.

maybe a sql injection ....and escalate from there..

EDIT: HN formatting isn't letting me write "asterix dot asterix", it shows up as "." :(

My reading of this is that it requires either mysql root or `GRANT FILE ON . TO ...` privileges? AFAICT this requires an explicit `GRANT FILE ON . TO ...`; just plain `GRANT ALL ON db.* TO ...` does NOT grant any FILE privileges. I assume an install that doesn't give any users FILE privileges is safe?

mysql> SELECT host, user, File_priv FROM mysql.user WHERE File_priv='Y';

AFAICT exploit chain:

* `GRANT FILE ON . TO ...`

* `SELECT unhex("%s") INTO DUMPFILE '%s'`

* ... clever tricks ...

* mysql root

* ... clever tricks ...

* service mysql restart

* system root

The mysql security model for FILE privileges described here seems ridiculous. Your security model relies on creating dumpfiles with `chmod 666` permissions, and rejecting config files that are world-writeable? "I fixed the security issue with world-writable dump files" "You just broken our security model!"

Never grant FILE privileges on a production mysql server?

Hint: try it as a text after a blank line with two spaces preceding it. https://news.ycombinator.com/formatdoc

Then you can write

(How to find out? Google.)

Summary: people that can run queries on your MySQL server, either by legit access (shared webhosting or something else) or via an SQL-injection vulnerability, can execute commands that might root your server.

Vendor response:

> No official patches or mitigations are available at this time from [Oracle].

> The vulnerabilities were patched by PerconaDB and MariaDB vendors by the end of 30th of August.

Looking at the PoC, it seems possible to overwrite any file that the MySQL user (or whichever user MySQL runs as) can write to.

In the PoC, they overwrite /etc/my.cnf, which is often advised to be chown'ed to mysql, making this possible (normally files in /etc are only root-writable). The new version loads a malicious shared library. This means that you should have made the mistake of making it mysql-writable (on top of others having SQL access to the server in the first place). This is not the case on my Ubuntu 14.04 LTS server, so anyone running that without weird modifications is probably safe as well.

Some wrapper script is mentioned which runs as root (while mysql itself runs as a separate user), which would apparently make it possible to get root on the server. I guess that's another requirement for real impact, but the first 2 compromise your MySQL server already so that's serious enough.

Edit: Updated post according to comment from jstanley. Thanks!

The more correct summary is:

> People that can run queries on your MySQL as a user that has FILE privileges, either by legit access or via an SQL-injection vulnerability, can execute commands that might root your server.

This may seem nitpicky, but it makes a world of difference. For instance, none of the (many) shared hosting providers (godaddy et. al.) nor solutions (plesk, cpanel, etc.) I know of give FILE permissions to SQL users at all.

In fact, the shoddy way to create users is through the "GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'%'" command, which does not grant FILE privileges to that user.

Taking this into account, another possible summary is:

If you explicitly created mysql users with the FILE privilege or you are using the root user for day-to-day operations, you may get your server rooted. Stop doing that. Otherwise nothing to see for you here, just move on and install whatever security updates are issued by your distro-de-jour.

> This may seem nitpicky

Not at all. I was trying to figure out what it was about in a rush (I was leaving home, but RCE on MySQL was high prio for me) and while figuring it out, thought I might write it down for others. It's a lot of info left and right throughout the article, so I might not have put it together correctly. Thanks for the correction!

> 2) a malicious library has to be present on the system,

If you can overwrite any file the MySQL user can write, does that means you can place a malicious library on the system, or must it be loaded from somewhere in the ld search path?

Exploits dont have to have executable code on the system.

Causing it to try and load a random .so would probably crash the DB. Since this is in the config file, it would restart and immediately crash.

This would be an effective Denial of Service attack.

For 2) It looks like the PoC uploads the malicious library into the MySQL data dir through the same exploit

As for 3) I guess this just something to check for if you find SQL injection vulnerabilities in your application.

For FreeBSD users out there, I would seem that, in the default setting, the mysqld_safe script is being run as mysql uid by the rc startup script. So by the time mysqld_safe is invoked, root privileges are already dropped.

But that shouldn't dissuade one from taking some preventive measures, e.g. making sure that unnecessary FILE privileges are revoked from accounts and/or making sure that my.cnf is owned by root and only writable by root. Also, as the CVE mentions, do remember that a my.cnf in /var/db/mysql (or /var/lib/mysql for Linux) will override settings in other locations. Touching it as root with an appropriate flag mask should plug that hole too.

An updated mysql package will be soon be available of course.

So one can merely get shell access as the unprivileged server process user rather than as the superuser.

It's interesting to see how many people look at this and react "Whoa! Shell access!" or "Whoa! Malicious shared library injection!", and how few have commented on the fact (almost treated as a minor sideline) that one vector for the exploit involves setting up database triggers that run with SUPER privileges.

"Whoa! Attackers (with FILE privilege) can alter your purchase orders and invoices, steal your contacts and confidential customer account information, change inventory records, and forge identities." No shell access or shared libraries involved.

But that's been known as CVE-2012-5613 for some time. (-:

Hm, they say "patched by MariaDB by August 30" but I don't see anything possibly related here https://github.com/MariaDB/server/commits/10.1 nor in other releases/tags.

Here is the relevant ticket: https://jira.mariadb.org/browse/MDEV-10465

Thanks for linking this here, did somebody also find the relevant reference to the Percona equivalent of this one?

IMO, this can be avoided by following one simple operational hygiene concept:

Don't grant more permissions to an application than they absolutely need.

Exploiting this remotely requires the ability to change logging, an administrative command which should not be available to anything but your devops tools and your operation engineers. It also requires the write bit to be set on a configuration file; MySQL does not need to be able to write to its configuration file to run. Again, the only thing writing to the file should be your devops tooling.

Follow this simple idea, and you'll avoid a lot of CVEs.

As for the LD_PRELOAD vulnerability, this has been fairly well known for many years (I watched a colleague demonstrate this at a MySQL conference back in 2013), and it affects quite a few more programs than just MySQL.

You are missing a subtlety by referring to "its configuration file" in the singular. Part of the problem is that there are multiple possible configuration files, at least one set of which normally does not exist and lives in the MySQL data directory which is writable by the unprivileged server user.

An additional safeguard against this exploit would be using the `secure_file_priv` option, which restricts the location that queries can write to.

According to the docs[0], this has been configured to '/var/lib/mysql-files' by default for most distribution packages since 5.7.6. Still worth updating though, in case CVE-2006-6663 bypasses that.

[0]: https://dev.mysql.com/doc/refman/5.7/en/server-system-variab...

A lot of people it seems are missing the fact that using SELECT ... INTO is merely one of three ways in which one can arrange to load the malicious shared library. The other two do not involve OUTFILE/DUMPFILE, and secure_file_priv does not apply to them.

While reading this, I couldn't help but wonder what SaaS vendors like AWS (RDS) do to protect themselves from inevitable RCE that provides a shell to an attacker. Sooner or later someone is going to get a shell. Do they use virtualization in a way where rooting a machine doesn't give much of a foothold into the network?

Probably RDS is just a layer over EC2, but I'm not holding my breath waiting Amazon disclose much information about their setup (I wouldn't).

For Postgres at least you are not the god-like DBA, so I just trust they have all bases covered (or at least more resources than I have for keeping everything safe).

If Debian is running mysqld_safe as root then that--alone--is a problem. As for the rest, they are just configuration mishaps being used with malicious intent. One could just as easily misconfigure similar services rendering similar results.

It's the running it that is the problem, not the running it as root. mysqld_safe is a Poor Man's Daemon Supervisor, written badly in shell script, as they always are. It demands running as root, because it has a configuration parameter of the user that the server program attempts to switch to and that it chown's various files to.

(Part of) the problem is that it is run at all. Don't be confused into thinking that this is a Debian problem, moreover, just because the problem happened to be demonstrated on Debian Linux. Debian isn't the only system still running mysqld_safe.

* http://jdebp.eu./Softwares/nosh/mariadb-and-mysql.html

You're right, running mysqld_safe is the problem. However, after a quick bit of further research, even Debian isn't running mysqld_safe anymore as they now default to systemd in version 8. So this isn't even a problem in that distribution unless you make it one.

Your research was too quick. (-:

Debian 8 packages up mysql 5.5 with only a van Smoorenburg rc script, no systemd units.

* https://packages.debian.org/en/jessie/arm64/mysql-server-5.5...

Debian 8 only has mysql 5.6 available through backports. That has a systemd service unit, written in 2014 by Akhil Mohan of Oracle. That service unit invokes mysqld_safe, though, in classic systemd House of Horror fashion.

* https://packages.debian.org/en/jessie-backports/arm64/mysql-...

* https://anonscm.debian.org/cgit/pkg-mysql/mysql-5.6.git/tree...

Apparently, Red Hat Enterprise Linux 7 has no systemd unit files for mysql 5.6, either, and still uses mysqld_safe.

* http://rpm.pbone.net/index.php3/stat/6/idpl/34647467/dir/red...

You're right, again, even though you linked arm64 file lists instead of amd64. The 5.6 backport does have that unit file, but the badly written one from Oracle. I guess you shouldn't use Debian (-:

Reading that CVE is very nostalgic, looks like a 90's era exploit.

Does it mean that we could finally get a shell to RDS? Would be interesting to tinker around.

No, RDS does not give users the SUPER or FILE privileges, which are required for this exploit.

The whole thing is a bit overblown, given that application users at any security-minded company won't have either of these two privileges either.

So yeah, that means roughly 80% percent of the sites on the internet will be affected, but not the 20% that employ competent, well staffed infosec teams. Good to know :)

Seriously though, almost every vulnerability that gets disclosed can have the "this is all overblown, and any security minded company won't have this problem", and yet we are all dealing with the long tail of malicious software and services hosted on vulnerable infrastructure...

You don't need a large specialized infosec team to know the following:

* Don't give SUPER or FILE privs to your application's mysql user

* Don't allow mysql to accept connections from the public internet

* Avoid SQL injection through use of bind variables

This is pretty elementary stuff, and just doing any 2 of the 3 above will prevent this exploit from being usable. (unless the attacker has SSH access to your hosts, but in that case, you should already consider your entire environment to be compromised.)

Does this affect any versions older than 5.5?

It clearly affects all versions <= 5.5.52, <= 5.6.33, <= 5.7.15

...Is anyone surprised?

Like, at all?

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact