Taller Inyecciones SQL [Hacker_Zero]

Iniciado por $ad, Abril 14, 2010, 02:27:28 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Abril 14, 2010, 02:27:28 PM Ultima modificación: Noviembre 23, 2014, 12:25:44 PM por Expermicid
Taller Inyecciones SQL

Eres libre de distribuír ésta información siempre y cuando mantengas ésta cabecera.


Autor: Hacker_Zero
Fuente: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta


Éste documento ha sido realizado con fines exclusivamente didácticos. Todos los ejemplos aquí posteados se realizaron en un servidor previamente preparado por el autor. Ni la web ni el autor se responsabilizan de otros usos que otros usuarios le puedan dar.


Empezamos

¿Que es una inyección SQL?

Pues muy fácil, una inyección SQL nos permite modificar el comportamiento de las consultas a la base de datos permitiendonos acceder a datos no públicos o modificar la base de datos a nuestro antojo.

Muchas veces se habla de que ésta és una técnica complicada, que es necesario aprender SQL. Ésto es falso, podemos inyectar código de una forma totalmente mecánica sin entender el porqué del fallo, lo que lo hace en una técnica peligrosa, aunque también hay técnicas de inyección SQL avanzadas.

Un poco de teoría

Aunque podríamos limitarnos aprender un proceso y utilizarlo mecanicamente sin entender nada, limitarnos a éso sería echar a perder una buena técnica, así que analizaremos el porque de los ataques de inyección SQL. Para ésta misión utilizaremos una base de datos de pruebas donde podremos practicar a nuestras anchas:


No tienes permitido ver los links. Registrarse o Entrar a mi cuenta



1- Averiguando si es vulnerable

Empezaremos por el Ejercicio nº 1. En éste caso, la variable id está mal depurada, aquí el código vulnerable:


