Solución al Desafío ESET #37

Presentamos la solución al Desafío ESET #37 que planteó realizar un reversing en Linux. El ganador obtuvo una entrada para ekoparty 2018.

El pasado 7 de septiembre lanzamos el Desafío ESET #37 que premiaba al primero en resolverlo con una entrada gratuita para la conferencia de seguridad ecofiesta 2018.

En primer lugar, nos gustaría agradecer a todos los que participaron y dedicaron parte de su tiempo tratando de resolver este desafío de invertir en Linux. Aprovechamos para felicitar a Apuromafo por ser el primero en resolver el desafío de forma correcta y ganar la entrada, y también a Mariano Marino y Víctor Meléndez, quienes también logarron resolver el desafío.

Por otro lado, si aún no tienes tu entrada para ekoparty 2018envíanos un mensaje directo a través de nuestras cuentas de Facebook o Gorjeo mencionando el hashtag #VivimosEcofiesta y te indicamos cómo puedes hacer para compre su entrada con un 15% de descuento.

A continuación, presentamos una posible solución al desafío:

Iniciamos el análisis con IDA y observamos que la cantidad de subrutinas no es muy grande; el binario es relativamente pequeño. vamos a la funcion principal() y lo primero que se observa es la existencia de datos numéricos en formato hexadecimal, que se almacenan en variables locales. Hay un total de 60 bytes de datos. Luego está el código que le las tres contraseñas por pantalla, aparentemente tomando como máximo 43 bytes, para evitar desbordamientos.

La primera contraseña a evaluar es la tercera, y se comprueba que sea numérica y de longitud 8, media el uso de strlen() y strspn().

Luego se llama a una subrutina que recibe entrada3 y otra variable como argumentos. Si entramos a esa subrutina, veremos otras secuencias de bytes hardcodeados. Buscando la primera secuencia en Google (67452301), el primer resultado es "SHA-1 Wikipedia". En este artículo encontramos todas las constantes y concluimos que se calculó el SHA-1 entrada3.

Luego se procesaron los bytes hexadecimales que habíamos visto al principio, primero para var_1A0luego var_180 y por ultimo var_160. Quedan entonces 3 variables de 20 bytes cada una, lo cual coincide con la longitud de un hash SHA-1.

Ese procesamiento que se hace reordena los bytes de esos hashes precalculados. Aparentemente, los bytes no eran para evitar realizar una búsqueda directa de esos hashes (como se hizo con las constantes de SHA-1). Luego se utiliza la misma subrutina (que he renombrado a comprobar_sha_1) tres veces, para comparar el hash calculado para cada input contra el valor precalculado.

Hash1 = 8af9a4abff70aaa9f2dd35446168d0a1fa6e7218
Hash2 = 2b3e371486dee4f954150c7863877108b7d4881d
Hash3 = ca6b77dc94df51f638186046788b6570b73d4fcb

Los valores de Hash1 y Hash2 pueden buscarse online y se obtiene el texto plano correspondiente:

Pass1 = supercalifragilisticoespialidoso
Pase2 = kingjames23

El tercer hash no se encuentra con una búsqueda. Si prestamos atención, ya habíamos calculado el SHA-1 para entrada3y luego se calcula nuevamente, por lo que en realidad se comprueba:

Hash3 == SHA-1(SHA-1(entrada3))

Pero como sabemos que la tercera entrada debe ser numérica y de 8 dígitos, podemos obtener la solución de fuerza bruta. Si tenemos hashcat, el proceso es rápido y simple:

Y se obtiene Pass3 = 69641758

No es necesario analizar el resto del código, pero descifra un búfer que muestra la bandera usando el cifrado AES. Para el descifrado se concatenan las 3 claves ingresadas (pero en orden inverso, copiando del último al primer carácter) y el MD5 de esa larga cadena se toma como clave de descifrado. Veremos la solución a continuación:

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir
error: Content is protected !!