Mostrando entradas con la etiqueta Hackin9. Mostrar todas las entradas
Mostrando entradas con la etiqueta Hackin9. Mostrar todas las entradas

martes, febrero 26, 2008

He pensado que II ...


¡Hola malignos!

Ya muchos habéis leido el hackeo que le han realizado a la web de Jazztel, así que creo que es momento para hablar un poco de ello. Un anonimo que prefiere "seguir en el economato" se había enterado de esto y le hizo un poco de análisis al sitio, así, como por jugar y eso, a ver que era lo que se escondía detrás de allí.

Tras mirar la web el sitio tenía XSS,SQL Injection, Blind SQL Injection, XSS, un cucharón, etc... Cuando he estado viendo la web no he podido evitar el ir a hacer una checklist del artículo de "He Pensado que..." y casi, casi están todas.

En fin, aquí os dejo algunas capturitas de los cucharones que ciruclan "por ahí", que tienen su gracia.

La "sam" o algo así

El administrador de discos...o algo así

El drivers_etc_hosts...o aglo así

En fin, será que no hay dinero para gastar en buenos técnicos y seguridad informática...

Ahora están "en ello", pero... ¿Lo harán bien o irán a las siguiente fases? ¿Descubrirán dónde tienen el SQL Injection y se dejarán los Blind SQL Injection? ¿Seguro que arreglan todo?

Saludos Malignos!

miércoles, enero 23, 2008

Time-Based Blind SQL Injection using Heavy Queries (Parte II de II)

***************************************************************************************
Artículo Publicado en la revista Hackin9 en Ene'08

- Time-Based Blind SQL Injection using Heavy Queries (I de II)
- Time-Based Blind SQL Injection using Heavy Queries (II de II)

***************************************************************************************

Time-Based Blind SQL Injection using heavy Queries

Sea como fuere, si en un ataque a ciegas se quiere saber si el valor ASCII de una determinada letra de un campo es mayor que un número estamos hablando de una condición no excesivamente pesada y se va a poder generar siempre una consulta más pesada que ella con facilidad. El objetivo del ataque es generar una consulta pesada que provoque un retardo de tiempos en la respuesta del motor de la base de datos que solo se ejecute sí y solo sí la condición que nos interesa vale TRUE. Esto implicaría que un retardo de tiempo es equivalente a un valor TRUE en la consulta ligera.

¿Cómo generar consultas pesadas?

La forma más sencilla de generar consultas pesadas es usar lo que más hace trabajar a las bases de datos, los productos cartesianos de tablas, es decir, unir una tabla con otra y con otra hasta generar una cantidad de registros tan grande que obliguen al servidor a consumir un tiempo medible en procesarlo. Para ello basta con conocer o averiguar o adivinar una tabla del sistema de bases de datos, que tenga algún registro, y unirla consigo misma hasta generar un tiempo medible. Vamos a ver algunos ejemplos.

Oracle

La siguente consulta, lanzada contra un servidor de pruebas, muestra en color azul la consulta pesada y en color roja la consulta de la que deseamos averiguar la respuesta. Lógicamente, en este caso, la respuesta ha de ser TRUE pues hemos utilizado el valor 300 que es mayor que cualquier valor ASCII:

http://blind.elladodelmal.com/oracle/pista.aspx?id_pista=1 and (select count(*) from all_users t1, all_users t2, all_users t3, all_users t4, all_users t5)>0 and 300>ascii(SUBSTR((select username from all_users where rownum = 1),1,1))

Lanzando esta consulta con la utilidad wget podemos ver una medición de tiempos:

Imagen: La consulta dura 22 segundos, luego la respuesta es VERDADERO.

Si forzamos que la segunda condición, la ligera, valga FALSO, en este caso preguntando si 0 es mayor que el valor ASCII de la primera letra, podremos comprobar cómo la consulta pesada no se ejecuta y el tiempo de respuesta es menor.