CÓDIGO
$user = $_GET['id'>;
(...)
$sql = mysql_query("SELECT * FROM `users` WHERE id=".$user) or die (mysql_error());



¿Como lo sabemos si no podemos ver el codigo fuente? Pues usaremos valores verdaderos y falso para ver como responde. Si ejecutamos:

CÓDIGO
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta


La consulta se realizara como:

CÓDIGO
SELECT * FROM `users` WHERE id=1 and 1=1


Y si ejecutamos:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

La consulta será:

CÓDIGO
SELECT * FROM `users` WHERE id=1 and 1=0


Como 1 no es igual a 0, en éste último caso la consulta no se realizará, por lo que no aparecen los datos de la base de datos en los campos de la web. Vale sabemos que es vulnerable, y ahora qué?

Tenemos que tener claro nuestro propósito, obtener información de la base de datos, en éste caso el nombre de usuario y contraseña del administrador. Como la podemos obtener? Pues lo que haremos será realizar una consulta en la variable vulnerable para que nos muestre los datos que queremos.


2- Averiguar el número de Columnas

Lo primero que tenemos que hacer es averiguar el número de columnas que tiene la tabla para poder hacer nosotros consultas, para eso se utiliza order by:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Como la tabla tiene más de 1 campo, se mostrará correctamente, seguimos:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Y así hasta llegar a 7, que se producirá un error:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Pues ya lo tenemos, tiene 6 campos, que fué él valor más alto que se mostró correctamente.


3- Haciendo nuestra consulta

Ahora que ya tenemos el número de columnas, 6, podemos hacer nuestra consulta:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Union: Se usa para combinar los resultados de varias sentencias SELECT.

Select: Nos permite consultar los datos almacenados en una tabla de la base de datos.

Luego ponemos las 6 columnas numerados del 1 al 6, lo que nos permitirá ver que campos se imprimen, los cuales nos permitirán a nosotros imprimir resultados. Vemos que los campos que se imprimen son 1,4,5,6. Que podemos hacer con ellos? Pues imprimir información, un ejemplo:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

version(): Devuelve la versión del servidor SQL.
database(): Devuelve el nombre de la base de datos.
user(): Devuelve el nombre de usuario conectado a la base de datos.
connection_id(): Devuelve el ID de una conexión. Cada conexión tiene su propio y único ID.

El 2 y el 3 no nos valen para imprimir resultados ya que no se muestran en pantalla.


4- Buscando nuestra tabla

Ahora que ya podemos imprimir lo que queramos en esos campos, buscaremos la tabla que contiene el usuario y contraseña de los usuarios. Para recorrer las tablas de una base de datos se utilizaremos lo siguiente:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Al ejecutar eso, nos mostrará el nombre de una tabla, pero no es la que queremos. Para recorrer las tablas en busca de la tabla que nos interesa, aumentaremos progresivamente el limit. Por ejemplo para ver la siguiente tabla:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

y la siguiente:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Así continuamos hasta encontrar una que pueda contener lo que nosotros queremos, el usuario y contraseña del administrador. Traceamos hasta llegar al 17:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Users, ésa parece ser la tabla donde se guarda esos datos ( podría haberse llamado también admin, access, o cualquier nombre sospechoso).


5- Buscando nuestras columnas

Ahora que ya tenemos la tabla, sólo nos queda saber que datos imprimir. Nosotros queremos el nombre de usuario y la contraseña, pero tenemos que saber como se llaman esas columnas para poderlas imprimir. Tracear columnas es similar a tracear tablas, se usa lo siguiente:


No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
where+table_name=char(NombreDeLaTablaEnAscii)+and+column_name+like+char(37,64,37)
En NombreDeLaTablaEnAscii irá el nombre de la tabla en código ascii separado por comas, aquí podemos ver las conversiones, luego subo un programa para hacer ésto de una forma más cómoda.

La inyección quedaría así:


No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
information_schema.columns+where+table_name=char(117,115,101,114,115)+and+column_name+like+char(37,64,37)

Oh, pero no se muestra nada! Tranquilo, ahora tenemos que ir traceando. Vamos aumentando el valor de 64 porgresivamente e iremos viendo diferentes nombres de columnas. Probemos con 65:


No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
information_schema.columns+where+table_name=char(117,115,101,114,115)+and+column_name+like+char(37,65,37)

Ah bien ya tenemos una de las columnas que buscabamos la que guarda el pass! Vale pues ahora a por la otra, la del usuario, seguimos traceando:

El 67 no nos muestra nada, el 68 nos muestra id que no nos interesa... 69 lo tenemos!


6- Imprimiendo los datos

Ya tenemos todo! Sabemos que tenemos que leer la columna Pass y la columna nombre de la tabla users, pues vamos a armar la inyección:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Bien ya está! Tenemos el nombre de usuario y contraseña del administrador! Bueno, pues aprovechamos que tenemos todo y sacamos la de otro user:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Ahí mandamos imprimir el nomre y pass de la tabla users donde el id es 2, el id del Admin suele ser 1, como es el primero se puede omitir y lo imprime igual.

Como sería para los demás users? Pues igual, solo cambiando el id.

Pues ésto fue todo por hoy, lo dejamos aquí de momento, aunque pronto actualizaré el post para poner más información de algunos comandos que hoy pasé así muy rápido.

Y aprovechad No tienes permitido ver los links. Registrarse o Entrar a mi cuenta para hacer pruebas, intentad sacar los users y pass vosotros solos, o provado cosas para ir cogiendo soltura.



ACTUALIZACIÓN

Bueno, pues el otro día Krackwar me presentó una función que desconocía ( De ese 99% que desconozco, xD): group_concat()

¿Para que sirve ésta función?

Bueno, algunos habréis tenido problemas o os lió algo lo de buscar tablas y columnas con el método anterior, o simplemente os parecía muy largo el proceso, bueno, y si pudieramos imprimir todas las tablas y columnas con una única sentencia? Ahí entra group_concat(), concadena miembros de un grupo como puede ser el nombre de las tablas y el nombre de las columnas, mejor con un ejemplo no? xD:

Para las tablas:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
2,3,4,5,6+from+information_schema.tables

Y para las columnas:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
2,3,4,5,6+from+information_schema.columns+where+table_name=char(117,115,101,114,115)



Ejercicio nº 2

Bueno pues para continuar el taller explicando otro tipo de inyección, me ayudaré del ejercicio 2 del servidor de pruebas de No tienes permitido ver los links. Registrarse o Entrar a mi cuenta . En éste ejercicio lo más interesante es entender la inyección.

-El código vulnerable

[code=sql>SELECT nombre FROM users Where nombre='$login' and Pass='$pass'[/code>

Nos deja pasar si al comprobar en la tabla users el nombre se corresponde con la contraseña. Nuestro objetivo es tener acceso sin saber el pass, podríamos modificar de alguna forma esa sentencia para que nos dejara pasar? Pues si.

-Nuestra inyección

Si en el campo login introducimos ADMIN y en password escribimos por ejemplo: Zero' OR '1'='1 la sentencia quedaría:

[code=sql>SELECT nombre FROM users Where nombre='ADMIN' and Pass='Zero' OR '1'='1'[/code>

Nos deja pasar si al comprobar en la tabla users al nombre ADMIN le corresponde la contraseña Zero o si 1 es igual a 1

Como 1 es igual a 1, nos dejará pasar ;D. Hay muchas más posibilidades, lo único que hay que hacer es modificar la sentencia para que de true y nos deje pasar.


Mi blog: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta