Ir al contenido principal

Reversing (III): Solución Reto 3 Atenea Escuela

En este post explico la solución a uno de los retos de Atenea Escuela, el reto 3 de la categoría de 'reversing' referido al "Análisis dinámico de aplicaciones".

Atenea Escuela es una plataforma básica de desafíos de seguridad informática compuesta por diferentes retos para fomentar el aprendizaje de los usuarios menos entendidos en el campo de la seguridad.

Las soluciones se pueden ver en la propia plataforma y creo que es una muy buena forma de aprender sobre esta temática.

Mi valoración sobre la dificultad de este reto es: . En él nos dan un archivo ejecutable (reto3.exe) y nos piden contestar a dos preguntas:

1.- ¿Cuál es el valor correcto que hay que introducir para conseguir mostrar el mensaje de éxito?.

2.- ¿Cuánto vale el registro EAX y las banderas de acarreo, de cero y de signo?.

Solución: Ejecuto el archivo reto3.exe y se me pide que introduzca un número:
Introduzco un número cualquiera, por ejemplo: 1234, y se muestra un mensaje de error:
Como en el reto anterior sobre 'reversing' que puse en este blog, utilizo OllyDbg y procedo de la misma forma que en el citado reto, aunque ya adelanto que en esta ocasión no será suficiente con hacerlo de esa manera.

Abro en esa herramienta el archivo ejecutable (reto3.exe) y, en la parte superior izquierda de la ventana principal (donde se muestra el código en ensamblador), busco todas las cadenas de texto o 'strings' utilizadas en el programa (clic botón derecho, 'Search for' > 'All referenced strings'):
obtengo lo siguiente:
Como se observa en la figura anterior, entre las cadenas de texto está el mensaje de error que me ha aparecido al ejecutar el programa: "Valor incorrecto! :("y también el mensaje que supuestamente aparecerá si introduzco el número correcto"Valor correcto!". Si hago doble clic sobre este último voy a la parte del código donde se encuentra esta cadena de texto:
Dos líneas más arriba veo la instrucción TEST de ensamblador. Esta instrucción es en cierto sentido igual a CMP, pero no realiza una resta sino una operación AND entre dos operandos, en nuestro caso entre el contenido del registro EAX y el contenido del mismo registro EAX, por lo que sirve para comprobar si EAX es igual a cero, ya que sólo en ese caso la operación lógica AND de EAX consigo mismo será cero. Si EAX es cero se activa la flag Z, ya que esta flag o bandera se activa (se pone a 1) cuando se ejecuta una instrucción y su resultado es cero.

Pongo un punto de interrupción ('breakpoint') en esa instrucción TEST (clic botón derecho sobre ella, 'Breakpoint' > 'Toggle') para que cuando ejecute el programa en modo depuración ('debug mode') éste se detenga en dicha instrucción:
Y ahora ejecuto el programa en modo depuración:
En ese momento:
Se me pide que introduzca un número (incluyo 1234) y tras pulsar 'Enter' el programa se detiene en el punto de interrupción que he puesto antes:
Justo debajo de la parte de la ventana principal donde se muestra el código en ensamblador se ve el contenido del registro EAX, que es igual a cero.

Ahora, veo que ocurriría si ejecuto la siguiente línea de código:

La instrucción en esta línea es JZ (equivalente a JE), es decir, un salto condicional a la dirección indicada (en este caso 0x004014AF) si el resultado de la instrucción anterior es igual a cero (en nuestro caso si EAX es igual a cero) o, lo que es lo mismo, si la flag Z está activada (es igual a 1). En nuestro caso, como EAX es igual a cero, se produciría el salto a la dirección establecida. Como se ve en la figura anterior, tras el salto a la dirección indicada se mostraría el mensaje de error.

Al igual que en el reto anterior, para evitar que salte y conseguir que el flujo del programa se dirija al mensaje que aparecería si introdujera el número correcto, puedo modificar la instrucción JZ por su contraria (JNZ o JNE, salto condicional si el resultado de la instrucción anterior es diferente de cero - en nuestro caso si EAX es diferente de cero - o, lo que es lo mismo, si la flag Z no está activada - es igual a 0), de la siguiente manera:
Como se ve, ahora, como el contenido de EAX es igual a cero, no se producirá el salto a la dirección indicada y el programa continuará para mostrar el mensaje de éxito, aquel que aparecería si hubiera introducido el valor correcto:
Sin embargo no puedo dar una respuesta a la primera pregunta del reto, es decir, no conozco qué valor hay que introducir para que se muestre este mensaje, por lo que me temo que hay que analizar el código con mayor profundidad.

Reinicio la ejecución del programa en modo depuración ('Debug''Restart'):
Y, de la misma forma que anteriormente, vuelvo a posicionarme en el sitio del código donde aparece el mensaje que supuestamente se mostrará si introdujera el número correcto"Valor correcto!".
Coloco un punto de interrupción ('breakpoint') en  la dirección 0x401495. En la dirección anterior a esa se moverá el número que introduzca al registro EAX.
Ejecuto el programa en modo depuración, introduzco el número que se nos solicita (incluyo otra vez 1234) y tras pulsar 'Enter' el programa se detiene en el primer punto de interrupción, el que acabo de poner justo antes.

