=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Reto Panda – Prueba #3 – SOLUCIÓN
-= Fecha Publicación: 21.04.2009 =-
Román Medina-Heigl Hernández
<
[email protected]>
Reto Panda – Prueba #3 - SOLUCIÓN. © RoMaNSoFt, 2009
ÍNDICE DE CONTENIDOS
--[ 0x01 - Introducción ] ......................................................................................................................3
--[ 0x02 - Herramientas utilizadas ].....................................................................................................4
--[ 0x03 - Análisis inicial ]...................................................................................................................5
--[ 0x04 - Los hilos “secundarios” ] ..................................................................................................11
--[ 0x05 - Primer intento ]..................................................................................................................15
--[ 0x06 – Las cien funciones ]..........................................................................................................17
--[ 0x07 - Solución “aproximada” ]...................................................................................................21
--[ 0x08 - Afinando la solución: funciones de tipo 2 ] ......................................................................23
--[ 0x09 - Resolviendo las funciones de tipo 3 ]................................................................................26
--[ 0x0a - Solución definitiva ] ..........................................................................................................32
--[ 0x0b - Feedback & Greetz ]..........................................................................................................33
Reto Panda – Prueba #3 - SOLUCIÓN. © RoMaNSoFt, 2009
--[ 0x01 - Introducción ]
En este paper trataré de resumir mi solución a la última prueba del concurso que Panda Security
ha celebrado recientemente (1/Abr - 9/Abr). A día de hoy todavía no se han publicado los
resultados del reto por lo que aún no hay ganadores ni soluciones oficiales a las distintas pruebas.
Este solucionario se ofrece sin garantía alguna y podría no ser 100% correcto. Tampoco pretende
ser un howto detallado, simplemente trataré de esbozar mi solución y el razonamiento que seguí en
la resolución de la prueba.
Constaba de 3 pruebas diferentes, todas ellas ejercicios de ingeniería inversa (“crackmes”), y
donde la dificultad era creciente. Me ceñiré a la prueba 3 (la última y supuestamente más difícil,
correspondiente al primer premio del concurso).
El concurso se ubicó en:
http://www.retopanda.es/
3
Reto Panda – Prueba #3 - SOLUCIÓN. © RoMaNSoFt, 2009
--[ 0x02 - Herramientas utilizadas ]
En mayor o menor medida se utilizaron las siguientes:
OllyDbg
UltraEdit
IDA Pro
http://www.hex-rays.com/idapro/
La herramienta por excelencia para análisis estático.
http://www.ollydbg.de/
Uno de los mejores debuggers para Windows.
http://www.ultraedit.com/
Excelente editor (ascii y hexadecimal).
http://peid.has.it/
Detección de packers, rutinas de crypto y compiladores.
http://mark0.net/soft-trid-e.html
Otro identificador de tipos de fichero basado en firmas binarias.
http://www.mingw.org/
Gcc para Windows, etc.
http://crank.sourceforge.net
Criptoanálisis y cifrados básicos.
PEiD
TrID
MinGW
Crank
4
Reto Panda – Prueba #3 - SOLUCIÓN. © RoMaNSoFt, 2009
--[ 0x03 - Análisis inicial ]
Nos bajamos el binario: reto3.exe. Lo analizamos y posteriormente ejecutamos (nos aseguran
que no contiene virus; no está de más pasarlo por VirusTotal y como no, recomendable lanzarlo en
un entorno controlado: Vmware):
El programa no acepta entrada de usuario ni emite ningún mensaje al ser ejecutado. Las
utilidades de identificación lanzadas tampoco son nada definitivas. Por ahora, ninguna pista :-/
Cargamos el todo-poderoso IDA-Pro. Lo primero que nos sorprende (y alegra) es:
5
Reto Panda – Prueba #3 - SOLUCIÓN. © RoMaNSoFt, 2009
Esto es, el binario contiene información de depuración (lo que facilitará su análisis) y nos
pregunta si queremos buscar/cargar los símbolos correspondientes. Por supuesto, asentimos.
Además, el binario es pequeño (76 kbytes) y no está empaquetado. A juzgar por estas “facilidades”,
todo apunta a que la prueba está pensada para que se resuelva (al menos en parte) mediante análisis
estático y seguro que esconderá otras dificultades y “sorpresas”.
Una vez finalizada la carga comprobamos la ventana de “nombres” y nos fijamos en las dos
primeras funciones:
Realmente la ejecución comenzará en el “entry point” (00403559), desde donde se llamará a
diferentes rutinas de inicialización propias de un ejecutable compilado con Visual Studio
(___security_init_cookie –el binario utiliza /gs-, ___tmainCRTStartup, …), pero no nos interesan.
Partiremos de la rutina principal o “_main”, cuya panorámica es la siguiente (tranquilos, en breve
entramos en detalle y con un zoom suficiente para no quedarnos sin vista ☺):
6
Reto Panda – Prueba #3 - SOLUCIÓN. © RoMaNSoFt, 2009
7
Reto Panda – Prueba #3 - SOLUCIÓN. © RoMaNSoFt, 2009
Veámoslo desde el principio. Primero, la parte del prólogo de la función e inicialización de
variables locales. IDA nos muestra el prototipo de la función en formato C en la cabecera (lo cual
es de agradecer). Se inicializan las variables locales, casi todas a cero (utilizando los típicos trucos
de optimización: “xor eax, eax” para poner eax a 0 y luego mover eax a las diferentes variables en
pila). Nótese el “CreateThread”, que ya lo tenemos preparado en edi ☺
Después tenemos el bucle de creación de hilos. En concreto, se crearán 10 threads que yo he
llamado “principales” ya que (estoy adelantando acontecimientos) cada uno de estos hilos lanzará a
su vez más hilos (lo veremos más adelante), que llamaré “secundarios” (para distinguirlos).
Además, en 411B50 tenemos una variable global que contendrá un array con 100 elementos de
2 bytes (1 word) cada uno. Cada word contendrá un carácter de la frase secreta que debemos
averiguar (ocupa doble porque el carácter es Unicode). Cada hilo se corresponderá con un word de
este array e inicialmente se asigna el número de hilo a dicha word. La rutina que se ejecuta para
cada hilo reside en StartAddress y se le pasa como parámetro el número de hilo.
8
Reto Panda – Prueba #3 - SOLUCIÓN. © RoMaNSoFt, 2009
Una vez lanzados los 10 hilos principales (que ya estudiaremos en profundidad lo que hacen), el
programa principal simplemente espera a que todos ellos terminen. El tiempo de sondeo es de 1
segundo (3E8h milisegundos) pero nos fijamos también que se introduce un sleep de algo más de
16 minutos (exactamente 1000 segundos o F40240h milisegundos). Este sleep no aporta nada
realmente y más tarde lo anularemos (reduciremos su valor), para que no moleste ☺
Finalmente, cuando todos los hilos han terminado, se imprimirá la frase secreta: “La cadena
oculta es: …”. Queda claro que el objetivo de la prueba es averiguar dicha cadena.
9
Reto Panda – Prueba #3 - SOLUCIÓN. © RoMaNSoFt, 2009
10
Reto Panda – Prueba #3 - SOLUCIÓN. © RoMaNSoFt, 2009
--[ 0x04 - Los hilos “secundarios” ]
Hemos visto que cada hilo principal ejecuta la rutina “StartAddress” pasándole como
parámetro el número de hilo. Analicemos ahora dicha rutina. Comienza así:
Lo más importante es que se llama a una función que depende del número de hilo. Para ello
se parte de un array de 100 punteros a función (410F50) y se utiliza como índice precisamente el
número de hilo. Comprobamos que efectivamente esta dirección contiene punteros a función:
11
Reto Panda – Prueba #3 - SOLUCIÓN. © RoMaNSoFt, 2009
Volveremos a este punto más adelante en el documento.
Siguiendo con el análisis del primer fragmento de la función “StartAddress”, el valor que
inicialmente recibirá esta función estará entre 0 y 9 (ambos inclusive), que son los 10 hilos creados
desde “main”. También cabe recalcar que cuando llamamos a una de las 100 funciones
“disponibles” (en realidad son menos, algunos punteros se repiten), siempre se le pasa como
parámetro el número de hilo (en algún caso se utilizará este valor, en otros no; esto es importante,
puesto que quiere decir que una misma función puede dar lugar a una letra diferente, en función del
hilo).
En el segundo fragmento se puede observar como se crean 9 hilos más (“secundarios”), po
Comentarios de: Reto Panda - Prueba #3 - SOLUCIÓN - (0)
No hay comentarios