miércoles, 12 de marzo de 2014

Un pequeño desafío

Pensaba dejar de escribir por un tiempo sobre desbordamiento de buffer por no ser cansino y dar un poco más de variedad a este blog.
Pero me ha llegado desde la cuenta de twitter de @brutelogic un interesante desafío.




Explotar un posible desbordamiento de buffer en un programa con tan pocas líneas. Parece que estas vulnerabilidades no son específicas de grandes y complejos programas. El diablo acecha en los más pequeños detalles.

Me sentí tentado a aceptar el reto y me puse la primera tarde que tuve un rato a estudiar esta vulnerabilidad. Compilé el programa y lo cargué con ollydbg (según el compilador de C que se esté usando la salida la salida puede ser distinta).
Tan pocas líneas de código... tan fácil de localizar  los punton de interrupción.
Coloquemos un punto de interrupción despúes de la función scanf y ejecutemos el programa.

La primera vez introducimos los siguientes datos: 1234 y la pila tiene estos valores:






Lo copiamos al portapapeles y lo guardamos con fichero de texto.




Repetimos la operación, esta vez con el valor 12345678 lo copiamos y guardamos otro fichero.


Con una pequeña manipulación cargamos cada resultado en una hoja excel que nos será muy util para comparar los resultados. Veamos los contenidos de ls pilas en ambas ejecuciones:



La parte superior de la pila (aunque en numeración corresponde a las direcciones más bajas) es igual en ambos lados (amarillo). A continuación viene el área donde se carga la cadena de caracteres. Vemos como al aumentar el número de caracteres estos van ocupando posiciones hacia abajo en la pila.
Un poquito más abajo encontramos un valor que tiene bastante pinta de ser la dirección de retorno usada por la instrucción RET un poco más adelante en el programa.



Ponemos otro punto de interrupción en esta instrucción y volvemos a ejecutar el programa. Esta introducimos la siguiente cadena: 123456789123456789
Ejecutamos hasta la instruccion RET  y analicemos la salida.



El primerar valor de la pila es 38373635. Este valor será el que la instruccion RET llevará al EIP. Y que se corresponde con la cadena ASCII 5678
Deberemos colocar en esa posición el valor que realmente deseamos que vaya al  EIP y habremos secuestrado el programa.


Al tratarse de una prueba de concepto no vamos a complicarnos demasiado. Llevaré el control a la instrucción: 00401052.

Justo antes de printf, así que tendremos una prueba visual de que hemos alterado el flujo de programa.


Debemos de introducir los siguientes datos: 1234567891234

Y a continuación el valor hexadecimal correspondiente a la dirección  deseada Para ello usaremos el teclado numérico e introduciremos estos valores en decimas. Antes de introducir cada valor deberemos mantener pulsada la tecla Alt y una vez introducido cada valor deberemos soltarla. Así:


{Alt}136   {Alt}255   {Alt}18   {Alt}00

Y ahí lo tenemos la proxima instrucción a ejecutar es la deseada, ejecutamos paso a paso (F7)  seguimos y nos vuelve a aparecer el mensaje


Esto demuestra que hemos sido capaces del alterar el flujo del programa.

Últimas observaciones. 


Todavía quedamos lejos de tener finalizado el exploit. Ahora deberíamos de intentar sacar partido de esta vulnerabilidad.
Una vía para conseguirlo es sobreescribir el texto "clear" que es usado en la invocación a la funcion system y sustituirlo por otro valor. Por ejemplo: cmd.exe



Pero esto ya requiere un poco más de paciencia  y se sale del objetivo de este breve post. 


No hay comentarios:

Publicar un comentario