Introducción
Recién rescatados del inframundo que es mi disco duro, os traigo un paquete de seis crackmes facilones para vuestro uso y disfrute. Desgraciadamente ya no está en activo la web de retos de donde los saqué así que os los dejo en descargas.
Los cuatro primero están realizados en Dev-C++ 4.9.9.2 siendo de estilo consola de comandos. Los dos restantes compilados con MingWin32 GCC 3.x carecen de GUI y vamos, que no se han esmerado mucho en darles forma.
Level 1
No cuesta mucho dar con el código interesante mediante las referencias de texto. En Ollydbg clic derecho sobre el código y Search for > All referenced text strings.
004012E1 |. 8845 E8 MOV BYTE PTR SS:[EBP-18],AL ; |||| 004012E4 |. C70424 11304000 MOV DWORD PTR SS:[ESP],level1.00403011 ; ||||ASCII "Input Serial: " 004012EB |. E8 C0050000 CALL <JMP.&msvcrt.printf> ; |||\printf 004012F0 |. 8D45 C8 LEA EAX,[LOCAL.14] ; ||| 004012F3 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX ; ||| 004012F7 |. C70424 20304000 MOV DWORD PTR SS:[ESP],level1.00403020 ; |||ASCII "%s" 004012FE |. E8 9D050000 CALL <JMP.&msvcrt.scanf> ; ||\scanf 00401303 |. 8D45 D8 LEA EAX,[LOCAL.10] ; || 00401306 |. 8D55 C8 LEA EDX,[LOCAL.14] ; || 00401309 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX ; || 0040130D |. 891424 MOV DWORD PTR SS:[ESP],EDX ; ||level1.00403022 00401310 |. E8 7B050000 CALL <JMP.&msvcrt.strcmp> ; |\strcmp 00401315 |. 8945 C4 MOV [LOCAL.15],EAX ; | 00401318 |. 837D C4 00 CMP [LOCAL.15],0 ; | 0040131C |. 75 0E JNZ SHORT level1.0040132C ; | 0040131E |. C70424 23304000 MOV DWORD PTR SS:[ESP],level1.00403023 ; |ASCII "Well done. \n" 00401325 |. E8 86050000 CALL <JMP.&msvcrt.printf> ; \printf 0040132A |. EB 0C JMP SHORT level1.00401338 0040132C |> C70424 30304000 MOV DWORD PTR SS:[ESP],level1.00403030 ; |ASCII "Wrong. \n" 00401333 |. E8 78050000 CALL <JMP.&msvcrt.printf> ; \printf 00401338 |> C70424 39304000 MOV DWORD PTR SS:[ESP],level1.00403039 ; |ASCII "PAUSE" 0040133F |. E8 3C050000 CALL <JMP.&msvcrt.system> ; \system 00401344 |. B8 00000000 MOV EAX,0 00401349 |. C9 LEAVE 0040134A \. C3 RETN
La madre del cordero está en la dirección 401310 que es donde se lleva a cabo la función de comparación strcmp.
756296A0 msvcrt.strcmp 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4] 756296A4 8B4C24 08 MOV ECX,DWORD PTR SS:[ESP+8] 756296A8 F7C2 03000000 TEST EDX,3 ; 0-3 = 4 bucles. Divide la comprobación en 4 bloques 756296AE 75 3C JNZ SHORT msvcrt.756296EC ; salta si hemos terminado los 4 bucles 756296B0 > 8B02 MOV EAX,DWORD PTR DS:[EDX] ; coge 4 caracteres del serial (INICIO BUCLE) 756296B2 3A01 CMP AL,BYTE PTR DS:[ECX] ; compara el 1º/5º/9º/13º dígito en función del bucle 756296B4 75 2E JNZ SHORT msvcrt.756296E4 ; salto a zona mala 756296B6 0AC0 OR AL,AL 756296B8 74 26 JE SHORT msvcrt.756296E0 756296BA 3A61 01 CMP AH,BYTE PTR DS:[ECX+1] ; compara el 2º/6º/10º/14º dígito en función del bucle 756296BD 75 25 JNZ SHORT msvcrt.756296E4 ; salto a zona mala 756296BF 0AE4 OR AH,AH 756296C1 74 1D JE SHORT msvcrt.756296E0 756296C3 C1E8 10 SHR EAX,10 756296C6 3A41 02 CMP AL,BYTE PTR DS:[ECX+2] ; compara el 3º/7º/11º/15º dígito en función del bucle 756296C9 75 19 JNZ SHORT msvcrt.756296E4 ; salto a zona mala 756296CB 0AC0 OR AL,AL 756296CD 74 11 JE SHORT msvcrt.756296E0 756296CF 3A61 03 CMP AH,BYTE PTR DS:[ECX+3] ; compara el 4º/8º/12º/16º dígito en función del bucle 756296D2 75 10 JNZ SHORT msvcrt.756296E4 ; salto a zona mala 756296D4 83C1 04 ADD ECX,4 756296D7 83C2 04 ADD EDX,4 756296DA 0AE4 OR AH,AH 756296DC ^ 75 D2 JNZ SHORT msvcrt.756296B0 ; Si no hemos terminado... 756296DE 8BFF MOV EDI,EDI 756296E0 33C0 XOR EAX,EAX ; EAX = 0 que es lo deseado 756296E2 C3 RETN ; salimos de la función superando la comprobación 756296E3 90 NOP 756296E4 1BC0 SBB EAX,EAX ; Zona mala 756296E6 D1E0 SHL EAX,1 756296E8 83C0 01 ADD EAX,1 ; EAX = 1 implica bad boy 756296EB C3 RETN ; salimos de la función
Si atendemos al volcado vemos el serial bueno Kcgcv8LsmV3nizfJ.
0060FEF0 31 32 33 34 35 36 37 38 39 30 00 75 40 19 18 00 1234567890.u@. 0060FF00 4B 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A Kcgcv8LsmV3nizfJ
Curiosamente, si introducimos el serial bueno el crackme no lo acepta. Fijándome en la comprobación veo que al introducir un serial de 16 caracteres inserta un carácter nulo (0x00) alterando el serial correcto y falseando la comprobación.
0060FEF0 4B 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A Kcgcv8LsmV3nizfJ 0060FF00 00 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A .cgcv8LsmV3nizfJ
Ahora ya no podemos comprobarlo pero recuerdo que la web consideraba válido el serial Kcgcv8LsmV3nizfJ, por lo que considero lo anteriormente citado un bug o un intento de despiste del autor.
Level 2
Es exactamente igual que el anterior cambiando el serial por 6LPw3vDYja9KrT2V.
Level 3
La comprobación del serial es igual a las dos anteriores pero añade una función intermedia que suma 0xD a cada carácter de nuestro serial
00401355 |. A1 03304000 MOV EAX,DWORD PTR DS:[403003] ; || 0040135A |. 8945 E8 MOV [LOCAL.6],EAX ; || 0040135D |. A1 07304000 MOV EAX,DWORD PTR DS:[403007] ; || 00401362 |. 8945 EC MOV [LOCAL.5],EAX ; || 00401365 |. A1 0B304000 MOV EAX,DWORD PTR DS:[40300B] ; || 0040136A |. 8945 F0 MOV [LOCAL.4],EAX ; || 0040136D |. A1 0F304000 MOV EAX,DWORD PTR DS:[40300F] ; || 00401372 |. 8945 F4 MOV [LOCAL.3],EAX ; || 00401375 |. C70424 13304000 MOV DWORD PTR SS:[ESP],level3.00403013 ; ||ASCII "Input Serial: " 0040137C |. E8 CF050000 CALL <JMP.&msvcrt.printf> ; |\printf 00401381 |. 8D45 D8 LEA EAX,[LOCAL.10] ; | 00401384 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX ; | 00401388 |. C70424 00304000 MOV DWORD PTR SS:[ESP],level3.00403000 ; |ASCII "%s" 0040138F |. E8 AC050000 CALL <JMP.&msvcrt.scanf> ; \scanf 00401394 |. 8D5D E8 LEA EBX,[LOCAL.6] 00401397 |. 8D45 D8 LEA EAX,[LOCAL.10] 0040139A |. 890424 MOV DWORD PTR SS:[ESP],EAX 0040139D |. E8 EEFEFFFF CALL level3.00401290 ; NUEVA FUNCIÓN SUMA 004013A2 |. 895C24 04 MOV DWORD PTR SS:[ESP+4],EBX ; || 004013A6 |. 890424 MOV DWORD PTR SS:[ESP],EAX ; || 004013A9 |. E8 82050000 CALL <JMP.&msvcrt.strcmp> ; |\strcmp 004013AE |. 8945 D4 MOV [LOCAL.11],EAX ; | 004013B1 |. 837D D4 00 CMP [LOCAL.11],0 ; | 004013B5 |. 75 0E JNZ SHORT level3.004013C5 ; | 004013B7 |. C70424 22304000 MOV DWORD PTR SS:[ESP],level3.00403022 ; |ASCII "Well done." 004013BE |. E8 8D050000 CALL <JMP.&msvcrt.printf> ; \printf 004013C3 |. EB 0C JMP SHORT level3.004013D1 004013C5 |> C70424 2D304000 MOV DWORD PTR SS:[ESP],level3.0040302D ; |ASCII "Wrong. \n" 004013CC |. E8 7F050000 CALL <JMP.&msvcrt.printf> ; \printf 004013D1 |> C70424 36304000 MOV DWORD PTR SS:[ESP],level3.00403036 ; |ASCII "PAUSE" 004013D8 |. E8 43050000 CALL <JMP.&msvcrt.system> ; \system 004013DD |. B8 00000000 MOV EAX,0 004013E2 |. 8B5D FC MOV EBX,[LOCAL.1] 004013E5 |. C9 LEAVE 004013E6 \. C3 RETN -------- 004012A4 |> /8B45 08 /MOV EAX,[ARG.1] ; | 004012A7 |. |890424 |MOV DWORD PTR SS:[ESP],EAX ; | 004012AA |. |E8 B1060000 |CALL <JMP.&msvcrt.strlen> ; \strlen 004012AF |. |3945 FC |CMP [LOCAL.1],EAX 004012B2 |. |73 1C |JNB SHORT level3.004012D0 004012B4 |. |8B45 08 |MOV EAX,[ARG.1] 004012B7 |. |8B55 FC |MOV EDX,[LOCAL.1] 004012BA |. |01C2 |ADD EDX,EAX 004012BC |. |8B45 08 |MOV EAX,[ARG.1] 004012BF |. |0345 FC |ADD EAX,[LOCAL.1] 004012C2 |. |0FB600 |MOVZX EAX,BYTE PTR DS:[EAX] 004012C5 |. |04 0D |ADD AL,0D ; char + 0xD 004012C7 |. |8802 |MOV BYTE PTR DS:[EDX],AL 004012C9 |. |8D45 FC |LEA EAX,[LOCAL.1] 004012CC |. |FF00 |INC DWORD PTR DS:[EAX] 004012CE |.^\EB D4 \JMP SHORT level3.004012A4 -------- 756296A0 msvcrt.strcmp 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4] 756296A4 8B4C24 08 MOV ECX,DWORD PTR SS:[ESP+8] 756296A8 F7C2 03000000 TEST EDX,3 756296AE 75 3C JNZ SHORT msvcrt.756296EC 756296B0 8B02 MOV EAX,DWORD PTR DS:[EDX] 756296B2 3A01 CMP AL,BYTE PTR DS:[ECX] 756296B4 75 2E JNZ SHORT msvcrt.756296E4 756296B6 0AC0 OR AL,AL 756296B8 74 26 JE SHORT msvcrt.756296E0 756296BA 3A61 01 CMP AH,BYTE PTR DS:[ECX+1] 756296BD 75 25 JNZ SHORT msvcrt.756296E4 756296BF 0AE4 OR AH,AH 756296C1 74 1D JE SHORT msvcrt.756296E0 756296C3 C1E8 10 SHR EAX,10 756296C6 3A41 02 CMP AL,BYTE PTR DS:[ECX+2] 756296C9 75 19 JNZ SHORT msvcrt.756296E4 756296CB 0AC0 OR AL,AL 756296CD 74 11 JE SHORT msvcrt.756296E0 756296CF 3A61 03 CMP AH,BYTE PTR DS:[ECX+3] 756296D2 75 10 JNZ SHORT msvcrt.756296E4 756296D4 83C1 04 ADD ECX,4 756296D7 83C2 04 ADD EDX,4 756296DA 0AE4 OR AH,AH 756296DC ^ 75 D2 JNZ SHORT msvcrt.756296B0 756296DE 8BFF MOV EDI,EDI 756296E0 33C0 XOR EAX,EAX 756296E2 C3 RETN 756296E3 90 NOP 756296E4 1BC0 SBB EAX,EAX 756296E6 D1E0 SHL EAX,1 756296E8 83C0 01 ADD EAX,1 756296EB C3 RETN
En la comparación vemos que el serial bueno es AvrQQsXjDk25Jrh por lo que si restamos 0xD (13 en decimal) a cada carácter obtendremos el serial bueno.
0060FF10 41 76 72 51 51 73 58 6A 44 6B 32 35 4A 72 68 00 AvrQQsXjDk25Jrh. 41 76 72 51 51 73 58 6A 44 6B 32 35 4A 72 68 - D 34 69 65 44 44 66 4B 5D 37 5E 25 28 3D 65 5B 4 i e D D f K ] 7 ^ % ( = e [ Serial bueno: 4ieDDfK]7^%(=e[
Level 4
La comprobación del serial es igual que la anterior pero sustituyendo la función que sumaba un valor a cada dígito del serial por una que genera un hash con nuestro serial y después lo compara con otro hash almacenado en memoria. Si no nos viene a la mente el tipo de hash que puede ser PEiD ya nos avisaba de que efectivamente el crackme incorpora la función MD5.
La función MD5 hace tiempo que no se considera segura debido a la existencia de numerosos «diccionarios» de hashes que hacen que encontremos la solución en segundos. Yo he utilizado la web MD5 online pero existen muchas más.
0060FE5C 004013BF RETURN to level4.004013BF from <JMP.&msvcrt.strcmp> 0060FE60 0060FEA0 ASCII "e807f1fcf82d132f9bb018ca6738a19f" 0060FE64 0060FEE0 ASCII "fe01d67a002dfa0f3ac084298142eccd" e807f1fcf82d132f9bb018ca6738a19f == 1234567890 fe01d67a002dfa0f3ac084298142eccd == orange
Level 5
La carta de presentación de este crackme es la imagen que veis arriba. Al explorarlo unos minutos enseguida nos damos cuenta de que no realiza ninguna comprobación y que nos está haciendo perder el tiempo. Ahí es cuando empezamos a revisar el ejecutable más a fondo y enseguida encontramos la solución con nuestro amigo el editor hexadecimal.
Level 6
Misma carta de presentación que el anterior y misma ausencia de comprobación del serial. En esta ocasión echando un vistazo a los recursos encontramos la solución rápidamente.