jueves, 19 de enero de 2012

Modificando los payloads de sqlmap

Hoy quiero escribir sobre algo que me ha resultado muy útil en algunas ocasiones. Se trata de la posibilidad de modificar los payloads de sqlmap. Seguro te estarás preguntando ¿Y para que quiero yo modificarlos? Bueno pues a veces sucede que algunos segmentos del payload como nombres de funciones, bases de datos o clausulas hacen match con una firma del IDS y te echan al agua la explotación. Pero claro como tu eres un ninja en SQL descubres al cabo de un rato una forma alternativa de inyección que se salta el IDS :D Lo único malo es que deberás hacer todo el trabajo manualmente porque no hay ninguna herramienta que utilice esa forma de inyectar o quiza debas programarte tu propia tool.

Bueno es en casos como el anterior donde la posibilidad de tunnear los payloads puede resultar muy útil. Y sqlmap nos da esa posibilidad.

Usando tampers

Esta opción esta descrita en la documentación de sqlmap. Se trata de programar una función en python que recibe el payload original por parámetro y lo devuelve modificado.

Por ejemplo:

#!/usr/bin/env python

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def tamper(payload):  
 return payload.replace("UNION ALL SELECT", "/*!UNION*/SELECT")

El sencillo tamper del ejemplo serviría para evadir algunas firmas que detectan inyecciones por UNION en MySQL.

Para usar este tamper con nuestro sqlmap, debemos guardarlo en un fichero con el nombre, por ejemplo, "unionbypass.py". Y luego indicar la ruta hacia nuestro fichero en el parámetro "--tamper" cuando ejecutemos sqlmap. Así:

$ ./sqlmap.py --url="http://vulnerable.com/?id=23" --tamper="/home/user/unionbypass.py" --dbs

Sqlmap ya trae algunos tampers funcionales que podemos usar para cosas como: reemplazar espacios por comentarios, alternar mayúsculas y minúsculas, incluir comentarios basura, etc. Estos tampers están en el directorio "tamper" dentro del directorio de sqlmap.

También es posible incluir más de un tamper a la vez.

$ ./sqlmap.py --url="http://vulnerable.com/?id=23" --tamper="tamper/space2comment.py, tamper/randomcase.py" --dbs

Editando queries.xml

Otra forma, quizá menos aconsejable, de tunnear los payloads de sqlmap es editando el fichero "queries.xml" que está dentro del directorio "xml" de sqlmap.

En este fichero se definen las funciones que utilizará sqlmap para cosas como: hacer casting a char, validar si es nulo, obtener la longitud de una cadena y otras tantas que se usan en una inyección.

Así que si conocemos alguna función que logra el mismo resultado que las empleadas allí podemos probar sustituyéndola.

Por ejemplo, podemos reemplazar "CAST" por "CONVERT"

ANTES:
<cast query="CAST(%s AS CHAR(10000))"/>

DESPUES:
<cast query="CONVERT(%s , CHAR)"/>

Sin embargo los cambios que realicemos aquí no siempre darán buenos resultados. Personalmente he tenido problemas con algunas modificaciones que hice. Por ejemplo al sustituir la función "IFNULL" de MySQL.

ANTES:
<isnull query="IFNULL(%s, ' ')"/>

DESPUES:
<isnull query="(SELECT(x)FROM(SELECT(@a:=%s),IF((@a)IS/**/NULL,0x20,@a)x)y)"/>

Debería funcionar pero no lo hace :/

Bueno, es todo por ahora.

Saludos...

6 comentarios:

  1. el internet se va a la mier....maldito SOPA. bye megaupload.... T_T ...snif...snif...me siento muy triste, como si mi disco duro se hubiera malogrado y hubiera perdido todo mmi informacion...snif...snif. LIBERTAD!!!!!!

    ResponderEliminar
  2. hOLA t saluda jUl¡0 , muy b/**/ uen tuto y mejor aun el analisis... tu si bro... como dirian en el laburo tu si la haces. mUY ENTENDIBLE , un super example , y no dejas nada a medias..
    Weno vro. como com3ntab4 , vengo de un manejador de base de datos de alto nivel jejejej y de pago y rojo , osea oracle XD weno, consulta , ke kiere decir esto en mySq|
    (SELECT(x)FROM(SELECT(@a:=%s),IF((@a)IS/**/NULL,0x20,@a)x)y) ---esto no es un := una asignacion...weno weno aver si nos explicas a ke se refiere jejeje . 3x¡t0z.

    ResponderEliminar
  3. @Anónimo, A mi también me ha fastidiado el cierre de Megaupload, pero seguro que no tarda en aparecer otro sitio similar... la red es así ;)

    @julio, xD me pasé por alto explicar eso jejeje... bueno, toda esa expresión pretende hacer lo mismo que la función ifnull. ifnull es como el coalesce de Oracle. Ej:

    select ifnull(nombre, 'es nulo') from usuarios;

    Si "nombre" es nulo devolverá "es nulo", en caso contrario devolverá el valor de "nombre".

    Bueno ahora a lo otro:

    (SELECT(x)FROM(SELECT(@a:=%s),IF((@a)IS/**/NULL,0x20,@a)x)y)

    Lo ponemos de forma más legible

    (SELECT x FROM (SELECT @a:=%s, IF(@a IS NULL, 0x20, @a) x) y)

    La consulta externa extrae el campo "x" de la subconsulta identificada como "y". Vemos la subconsulta:

    (SELECT @a:=%s, IF(@a IS NULL, 0x20, @a) x)

    Se seleccionan 2 campos, el primero define la variable @a asignándole el valor "%s" esa expresión (%s) será reemplazada por sqlmap luego para testear un valor cualquiera.

    El segundo campo es un IF que devolverá 0x20 si @a es nulo o el valor de @a en caso contrario. 0x20 es un espacio en blanco codificado en hexadecimal. Al segundo campo se le asocia un alias "x".

    Bueno con todo eso se consigue imitar la funcionalidad de IFNULL :)

    Saludos.

    ResponderEliminar
    Respuestas
    1. tenia unos videos nopor en Megaupload que fastidio. Nose como hare para recuperarlos, crees q me devuelvan?

      Eliminar
  4. Muy buena explicacion , bueno el coalesce en oracle devuelve el primer valor nulo de una lista de valores... y en oracle tenemos el nvl(campo1,'esnulo')
    o el nvl2 apartir de versiones 10 o superiores el nvl2(campo1,'noesnulo','siesnulo'), muy explicado vro... como comente el manejador rojo y de pago tiene lo suyo... jejejejej

    valla ke con el Mysql hay que hacer funcion propia-- weno weno. exitos vro.
    haPLaM0s.

    ResponderEliminar
    Respuestas
    1. Buen dato lo del nvl, no conocía esa función. Yo usaba coalesce para conseguir el mismo efecto.

      En MySQL no es que haya que hacer tu propia función "nvl", para eso está "ifnull". Sino que la cadena "ifnull" es detectada por algunos IDS, así que con un par de selects puedes imitar la misma funcionalidad.

      Saludos.

      Eliminar