Imagen: La consulta dura 1 segundo, luego la respuesta es FALSO.

Como se puede ver en la consulta generada se ha utilizado 5 veces la vista all_users, pero esto no quiere decir que sea el número de tablas que deban utilizarse para todas las bases de datos Oracle, ya que el retardo de tiempo dependerá de la configuración del servidor y el número de registros que tenga la tabla. Lo que es absolutamente cierto es que se puede medir un retardo de tiempo y puede automatizarse este sistema.

Microsoft Access

Los motores Microsoft Access no tienen funciones de retardo de tiempo, pero las bases de datos Access tienen un pequeño diccionario de datos compuesto por una serie de tablas. En las versiones de Microsoft Access 97 y 2000 es posible acceder a la tabla MSysAccessObjects y las versiones 2003 y 2007 a la tabla MSysAccessStorage y generar, mediante uniones de estas tablas consultas pesadas que generen retardos de tiempos medibles. Por ejmplo, para una base de datos con Access 2003, podríamos ejecutar la siguiente consulta:

http://blind.access2007.foo/Blind3/pista.aspx?id_pista=1 and (SELECT count(*) from MSysAccessStorage t1, MSysAccessStorage t2, MSysAccessStorage t3, MSysAccessStorage t4, MSysAccessStorage t5, MSysAccessStorage t6) > 0 and exists (select * from contrasena)

En azul la consulta pesada y en rojo la consulta de la que queremos respuesta, es decir, si existe la tabla llamada “contrasena”. Como se puede ver en la captura realizada con la utilidad wget la consulta dura 39 segundos, luego, la consulta pesada, en este caso muy pesada para este entorno, se ha ejecutado por lo que el valor es VERDADERO, la tabla “contrasena” existe y tiene registros.

Imagen: La consulta dura 39 segundos, luego la respuesta es VERDADERO.

Para comprobarlo realizados la negación de la consulta ligera y medimos el tiempo de respuesta:

Imagen: La consulta dura menos de 1 segundo, luego la respuesta es FALSO.

MySQL

En las versiones 5.x de los motores MySQL es posible conocer a priori un montón de tablas de acceso, de la misma forma que sucede en todos los sistemas que tienen diccionarios de datos. En el caso de MySQL se pueden generar consultas pesadas utilizando cualquiera de las tablas de Information_schema, como por ejemplo la tabla columns.

http://blind.mysql5.foo/pista.aspx?id_pista=1 and exists (select * from contrasena) and 300 > (select count(*) from information_schema.columns, information_schema.columns T1, information_schema T2)

En azul la consulta pesada y en rojo la consulta de la que se desea una respuesta VERDADERA o FASLA.

En las versiones 4.x y anteriores la elección de la tabla debe ser conocida o adivinada ya que no comparten un catálogo que por defecto sea accesible desde fuera.

Microsoft SQL Server

Con los motores de bases de datos Microsoft SQL Server se cuenta con un diccionario de datos por cada base de datos y además un diccionario global del servidor mantenido en la base de datos master. Para generar una consulta pesada se puede intentar utilizar cualquier tabla de esas, como por ejemplo las tablas sysusers, sysobjects o syscolumns. El ejemplo siguiente muestra una consulta pesada para un motor Microsoft SQL Server 2000. De nuevo en azul la consulta pesada y en rojo la que buscamos respuesta:

http://blind.sqlserver2k.foo/blind2/pista.aspx?id_pista=1 and (SELECT count(*) FROM sysusers AS sys1, sysusers as sys2, sysusers as sys3, sysusers AS sys4, sysusers AS sys5, sysusers AS sys6, sysusers AS sys7, sysusers AS sys8)>0 and 100>(select top 1 ascii(substring(name,1,1)) from sysusers)

Otros motores de bases de datos

