Personal information:

A Coruña, Galicia, Spain

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-

No hay comentarios:

Publicar un comentario