Esta es la primera entrega de tres en las que vamos a ver tres crackmes que todo reverser debería hacer. Son la serie del autor Cruehead. Aunque los hice hace ya muchos años, he decidido documentarlos para que el lector que empieza pueda deleitarse. En este caso se trata del típico Nombre / Serial.
El algoritmo
El algoritmo de este crackme es lo más sencillo que nos podemos encontrar.
Abrimos el crackme con Olly y buscamos en las «string references» el mensaje de error. Pinchamos sobre el y en la parte superior enseguida vemos 2 calls muy interesantes.
Veamos que hace con el nombre.
Para «deurus» pondría todo en mayúsculas, sumaría su valor ascii y le haría XOR 0x5678.
Introducción A quien va dirigido Comprobaciones previas Lo que necesitamos Presupuesto Ejemplo de instalación Preguntas frecuentes Glosario Notas finales Introducción
Continuamos con la segunda entrega de Cruehead. En este caso nos encontramos con un único campo de contraseña para introducir.
El algoritmo
Abrimos con Olly y vemos dos saltos. El primer Call realiza una serie de operaciones con el serial introducido y el segundo comprueba si el serial es correcto.
A continuación llegamos aquí:
00401365 /$ C605 18214000 00 MOV BYTE PTR DS:[402118],0
0040136C |. 8B7424 04 MOV ESI,DWORD PTR SS:[ESP+4]
00401370 |. 56 PUSH ESI
00401371 |> 8A06 /MOV AL,BYTE PTR DS:[ESI] ; <---
00401373 |. 84C0 |TEST AL,AL
00401375 |. 74 19 |JE SHORT CRACKME2.00401390
00401377 |. FE05 18214000 |INC BYTE PTR DS:[402118]
0040137D |. 3C 41 |CMP AL,41 ; 41 = A
0040137F |. 72 04 |JB SHORT CRACKME2.00401385 ; ya es mayúscula
00401381 |. 3C 5A |CMP AL,5A ; 5A = Z
00401383 |. 73 03 |JNB SHORT CRACKME2.00401388 ; Convertir a mayúscula
00401385 |> 46 |INC ESI
00401386 |.^ EB E9 |JMP SHORT CRACKME2.00401371 ; Bucle -->
00401388 |> E8 25000000 |CALL CRACKME2.004013B2
0040138D |. 46 |INC ESI
0040138E |.^ EB E1 \JMP SHORT CRACKME2.00401371
00401390 |> 5E POP ESI
00401391 |. E8 03000000 CALL CRACKME2.00401399 ;Convertido a mayúsculas continuamos
00401396 |. EB 00 JMP SHORT CRACKME2.00401398
00401398 \> C3 RETN
Si nuestro serial contiene solo letras, las convierte a mayúsculas y seguimos aquí. En resumen hace XOR byte a byte entre nuestro serial y la frase «Messing_in_bytes»
00401399 /$ 33DB XOR EBX,EBX
0040139B |. 33FF XOR EDI,EDI
0040139D |> 8A8F A3214000 /MOV CL,BYTE PTR DS:[EDI+4021A3] ; Carga el primer byte de 4021A3
004013A3 |. 8A1E |MOV BL,BYTE PTR DS:[ESI] ;
004013A5 |. 84DB |TEST BL,BL
004013A7 |. 74 08 |JE SHORT CRACKME2.004013B1
004013A9 |. 32D9 |XOR BL,CL ; byteSerial XOR Byte"Messing_in..."
004013AB |. 881E |MOV BYTE PTR DS:[ESI],BL
004013AD |. 46 |INC ESI ;Siguiente byte de "Messing_in_bytes"
004013AE |. 47 |INC EDI ;Siguiente byte del serial
004013AF |.^ EB EC \JMP SHORT CRACKME2.0040139D
004013B1 \> C3 RETN ;XOR finalizado volvemos
Estado del DUMP (memoria) antes del XOR y con nuestro serial (12345678) cargado.
Si buscamos el comando REPE encontramos que si el flag Z = 1 el bucle se corta y que trabaja con bytes. El problema es que en Olly la instrucción REPE nosotros la vemos con un solo paso y nos puede pasar desapercibida.
En resumen, está comprobando los bytes de las direcciones 402150 (1F 2C 37 36 3B 3D 28 19 3D 26 1A 31 2D 3B 37 3E) con nuestro serial XOReado, 40217E en adelante, por lo que si hacemos XOR entre los bytes de 402150 y la frase «Messing_in_bytes» obtendremos la clave correcta.
M e s s i n g _ i n _ b y t e s
4D 65 73 73 69 6E 67 5F 69 6E 5F 62 79 74 65 73
XOR
1F 2C 37 36 3B 3D 28 19 3D 26 1A 31 2D 3B 37 3E
-----------------------------------------------
52 49 44 45 52 53 4F 46 54 48 45 53 54 4F 52 4D
R I D E R S O F T H E S T O R M
Serial: RIDERSOFTHESTORM
En este reto se nos entrega un archivo WAV de 9,92 MB. Tras escucharlo y analizarlo por encima con Audacity no llego a ningún lado por lo que me tiro al descarte de herramientas conocidas, y en ésta ocasión sale a escena DeepSound.
Sin más dilación extraemos el JPG y continuamos.
La aparición en escena de DeepSound me hace sospechar sobre el uso de herramientas conocidas y ¡bingo!, sale a escena StegHide. En esta ocasión el autor del reto nos lo ha puesto fácil y la extracción no requiere clave.
Al abrir el archivo TXT como texto vemos lo siguiente:
y si lo abrimos con un editor hexadecimal vemos esto otro:
Claramente el archivo esconde algo que por la repetición de los caracteres me hace sospechar de un simple XOR y efectivamente la flag está XOReada. Tras un ataque preliminar, digamos que los árboles no me dejaban ver el bosque, de modo que limpié los bytes correspondientes a la frase «this is the flag :)» y procesé de nuevo obteniendo por fin la ansiada flag.
RAW bytes
FF FE 74 00 68 00 69 00 73 00 20 00 40 DB 53 DC 40 DB 48 DC 40 DB 53 DC 40 DB 7B DC 40 DB 74 DC 69 00 73 00 20 00 40 DB 30 DC 40 DB 30 DC 40 DB 5F DC 40 DB 33 DC 40 DB 34 DC 74 00 68 00 65 00 20 00 40 DB 73 DC 40 DB 79 DC 40 DB 5F DC 40 DB 6D DC 40 DB 34 DC 66 00 6C 00 61 00 67 00 20 00 40 DB 6E DC 40 DB 7D DC 40 DB 20 DC 3A 00 29 00
Cleaned bytes [quitando this is the flag :)]
FF FE 40 DB 53 DC 40 DB 48 DC 40 DB 53 DC 40 DB 7B DC 40 DB 74 DC 40 DB 30 DC 40 DB 30 DC 40 DB 5F DC 40 DB 33 DC 40 DB 34 DC 40 DB 73 DC 40 DB 79 DC 40 DB 5F DC 40 DB 6D DC 40 DB 34 DC 40 DB 6E DC 40 DB 7D DC 40 DB 20 DC
clave XOR == 00fc60fb
Resultado
S H S { t 0 0 _ 3 4 s y _ m 4 n }
Esta vez se trata de un crackme realizado en VC++ 5.0/6.0 y en sus entrañas utiliza RSA-24. En este caso la peculiaridad es que el nombre no interviene en la generación del serial siendo un resultado único.
Resumen RSA
Parámetros
p = Primer número primo
q = Segundo número primo
e = Exponente público que cumpla MCD(e,(p-1)*(q-1))==1
n = Módulo público siendo n=p*q
d = Exponente privado que cumpla d=e^(-1) mod ((p-1)*(q-1))
De este modo e y n son la parte pública de la clave y d y n la parte privada. Los número primos p y q se utilizan solo para generar los parámetros y de ahí en adelante se pueden desechar.
Funciones de Cifrado/Descifrado
cifrado = descifrado ^ e mod n
descifrado = cifrado ^ d mod n
OllyDbg
Nuestro primer vistazo con OllyDbg nos muestra cuatro números de los que podemos hacernos una idea de que 9901 es un buen candidato a ser el exponente público (e) y 12790891 el módulo n ya que casualmente es un número de 24 bits. Los otros dos números de momento no nos dicen nada.
Referencias de texto
A continuación de los números tenemos la rutina de comprobación en la que comprueba que nuestro serial tenga 14 dígitos y lo divide en dos partes de 7 dígitos. Interesante ya que los otros dos números que aparecían en las referencias de texto tienen 7 dígitos cada uno.
A continuación hace una serie de operaciones matemáticas para finalmente comparar el resultado con 8483678 y con 5666933. Lo que está haciendo es cifrar con nuestro serial en dos partes para comprobar que tenemos el número descifrado. Veamos un ejemplo con el serial 12345678901234.
descifrado ^ e mod n = cifrado
x1 = 1234567 y x2 = 8901234
1º parte del serial
x1 ^ 9901 mod 12790891 != 8483678
2º parte del serial
x2 ^ 9901 mod 12790891 != 5666933
Obviamente el resultado de las operaciones anteriores no da ese resultado y el Crackme nos tira fuera de modo que no nos queda más que atacar a RSA para obtener los primos p y q y el módulo privado d. De este modo podremos obtener los números buenos.
Los primos p y q se obtienen factorizando (botón Factor N) y una vez que tenemos p y q hallamos d (botón Calc. D). Todo esto es coser y cantar con la ayuda de la herramienta RSA-Tool 2. El exponente público e se introduce en hexadecimal.
Obteniendo p, q y d
Una vez que tenemos d hallamos el serial de forma sencilla con la herramienta Big Integer Calculator.
cifrado ^ d mod n = descifrado
1º parte del serial
8483678 ^ 10961333 mod 12790891 = 7167622
2º parte del serial
5666933 ^ 10961333 mod 12790891 = 3196885
SERIAL = 71676223196885
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.
Realistic Challenge 3: Your school is employing a web designer who is charging far too much for site design and doesn’t know anything about protecting the site. However, he’s sure that there’s no way anyone can hack into any site he’s designed, prove him wrong!
En tu escuela están haciendo una web nueva muy rápido. El creador asegura que no le pueden hackear, demuéstrale que está equivocado.
Analizando a la víctima
Echamos un vistazo y vemos en el menú cosas interesantes. La primera de ellas es un Login que pronto descartamos ya que no parece llevar a ninguna parte. La segunda sirve para mandar enlaces al administrador y que este los publique posteriormente en la web.
Vamos a trastear un poco con la opción de mandar enlaces. En el código fuente ya vemos algo interesante y es que hay un campo oculto con el valor a 1 al mandar el enlace. Probamos a mandar un enlace sin tocar nada y nos dice que lo manda pero que lo tienen que aprobar. Vamos a probar ahora cambiando el valor del parámetro oculto a 0 con Firebug.
¡Funcionó!, el enlace ha pasado el filtro.
¿Cómo podemos aprovechar esto?, pués la forma más común es «XSS cross site scripting«. Veamos una prueba. Con el parámetro oculto otra vez en 0 mandamos el siguiente enlace y reto superado.
En el primer vistazo con el editor hexadecimal ya vemos la solución al reto:
Pho
Al igual que el caso anterior con el editor hexadecimal tenemos más que suficiente para resolver el reto.
Minions
En el análisis inicial no destaca prácticamente nada excepto la palabra myadmin que podemos ver con un editor hexadecimal.
La palabra myadmin es una buena candidata a ser contraseña ante una decodificación. Probamos con lo estándar y conseguimos resultados con steghide. La decodificación nos devuelve la cadena AEMAVABGAGwAZQBhAHIAbgB7AHQAaABpAHMAXwBpAHMAXwBmAHU***** que rápidamente catalogamos como base64 para resolver el reto.
Unopenable
Se nos entrega una imagen GIF aparentemente corrupta. Estudiando un poco la cabecera de los archivos GIF llegamos rápidamente a la conclusión de que faltan los cuatro primeros bytes del archivo.
Una vez insertados los bytes podemos ver una animación que contiene una cadena de texto fácilmente reconocible como base64. La decodificamos y ya tenemos la solución.
Oreo
Mirando con un editor hexadecimal no encontramos nada excepto la frase This is not the flag you are looking for para intentar disuadirnos.
Cargamos la imagen en Aperi’Solvey enseguida nos llama la atención la sección Binwalk y un suculento Rar.
Descargamos el archivo Rar y al descomprimir nos encontramos con un archivo de texto con la misma frase desalentadora del inicio y una imagen JPG, esta vez con dos oreos. Inspeccionando la imagen damos con la solución.