El método funciona de igual forma en otros motores de bases de datos. Al final la idea es sencilla, hacer trabajar el motor de base de datos usando técnicas de anti optimización. Como la explotación depende del entorno es necesario un proceso de ajuste de la consulta pesada para cada entorno y además, al ser basado en tiempos, hay que tener en cuenta las características del medio de transmisión. Siempre es recomendable realizar varias pruebas para comprobar que los resultados son correctos.

Contramedidas

Evitar estas técnicas es lo mismo que evitar las vulnerabilidades de SQL Injection. Para evitar que una aplicación sea vulnerable a ellas se han escrito y es fácil encontrar guías de precauciones a seguir y como hacerlo en cada lenguaje de programación en concreto. Sin embargo no me gustaría terminar sin recomendar el uso de las herramientas de Análisis Estático de Código. Estas herramientas son una ayuda más al ojo del programador a la hora de evitar vulnerabilidades en el código.

Lógicamente no son perfectas y se necesita de un programador experimentado y preparado para el desarrollo seguro de aplicaciones, pero sí son un apoyo más. Herramientas como Fxcop ayudan a detectar las vulnerabilidades mediante el análisis del código. Existen múltiples herramientas de este tipo y especializadas en distintos lenguajes.


Referencias

- OWASP Top 10. The Ten Most Critical Web Applications Security Vulnerabilities
- NT Web Technology Vulnerabilities
- Advanced SQL Injection
- (more) Advanced SQL Injection
- Blind SQL Injection Automation Techniques
- Blind XPath Injection
- Protección contra Blind SQL Injection
- Time-Based Blind SQL Injection using Heavy Queries

Herramientas

- SQLBftools
- SQLNinja
- Absinthee
- SQL PowerInjector

***************************************************************************************
Artículo Publicado en la revista Hackin9 en Ene'08

- Time-Based Blind SQL Injection using Heavy Queries (I de II)
- Time-Based Blind SQL Injection using Heavy Queries (II de II)

***************************************************************************************

martes, enero 22, 2008

Time-Based Blind SQL Injection using Heavy Queries (Parte I de II)

***************************************************************************************
Artículo Publicado en la revista Hackin9 en Ene'08

- Time-Based Blind SQL Injection using Heavy Queries (I de II)
- Time-Based Blind SQL Injection using Heavy Queries (II de II)

***************************************************************************************

SQL Injection

OWASP (The Open Web Application Security Project) ha publicado recientemente un documento en el que recoge las 10 vulnerabilidades se seguridad más críticas en Aplicaciones Web. En él, se recogen las vulnerabilidades que más siguen afectando y que siguen siendo “viejas conocidas” para el gran público. En primer lugar se encuentran los ataques Cross-Site Scripting, con todas sus variantes de ataques persistentes y no persistentes mientras que en segundo lugar quedan las inyecciones de código malicioso y especialmente las vulnerabilidades de SQL Injection. Sí, parece que fue ayer cuando se publicó en el año 1998 el primer documento que hablaba de la posibilidad de inyectar código SQL en consultas firmado, por el ya famoso, rain.forest.pupy y titulado “NT Web Technology Vulnerabilities”, pues bien, ya casi 8años se cumplen desde que se habló de esa posibilidad y a día de hoy sigue siendo una de las vulnerabilidades más peligrosas.

Blind SQL Injection

Es cierto que las formas de explotarlas han ido cambiando, en parte, por la fortificación de sistemas, que, aunque no evita la vulnerabilidad si dificulta su explotación. En el año 2002 Chrish Anley hace referencia en su documento “(more) Advanced SQL Injection” a la posibilidad de realizar ataques de inyección de código a ciegas y utilizando métodos tan curiosos, en aquel entonces, como forzar una parada de tiempos en las bases de datos SQL Server si se cumple una condición llamando a un procedimiento almacenado para ejecutar un Ping a localhost o llamando a la función waitfor de Microsoft SQL Server. Fue en ese momento cuando se puede decir que ven la luz las técnicas de explotación de vulnerabilidades de inyección de comandos SQL a ciegas. Es decir, Blind SQL Injection.