Efectivamente, tanto debajo de la parte de la ventana principal donde se muestra el código en ensamblador como en la parte superior derecha de dicha ventana principal, veo que el contenido del registro EAX es 0x4D2 en hexadecimal (1234 en decimal):
Ejecuto la siguiente instrucción y veo que la siguiente es una CALL a la dirección 0x401440.
Ejecuto la CALL, pero no con el botón que se muestra en la figura anterior, 'Step over (F8)', sino con el que se muestra en la figura siguiente, 'Step into (F7)'. La diferencia entre ambos es que mientras el primero ejecutaría todo el código de la CALL sin interrupción y continuaría en la siguiente línea después de ella, el segundo entrará en el código de la CALL y permitirá ejecutar sus instrucciones una a una.
En el código de la CALL, hasta la instrucción RETN de la dirección 0x401462, que es la última y devuelve el control a la instrucción siguiente a la CALL, veo que hay una instrucción JLE que provocará un salto condicional a la dirección indicada si el número que he introducido, 1234 en decimal (4D2 en hexadecimal), es menor o igual que 256 en decimal (100 en hexadecimal).
En nuestro caso, como el número que he introducido, 1234 en decimal, es mayor que 256 en decimal no se producirá el salto, y continuando con la ejecución veo que la instrucción JG que se encuentra después provocará un salto condicional a la dirección indicada si el número que he introducido, 1234 en decimal (4D2 en hexadecimal), es mayor que 666 en decimal (29A en hexadecimal).
En resumen: si el número introducido es menor o igual que 256 o dicho número es mayor que 666 se producirá un salto a la dirección 0x0040145C en la que se moverá 0 al registro EAX y, tras salir de la CALL, el programa mostrará el mensaje de error. Como nosotros hemos introducido 1234 en decimal, que es mayor que 666 en decimal, se visualizará dicho mensaje:
Por el contrario, si el número introducido es mayor que 256 y menor o igual que 666 se moverá 1 al registro EAX y, tras salir de la CALL, el programa mostrará el mensaje de éxito.
Por tanto la respuesta a la primera pregunta es que el número introducido tiene que estar comprendido entre 257 y 666, ambos inclusive, para que se muestre el mensaje de éxito, mientras que para contestar a la segunda pregunta nos fijamos en la parte superior derecha de la ventana principal de OllyDbg:
Es decir, la respuesta a la segunda pregunta es que el registro EAX tiene valor 1, la bandera de acarreo (C) tiene valor 1, la de cero (Z) tiene valor 0 y la de signo (S) tiene valor 1.

Comentarios

Entradas populares de este blog

Criptografía (I): cifrado Vigenère y criptoanálisis Kasiski

Hace unos días mi amigo Iñaki Regidor ( @Inaki_Regidor ), a quien dedico esta entrada :), compartió en las redes sociales un post titulado "Criptografía: el arte de esconder mensajes"  publicado en uno de los blogs de EiTB . En ese post se explican ciertos métodos clásicos para cifrar mensajes , entre ellos el cifrado de Vigenère , y , al final del mismo, se propone un reto consistente en descifrar un mensaje , lo que me ha animado a escribir este post sobre el método Kasiski  para atacar un cifrado polialfabético ( conociendo la clave descifrar el mensaje es muy fácil, pero lo que contaré en este post es la forma de hacerlo sin saberla ). El mensaje a descifrar es el siguiente: LNUDVMUYRMUDVLLPXAFZUEFAIOVWVMUOVMUEVMUEZCUDVSYWCIVCFGUCUNYCGALLGRCYTIJTRNNPJQOPJEMZITYLIAYYKRYEFDUDCAMAVRMZEAMBLEXPJCCQIEHPJTYXVNMLAEZTIMUOFRUFC Como ya he dicho el método de Vigenère es un sistema de sustitución polialfabético , lo que significa que, al contrario que en un sistema de

Criptografía (XXIII): cifrado de Hill (I)

En este post me propongo explicar de forma comprensible lo que he entendido sobre el cifrado de Hill , propuesto por el matemático Lester S. Hill , en 1929, y que se basa en emplear una matriz como clave  para cifrar un texto en claro y su inversa para descifrar el criptograma correspondiente . Hay tres cosas que me gustan de la criptografía clásica, además de que considero que ésta es muy didáctica a la hora de comprender los sistemas criptográficos modernos: la primera de ellas es que me "obliga" a repasar conceptos de matemáticas aprendidos hace mucho tiempo y, desgraciadamente, olvidados también hace demasiado tiempo, y, por consiguiente, que, como dice  Dani , amigo y coautor de este blog, me "obliga" a hacer "gimnasia mental"; la segunda es que, en la mayoría de las ocasiones, pueden cifrarse y descifrase los mensajes, e incluso realizarse el criptoanálisis de los criptogramas, sin más que un simple lápiz y papel, es decir, para mi es como un pasat

¿Qué significa el emblema de la profesión informática? (I)

Todas o muchas profesiones tienen un emblema que las representa simbólicamente y en el caso de la  informática: " es el establecido en la resolución de 11 de noviembre de 1977  para las titulaciones universitarias superiores de informática, y  está constituido por una figura representando en su parte central  un  núcleo toroidal de ferrita , atravesado por  hilos de lectura,  escritura e inhibición . El núcleo está rodeado por  dos ramas : una  de  laurel , como símbolo de recompensa, y la otra, de  olivo , como  símbolo de sabiduría. La  corona  será la  de la casa real  española,  y bajo el escudo se inscribirá el acrónimo de la organización. ". Veamos los diferentes elementos tomando como ejemplo el emblema del COIIE/EIIEO (Colegio Oficial de Ingenieros en Informática del País Vasco/ Euskadiko Informatikako Ingeniarien Elkargo Ofiziala ) . Pero no sólo el COIIE/EIIEO adopta el emblema establecido en dicha resolución, sino que éste se adopta también como im