En esta entrada la solución a uno de los retos de 'reverse' (ingeniería inversa) de la edición de 2018 de CyberOlympics, competición en modalidad 'on-line', estilo 'Capture the Flag' y formato 'Jeopardy', dirigida a centros educativos y organizada por el Instituto Nacional de Ciberseguridad (INCIBE) en el marco de la actividad llamada CyberCamp.Este desafío, en mi opinión, presenta un nivel de dificultad bajo (★★☆☆☆).
Enunciado: Un conocido fabricante de ATM (cajeros automáticos) quiere implantar un sistema de seguridad con clave de manera que, aunque un técnico malicioso obtenga el software, no pueda obtener la clave original. Como están tan seguros de que es imposible, nos han dado una copia del programa que realiza el filtro para que la auditemos. Debemos averiguar cuál es la contraseña válida que acepta el programa.
Enunciado: Un conocido fabricante de ATM (cajeros automáticos) quiere implantar un sistema de seguridad con clave de manera que, aunque un técnico malicioso obtenga el software, no pueda obtener la clave original. Como están tan seguros de que es imposible, nos han dado una copia del programa que realiza el filtro para que la auditemos. Debemos averiguar cuál es la contraseña válida que acepta el programa.
Recursos asociados al reto: archivo reto13.
Solución: lo primero que hago es ver de qué tipo es el archivo que se proporciona como recurso asociado al reto:
Lo ejecuto:
Y me indica que debo introducir una cadena como entrada, que supongo que es la contraseña que debo averiguar.
Introduzco cualquier cadena (por ejemplo: "password") y se muestra un mensaje diciendo que es invalida:
Desensamblo el ejecutable Linux con 'IDA' para realizar un análisis estático del código:Al
final de la función 'main' veo que se llama a ‘_memcmp’ en donde se comparan
los valores de los registros 'rsi' y 'rdi'. Entiendo que en uno de ellos se
encuentra la contraseña que he introducido ("password") y en el otro la que
debo averiguar; si el contenido de ambos registros es igual nos mostrará el
mensaje con la flag: “congratulations! flag{%s}\n” y si no son iguales nos
mostrará el mensaje “invalid password”.
Tras
este primer análisis estático de código, abro el ejecutable con el
desensamblador 'gdb', un depurador (en inglés, 'debugger') muy popular. La idea es poner un
punto de ruptura (en inglés, 'breakpoint') en la instrucción que llama a ‘_memcmp’ y, tras
ejecutarlo y cuando pare en el punto de ruptura, ver cuál es el contenido de
los registros 'rdi' y 'rsi'.
Desensamblo la función 'main': (gdb)
disas main
Pongo el punto de ruptura:
Examino el contenido de ambos registros ('rdi' y 'rsi'):Y, tras alguna pruebas, con la ayuda de una herramienta 'online' descubro que el contenido del registro 'rdi' se corresponde con el 'hash' md5 de la contraseña que he introducido ("password"):Por lo que el contenido del registro 'rsi' se corresponderá con el 'hash' md5 de la contraseña que tengo que averiguar. Intento “revertir” ese 'hash' md5 con la misma herramienta y lo consigo (la herramienta contiene en su BD ese 'hash' y, por tanto, sabe cuál es el texto en claro correspondiente al mismo):
Comentarios
Publicar un comentario