En el año 2004, Cameron Hotchkies, en las Blackhat Conferences, presentando la herramienta SQueal, que más tarde se convertiría en Absinthe, hablaba de los métodos de automatizar la extracción de información mediante ataques Blind SQL Injection. El documento publicado “Blind SQL Injeciton Automation Techniques” mostraba las diferentes posibilidades a la hora de conocer cuando una respuesta significa un valor positivo o negativo. Se echa de menos en el documento y también en la herramienta la posibilidad mostrada por Chrish Anley de usar retardos de tiempo en la automatización.

Imagen: Extracción de datos con Absinthe

Time-Based Blind SQL Injection

A las técnicas que automatizan la extracción de información a ciegas usando retardos de tiempo se las conoce como Time-Based Blind SQL Injection y han ido especializándose en diferentes tecnologías de bases de datos para generar retardos de tiempo. Así, por ejemplo, la herramienta SQL Ninja, utiliza el sistema de tiempos descrito por Chrish Anley en aplicaciones web que utilizan motores de base de datos Microsoft SQL Server. Otras herramientas como SQL Power Injector utilizan el sistema de inyectar funciones Benchmark que generan retardos en motores de bases de datos MySQL o inyectar la llamada a la función PL/SQL DBMS_LOCK.SLEEP(time) en sistemas con motores Oracle. Para otros sistemas de bases de datos como Access o DB2 no existe forma similar de generar retardos de tiempo. Los métodos de generar estos retardos de tiempo quedan por tanto restringidos bastante. En primer lugar para Access, DB2 y otros motores de bases de datos no se conoce ninguna forma; en segundo lugar, para hacerlo en motores Oracle se necesita acceso a una inyección PL/SQL que no es común encontrarse con un entorno que lo permita y, por último los sistemas de fortificación suelen tener en cuenta la restricción del uso de funciones Benchmark en entornos MySQL y waitfor en entornos Microsoft SQL Server.

En el presente artículo vamos a ver como poder realizar un ataque a ciegas usando inyecciones de código que generan retardos de tiempo utilizando consultas pesadas, es decir, Time-Based Blind SQL Injection with Heavy Queries.

“Booleanización”

El término “Booleanización” no es mío, la primera vez que lo leí fue en el documento “Blind XPath Injection” de Amit Klein y que desconozco si existía previamente o no, pero en el caso de que no existiera hay que crearlo. La idea consiste en como extraer un dato mediante una secuencia de condiciones booleanas que devuelve True o False. Por ejemplo, supongamos queremos extraer el valor del campo username de la vista all_users en un motor Oracle y este valor es “sys”. El proceso de “booleanización” sería el siguiente:

255>(Select ASCII(Substr(username,1,1)) from all_users where rownum<=1
-> True [255 > ASCII(‘s’)=115]

122>(Select ASCII(Substr(username,1,1)) from all_users where rownum<=1
-> True [122 > ASCII(‘s’)=115]

61>(Select ASCII(Substr(username,1,1)) from all_users where rownum<=1
-> False [61 < ASCII(‘s’)=115]

92>(Select ASCII(Substr(username,1,1)) from all_users where rownum<=1
-> False [92 < ASCII(‘s’)=115]

107>(Select ASCII(Substr(username,1,1)) from all_users where rownum<=1
-> False [107 < ASCII(‘s’)=115]

115>(Select ASCII(Substr(username,1,1)) from all_users where rownum<=1
-> False [115 = ASCII(‘s’)=115]

119>(Select ASCII(Substr(username,1,1)) from all_users where rownum<=1
-> True [119 < ASCII(‘s’)=115]

117>(Select ASCII(Substr(username,1,1)) from all_users where rownum<=1
-> True [117 < ASCII(‘s’)=115]

116>(Select ASCII(Substr(username,1,1)) from all_users where rownum<=1
-> True [116 < ASCII(‘s’)=115]

En este punto se ha averiguado que el valor ASCII de la primera letra del nombre es 115 ya que no es mayor que 115 y es menor que 116. Y se pasaría a realizar el mismo proceso con la segunda letra. Como se puede ver el proceso va a exigir una serie de repetición de peticiones para cada valor, pero al final se obtiene el resultado. El problema, como se explica al principio de este artículo, es determinar cuando la respuesta es True y cuando es False.

Time-Based Blind SQL Injection

Hasta el momento, lo sistemas que se conocían para extraer información estaban basados en las funciones que ofrecía cada motor de bases de datos, así, por ejemplo, en una aplicación web que utilice Microsoft SQL Server podría realizarse una inyección como la siguiente:

http://servidor/prog.cod?id=1; if (exists(select * from contrasena)) waitfor delay ‘0:0:5’--

Esta consulta, en el caso de existir la tabla “contrasena” y tener algún registro va a pausar la respuesta de la página web un tiempo de 5 segundos. Si la respuesta se obtiene en un periodo inferior podemos inferir que la tabla “contrasena” existe y tiene algún registro. La misma idea puede ser utilizada para una aplicación con Oracle:

http://servidor/prog.cod?id=1; begin if (condicion) then dbms_lock.sleep(5); end if; end;

Y con MySQL, usando por ejemplo la función Benchmark del ejemplo, que suele tardar unos 6 segundos en procesarse o la función Sleep(), que ya viene en las versiones 5 de MySQL.

http://servidor/prog.cod?id=1 and exists(select * from contrasena) and benchmark(5000000,md5(rand()))=0

http://servidor/prog.cod?id=1 and exists(select * from contrasena) and sleep(5)

Heavy Queries

Las consultas pesadas han sido y siguen siendo un quebradero de cabeza en la optimización de sistemas de bases de datos. Un motor puede almacenar cantidades de información tan grandes y con tal cantidad de usuarios que si no se optimizaran las bases de datos dejarían de ser útiles. Los ajustes de rendimiento son constantes en los grandes sistemas de bases de datos para conseguir mejorar los tiempos de respuesta. Con los años los motores de bases de datos se han ido evolucionando para que sean ellos los que optimicen las consultas que generan los programadores y no al revés como se hacía antaño, aunque hay algunos motores que siguen requiriendo del programador para optimizar una consulta. Es decir, supongamos una consulta Select como la siguiente:

Select campos from tablas where condición_1 and condición_2;

¿Con que orden evaluar las condiciones para que se ejecute esta consulta y el sistema lo más rápido posible? En este ejemplo, al utilizar una condición AND, si la primera condición que evaluamos da como resultado un valor FALSO el motor ya no tiene que evaluar la otra. Si hubiera sido un operador OR el funcionamiento hubiera sido al revés, es decir, si la primera da VERDADERO ya no hay que evaluar la segunda condición. La conclusión varía en cada motor de bases de datos. En algunos se establece una precedencia y se hace recaer la optimización sobre el programador. Es decir, se evalúan las condiciones de izquierda a derecha o de derecha a izquierda y es responsabilidad del programador elegir el orden de evaluación en función de la probabilidad de obtener el resultado en menos tiempo. Si por ejemplo se estima que en evaluar la condición_1 el motor tarda 6 segundos y en evaluar la condición_2 unos 2 segundos y el motor utiliza precedencia por la izquierda entonces habrá que situar a la izquierda la condición de menos tiempo. Para entenderlo vamos a ver la tabla de tiempos posibles:

Tabla con la condición_1 (la pesada) a la izquierda
Tabla con la condición_2 (la ligera) a la izquierda

Como se puede ver, en una probabilidad similarmente distribuida de que cada condición pueda tomar valores TRUE o FALSE, es más optimo evaluar siempre primero la consulta ligera. Esto puede cambiar en función de las densidades. Es decir, en una clausula Where con operador AND en la que la condición ligera tenga una probabilidad del 99 % de ser TRUE y la pesada una probabilidad del 5 % de ser TRUE puede ser más eficiente utilizar una precedencia distinta.

Motores como Microsoft SQL Server u Oracle implementan optimización de consultas en tiempo de ejecución. Es decir, analizar las condiciones que pone el programador y eligen el orden de ejecución “correcto” según su estimación. Para ello utilizar reglas básicas, avanzadas e incluso datos estadísticos de las tablas de la base de datos en concreto.

***************************************************************************************
Artículo Publicado en la revista Hackin9 en Ene'08

- Time-Based Blind SQL Injection using Heavy Queries (I de II)
- Time-Based Blind SQL Injection using Heavy Queries (II de II)

***************************************************************************************

lunes, enero 07, 2008

Articulando directorios

Una de las tareas que más disfruto es cuando estoy enredando con algo. El juguetear con cosas para ver que se puede o no se puede hacer es uno de las mejores ocupaciones que uno puede realizar.

Después de haber jugado una temporada con algo, a mi, que soy una cotorra, no me gusta callarme las cosas, así que lo cuento. Me gusta escribir sobre las cosas con las que juego y darle mil vuletas para poder sacarle todo el jugo. Eso ha hecho que este mes de Enero haya escrito un artículo para Windows TI Magazine sobre mis apiroladas y el OOXML, otro para Red Seguridad sobre como hacer el capullo dando una charla, otro para PCWorld sobre los riesgos en la mensajería instantanea y otro para la revista Hackin9 sobre Blind SQL Injection basado en tiempos usando consultas pesadas. Todo el día dale que te pego a "escribil y escribil". Además me ha dado tiempo a escribir el Proyecto del Postgrado que leeré el día 10 de Enero y a escribir un artículo para un congreso sobre lo que iba la fase 2 del Reto 5.

Sí, escribir mola, por eso suelo hacerlo aquí a diario, en el blog. El caso es, que como soy una cotorra, me gusta publicar en el blog los artículos que publico en las revistas, por lo que siempre les solicito que una vez que los hayan publicado ellos los publicaré yo.

Como de la revista Hackin9 me dan pocas señales de vida, pues he ido a la web a ver si encontraba mi artículo por allí y así lo publicaba por aquí.... Pero no. No lo he visto allí, aunque sí tego la certeza de que está publicado porque me enviaron la revista en la que sale [Enero del 2008].

El caso es que la revista tiene una sección para descargar artículos, pero obliga a suscribirse a la newsletter y, cuando salga dicha newsletter se supone que recibirás algún artículo enlazado, pero no el que querías en concreto.

Buscando artículos había encontrado uno de XPath Injection que quería leerme, ya que estoy preparando una cosa y cualquier información sobre ese tema me viene bien, así que me he suscrito, pero no lo he podido descargar. Sin embargo "no se como" buscando, buscando por los links he llegado a este directorio... dónde están todos los artículos que han sido publicados en las newsletters.

Vale, el artículo en cuestión que yo quería es éste: "Introducción a las técnicas de Xpath Injection". Si estás empezando con el tema, léelo, está chulo, pero tienes una lista completa de otos artículos en el mismo directorio... en muchos idiomas.

Es de agradecer que Hackin9 publique los pdfs de los artículos, pero podría ser un interfaz más amigable que el simple listado de directorio abierto en Apache, ¿no?

Centro de descarga de artículos Hackin9

Saludos Malignos!

Entrada destacada

+300 referencias a papers, posts y talks de Hacking & Security con Inteligencia Artificial

Hace un mes comencé a recuperar en un post mi interés en los últimos años, donde he publicado muchos artículos en este blog , y he dejado mu...

Entradas populares