Introducción
Decompilado
Abrimos la víctima con nuestro decompilador favorito y nos fijamos en su contenido.

Abrimos la víctima con nuestro decompilador favorito y nos fijamos en su contenido.

Aquí tenemos un Crackme clásico creado por Scarebyte hallá por el año 2000 y que cuenta con varias fases siendo un crackme muy interesante para iniciarse o simplemente para divertirse. Al estar realizado en Delphi, los apartados de las checkboxes y de las trackbars se simplifican y mucho, pero aún así hay que currarselo un poco para dejar todo bien atado. Si os fijáis en las soluciones que aparecen en crackmes.de, en aquellos años se usaba DEDE y aunque yo usaré otra herramienta, DEDE sigue siendo igual de útil.
PEiD nos dice que nos enfrentamos a ASPack 1.08.03 -> Alexey Solodovnikov, así que vamos al lío.
Tan sencillo como poner un Breakpoint a User32.MessageBoxA. La llamada a NOPear está en la dirección 441CF2.
Desde las string references localizamos los mensajes de chico bueno y chico malo que nos llevan al código a analizar.
0044C3CD |. E8 5294FDFF CALL CrackMe_.00425824 0044C3D2 |. 8B45 FC MOV EAX,[LOCAL.1] 0044C3D5 |. E8 9A76FBFF CALL CrackMe_.00403A74 0044C3DA |. 83F8 0C CMP EAX,0C ; Lengh C = 12 0044C3DD |. 0F85 53010000 JNZ CrackMe_.0044C536 ; Salto a chico malo 0044C3E3 |. 8D55 FC LEA EDX,[LOCAL.1] 0044C3E6 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C3EC |. E8 3394FDFF CALL CrackMe_.00425824 0044C3F1 |. 8B45 FC MOV EAX,[LOCAL.1] 0044C3F4 |. 8038 43 CMP BYTE PTR DS:[EAX],43 ; 1º dígito serial = C 0044C3F7 |. 0F85 27010000 JNZ CrackMe_.0044C524 ; Salto a chico malo 0044C3FD |. 8D55 F8 LEA EDX,[LOCAL.2] 0044C400 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C406 |. E8 1994FDFF CALL CrackMe_.00425824 0044C40B |. 8B45 F8 MOV EAX,[LOCAL.2] 0044C40E |. 8078 03 6F CMP BYTE PTR DS:[EAX+3],6F ; 4º dígito serial = o 0044C412 |. 0F85 0C010000 JNZ CrackMe_.0044C524 ; Salto a chico malo 0044C418 |. 8D55 F4 LEA EDX,[LOCAL.3] 0044C41B |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C421 |. E8 FE93FDFF CALL CrackMe_.00425824 0044C426 |. 8B45 F4 MOV EAX,[LOCAL.3] 0044C429 |. 8078 08 6F CMP BYTE PTR DS:[EAX+8],6F ; 9º dígito serial = o 0044C42D |. 0F85 F1000000 JNZ CrackMe_.0044C524 ; Salto a chico malo 0044C433 |. 8D55 F0 LEA EDX,[LOCAL.4] 0044C436 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C43C |. E8 E393FDFF CALL CrackMe_.00425824 0044C441 |. 8B45 F0 MOV EAX,[LOCAL.4] 0044C444 |. 8078 01 6C CMP BYTE PTR DS:[EAX+1],6C ; 2º dígito serial = l 0044C448 |. 0F85 D6000000 JNZ CrackMe_.0044C524 ; Salto a chico malo 0044C44E |. 8D55 EC LEA EDX,[LOCAL.5] 0044C451 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C457 |. E8 C893FDFF CALL CrackMe_.00425824 0044C45C |. 8B45 EC MOV EAX,[LOCAL.5] 0044C45F |. 8078 04 20 CMP BYTE PTR DS:[EAX+4],20 ; 5º dígito serial = espacio 0044C463 |. 0F85 BB000000 JNZ CrackMe_.0044C524 ; Salto a chico malo 0044C469 |. 8D55 E8 LEA EDX,[LOCAL.6] 0044C46C |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C472 |. E8 AD93FDFF CALL CrackMe_.00425824 0044C477 |. 8B45 E8 MOV EAX,[LOCAL.6] 0044C47A |. 8078 0A 52 CMP BYTE PTR DS:[EAX+A],52 ; 11º dígito serial = R 0044C47E |. 0F85 A0000000 JNZ CrackMe_.0044C524 ; Salto a chico malo 0044C484 |. 8D55 E4 LEA EDX,[LOCAL.7] 0044C487 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C48D |. E8 9293FDFF CALL CrackMe_.00425824 0044C492 |. 8B45 E4 MOV EAX,[LOCAL.7] 0044C495 |. 8078 07 75 CMP BYTE PTR DS:[EAX+7],75 ; 8º dígito serial = u 0044C499 |. 0F85 85000000 JNZ CrackMe_.0044C524 ; Salto a chico malo 0044C49F |. 8D55 E0 LEA EDX,[LOCAL.8] 0044C4A2 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C4A8 |. E8 7793FDFF CALL CrackMe_.00425824 0044C4AD |. 8B45 E0 MOV EAX,[LOCAL.8] 0044C4B0 |. 8078 09 6E CMP BYTE PTR DS:[EAX+9],6E ; 10º dígito serial = n 0044C4B4 |. 75 6E JNZ SHORT CrackMe_.0044C524 ; Salto a chico malo 0044C4B6 |. 8D55 DC LEA EDX,[LOCAL.9] 0044C4B9 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C4BF |. E8 6093FDFF CALL CrackMe_.00425824 0044C4C4 |. 8B45 DC MOV EAX,[LOCAL.9] 0044C4C7 |. 8078 02 6E CMP BYTE PTR DS:[EAX+2],6E ; 3º dígito serial = n 0044C4CB |. 75 57 JNZ SHORT CrackMe_.0044C524 ; Salto a chico malo 0044C4CD |. 8D55 D8 LEA EDX,[LOCAL.10] 0044C4D0 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C4D6 |. E8 4993FDFF CALL CrackMe_.00425824 0044C4DB |. 8B45 D8 MOV EAX,[LOCAL.10] 0044C4DE |. 8078 05 69 CMP BYTE PTR DS:[EAX+5],69 ; 6º dígito serial = i 0044C4E2 |. 75 40 JNZ SHORT CrackMe_.0044C524 ; Salto a chico malo 0044C4E4 |. 8D55 D4 LEA EDX,[LOCAL.11] 0044C4E7 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C4ED |. E8 3293FDFF CALL CrackMe_.00425824 0044C4F2 |. 8B45 D4 MOV EAX,[LOCAL.11] 0044C4F5 |. 8078 0B 6E CMP BYTE PTR DS:[EAX+B],6E ; 12º dígito serial = n 0044C4F9 |. 75 29 JNZ SHORT CrackMe_.0044C524 ; Salto a chico malo 0044C4FB |. 8D55 D0 LEA EDX,[LOCAL.12] 0044C4FE |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C504 |. E8 1B93FDFF CALL CrackMe_.00425824 0044C509 |. 8B45 D0 MOV EAX,[LOCAL.12] 0044C50C |. 8078 06 67 CMP BYTE PTR DS:[EAX+6],67 ; 7º dígito serial = g 0044C510 |. 75 12 JNZ SHORT CrackMe_.0044C524 ; Salto a chico malo 0044C512 |. BA 78C54400 MOV EDX,CrackMe_.0044C578 ; ASCII "Right Password" 0044C517 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C51D |. E8 3293FDFF CALL CrackMe_.00425854 0044C522 |. EB 22 JMP SHORT CrackMe_.0044C546 0044C524 |> BA 90C54400 MOV EDX,CrackMe_.0044C590 ; ASCII "Wrong Password" 0044C529 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 0044C52F |. E8 2093FDFF CALL CrackMe_.00425854 0044C534 |. EB 10 JMP SHORT CrackMe_.0044C546 0044C536 |> BA 90C54400 MOV EDX,CrackMe_.0044C590 ; ASCII "Wrong Password" Chequeo rápido ABCD EFGHIJK Clno iguonRn ; 1º dígito serial = C ; 4º dígito serial = o ; 9º dígito serial = o ; 2º dígito serial = l ; 5º dígito serial = espacio ; 11º dígito serial = R ; 8º dígito serial = u ; 10º dígito serial = n ; 3º dígito serial = n ; 6º dígito serial = i ; 12º dígito serial = n ; 7º dígito serial = g
Básicamente chequea la frase «Cool Running» de forma desordenada como se ve justo encima, siendo el password correcto «Clno iguonRn«. Os dejo el código para que lo analicéis.
De nuevo con las string references localizamos el código.
0044C648 /. 55 PUSH EBP 0044C649 |. 8BEC MOV EBP,ESP 0044C64B |. 83C4 F8 ADD ESP,-8 0044C64E |. 53 PUSH EBX 0044C64F |. 56 PUSH ESI 0044C650 |. 33C9 XOR ECX,ECX 0044C652 |. 894D F8 MOV [LOCAL.2],ECX 0044C655 |. 8BF0 MOV ESI,EAX 0044C657 |. 33C0 XOR EAX,EAX 0044C659 |. 55 PUSH EBP 0044C65A |. 68 83C74400 PUSH CrackMe_.0044C783 0044C65F |. 64:FF30 PUSH DWORD PTR FS:[EAX] 0044C662 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP 0044C665 |. 33C0 XOR EAX,EAX 0044C667 |. 8945 FC MOV [LOCAL.1],EAX 0044C66A |. A1 80F84400 MOV EAX,DWORD PTR DS:[44F880] ; Eax = Nombre 0044C66F |. E8 0074FBFF CALL CrackMe_.00403A74 0044C674 |. 83F8 06 CMP EAX,6 ; Cmp lengh nombre con 6 0044C677 |. 0F8E F0000000 JLE CrackMe_.0044C76D ; Salta si <= 6 0044C67D |. A1 80F84400 MOV EAX,DWORD PTR DS:[44F880] ; Eax = Nombre 0044C682 |. E8 ED73FBFF CALL CrackMe_.00403A74 0044C687 |. 83F8 14 CMP EAX,14 ; Cmp lengh nombre con 20 (14h) 0044C68A |. 0F8D DD000000 JGE CrackMe_.0044C76D ; salta si >= 20 0044C690 |. A1 80F84400 MOV EAX,DWORD PTR DS:[44F880] 0044C695 |. E8 DA73FBFF CALL CrackMe_.00403A74 0044C69A |. 85C0 TEST EAX,EAX 0044C69C |. 7E 17 JLE SHORT CrackMe_.0044C6B5 0044C69E |. BA 01000000 MOV EDX,1 0044C6A3 |> 8B0D 80F84400 /MOV ECX,DWORD PTR DS:[44F880] ; Bucle in 0044C6A9 |. 0FB64C11 FF |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1] 0044C6AE |. 014D FC |ADD [LOCAL.1],ECX ; Suma dig nombre y guarda en 12FBC4 0044C6B1 |. 42 |INC EDX 0044C6B2 |. 48 |DEC EAX 0044C6B3 |.^ 75 EE \JNZ SHORT CrackMe_.0044C6A3 ; Bucle out 0044C6B5 |> A1 84F84400 MOV EAX,DWORD PTR DS:[44F884] ; Eax = Compañia 0044C6BA |. E8 B573FBFF CALL CrackMe_.00403A74 0044C6BF |. 83F8 02 CMP EAX,2 ; Cmp lengh compañia con 2 0044C6C2 |. 7E 18 JLE SHORT CrackMe_.0044C6DC ; Salta si <= 2 0044C6C4 |. A1 84F84400 MOV EAX,DWORD PTR DS:[44F884] ; Eax = Compañia 0044C6C9 |. E8 A673FBFF CALL CrackMe_.00403A74 0044C6CE |. 83F8 08 CMP EAX,8 ; Cmp lengh compañia con 8 0044C6D1 |. 7D 09 JGE SHORT CrackMe_.0044C6DC ; Salta si >= 8 0044C6D3 |. 8B45 FC MOV EAX,[LOCAL.1] ; Eax = sum nombre 0044C6D6 |. 6BC0 02 IMUL EAX,EAX,2 ; Sum nombre * 2 0044C6D9 |. 8945 FC MOV [LOCAL.1],EAX 0044C6DC |> 68 98C74400 PUSH CrackMe_.0044C798 ; ASCII "I Love Cracking and " 0044C6E1 |. 8D55 F8 LEA EDX,[LOCAL.2] 0044C6E4 |. 8B45 FC MOV EAX,[LOCAL.1] 0044C6E7 |. E8 68B0FBFF CALL CrackMe_.00407754 0044C6EC |. FF75 F8 PUSH [LOCAL.2] ; sum del nombre 0044C6EF |. 68 B8C74400 PUSH CrackMe_.0044C7B8 ; ASCII " Girls ;)" 0044C6F4 |. B8 8CF84400 MOV EAX,CrackMe_.0044F88C 0044C6F9 |. BA 03000000 MOV EDX,3 0044C6FE |. E8 3174FBFF CALL CrackMe_.00403B34 ; Concatena 1º frase + sum nombre + 2ºfrase 0044C703 |. 33C0 XOR EAX,EAX 0044C705 |. 8945 FC MOV [LOCAL.1],EAX 0044C708 |. A1 88F84400 MOV EAX,DWORD PTR DS:[44F888] ; Eax = Serial 0044C70D |. E8 6273FBFF CALL CrackMe_.00403A74 0044C712 |. 8BD8 MOV EBX,EAX 0044C714 |. A1 8CF84400 MOV EAX,DWORD PTR DS:[44F88C] 0044C719 |. E8 5673FBFF CALL CrackMe_.00403A74 0044C71E |. 3BD8 CMP EBX,EAX ; Compara tamaño frase con tamaño serial 0044C720 |. 75 4B JNZ SHORT CrackMe_.0044C76D 0044C722 |. A1 88F84400 MOV EAX,DWORD PTR DS:[44F888] 0044C727 |. E8 4873FBFF CALL CrackMe_.00403A74 0044C72C |. 85C0 TEST EAX,EAX 0044C72E |. 7E 27 JLE SHORT CrackMe_.0044C757 0044C730 |. BA 01000000 MOV EDX,1 0044C735 |> 8B0D 88F84400 /MOV ECX,DWORD PTR DS:[44F888] ; Bucle in --> 0044C73B |. 0FB64C11 FF |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1] 0044C740 |. 034D FC |ADD ECX,[LOCAL.1] 0044C743 |. 8B1D 8CF84400 |MOV EBX,DWORD PTR DS:[44F88C] 0044C749 |. 0FB65C13 FF |MOVZX EBX,BYTE PTR DS:[EBX+EDX-1] ; Compara dígito a dígito nuestro serial 0044C74E |. 2BCB |SUB ECX,EBX ; con la concatenación anterior 0044C750 |. 894D FC |MOV [LOCAL.1],ECX 0044C753 |. 42 |INC EDX 0044C754 |. 48 |DEC EAX 0044C755 |.^ 75 DE \JNZ SHORT CrackMe_.0044C735 ; <-- Bucle out 0044C757 |> 837D FC 00 CMP [LOCAL.1],0 0044C75B |. 75 10 JNZ SHORT CrackMe_.0044C76D ; Salta si algo ha ido mal 0044C75D |. 8B86 14030000 MOV EAX,DWORD PTR DS:[ESI+314] 0044C763 |. BA CCC74400 MOV EDX,CrackMe_.0044C7CC ; "You have found the correct Serial :)"
En resumen
Para afrontar esta parte del reto vamos a usar una herramienta llamada Interactive Delphi Reconstructor o IDR. En su día la mejor herramienta era DEDE, pero IDR a mi parecer es algo más potente.
Básicamente IDR nos permite sin quebraderos de cabeza localizar el código del botón que comprueba la secuencia de checkboxes correcta. Cargamos el crackme en IDR y dentro de la pestaña «Units (F2)«, abajo del todo hacemos doble click sobre «F Crack» y vemos que nos muestra todos los controles del formulario. El botón que nos interesa se llama «SpeedButton3«.
Si hacemos doble click sobre el nos muestra el código que se muestra a continuación.
crack::TForm1.SpeedButton3Click 0044C7F4 push ebp 0044C7F5 mov ebp,esp 0044C7F7 push 0 0044C7F9 push ebx 0044C7FA mov ebx,eax 0044C7FC xor eax,eax 0044C7FE push ebp 0044C7FF push 44C920 0044C804 push dword ptr fs:[eax] 0044C807 mov dword ptr fs:[eax],esp 0044C80A mov eax,dword ptr [ebx+324]; TForm1.cb3:TCheckBox 0044C810 mov edx,dword ptr [eax] 0044C812 call dword ptr [edx+0B8]; TCustomCheckBox.GetChecked 0044C818 test al,al >0044C81A je 0044C8ED 0044C820 mov eax,dword ptr [ebx+328]; TForm1.cb5:TCheckBox 0044C826 mov edx,dword ptr [eax] 0044C828 call dword ptr [edx+0B8]; TCustomCheckBox.GetChecked 0044C82E test al,al >0044C830 je 0044C8ED 0044C836 mov eax,dword ptr [ebx+32C]; TForm1.cb6:TCheckBox 0044C83C mov edx,dword ptr [eax] 0044C83E call dword ptr [edx+0B8]; TCustomCheckBox.GetChecked 0044C844 test al,al >0044C846 je 0044C8ED 0044C84C mov eax,dword ptr [ebx+358]; TForm1.cb12:TCheckBox 0044C852 mov edx,dword ptr [eax] 0044C854 call dword ptr [edx+0B8]; TCustomCheckBox.GetChecked 0044C85A test al,al >0044C85C je 0044C8ED 0044C862 mov eax,dword ptr [ebx+364]; TForm1.cb15:TCheckBox 0044C868 mov edx,dword ptr [eax] 0044C86A call dword ptr [edx+0B8]; TCustomCheckBox.GetChecked 0044C870 test al,al >0044C872 je 0044C8ED 0044C874 mov eax,dword ptr [ebx+330]; TForm1.cb20:TCheckBox 0044C87A mov edx,dword ptr [eax] 0044C87C call dword ptr [edx+0B8]; TCustomCheckBox.GetChecked 0044C882 test al,al >0044C884 je 0044C8ED 0044C886 mov eax,dword ptr [ebx+34C]; TForm1.cb9:TCheckBox 0044C88C mov edx,dword ptr [eax] 0044C88E call dword ptr [edx+0B8]; TCustomCheckBox.GetChecked 0044C894 test al,al >0044C896 je 0044C8ED 0044C898 mov eax,dword ptr [ebx+354]; TForm1.cb11:TCheckBox 0044C89E mov edx,dword ptr [eax] 0044C8A0 call dword ptr [edx+0B8]; TCustomCheckBox.GetChecked 0044C8A6 test al,al >0044C8A8 je 0044C8ED 0044C8AA mov eax,dword ptr [ebx+35C]; TForm1.cb13:TCheckBox 0044C8B0 mov edx,dword ptr [eax] 0044C8B2 call dword ptr [edx+0B8]; TCustomCheckBox.GetChecked 0044C8B8 test al,al >0044C8BA je 0044C8ED 0044C8BC mov eax,dword ptr [ebx+33C]; TForm1.cb19:TCheckBox 0044C8C2 mov edx,dword ptr [eax] 0044C8C4 call dword ptr [edx+0B8]; TCustomCheckBox.GetChecked 0044C8CA test al,al >0044C8CC je 0044C8ED 0044C8CE lea eax,[ebp-4] 0044C8D1 mov edx,44C934; 'Ìõô¸ö÷ê¥ó¤ÉÚÀÆ²Äæââîàä¶¶' 0044C8D6 call @LStrLAsg 0044C8DB lea eax,[ebp-4] 0044C8DE call 0044BF00 0044C8E3 mov eax,dword ptr [ebp-4] 0044C8E6 call ShowMessage >0044C8EB jmp 0044C90A 0044C8ED lea eax,[ebp-4] 0044C8F0 mov edx,44C958; 'Åÿæò衦óàù¨ïêçð®øé¤íüàî诹' 0044C8F5 call @LStrLAsg 0044C8FA lea eax,[ebp-4] 0044C8FD call 0044BF00 0044C902 mov eax,dword ptr [ebp-4] 0044C905 call ShowMessage 0044C90A xor eax,eax 0044C90C pop edx 0044C90D pop ecx 0044C90E pop ecx 0044C90F mov dword ptr fs:[eax],edx 0044C912 push 44C927 0044C917 lea eax,[ebp-4] 0044C91A call @LStrClr 0044C91F ret <0044C920 jmp @HandleFinally <0044C925 jmp 0044C917 0044C927 pop ebx 0044C928 pop ecx 0044C929 pop ebp 0044C92A ret
Como podéis apreciar, las checkboxes involucradas son la 3, 5, 6, 9, 11, 12, 13, 15, 19 y 20. Solo nos falta saber cuales se corresponden con esa numeración y aquí ya depende de cada uno, yo en su día saqué los números a mano mediante el orden de tabulación, pero ya que tenemos IDR, el nos va a dar la solución de una forma sencilla y rápida.
Vamos a la pestaña «Forms (F5)«, seleccionamos la opción Form y hacemos doble click sobre el formulario.
Veréis que aparece el formulario con todos los recursos, incluso los puedes modificar. Localizar los checkboxes ahora es un juego de niños.
Os dejo un vídeo.
De nuevo, con la ayuda de IDR, localizamos la parte del código y analizamos su funcionamiento. Esta parte es la más divertida ya que requiere de un keygen pero en vez de coger el número de serie de una caja de texto lo obtiene de 5 trackbars como muestra la siguiente imagen.
El código de comprobación es el siguiente.
CPU Disasm Address Hex dump Command Comments 0044C1FF |. E8 ECF6FCFF CALL 0041B8F0 ; b^3 0044C204 |. D805 50C34400 FADD DWORD PTR DS:[44C350] ; b^3+5 0044C20A |. D9FA FSQRT ; sqrt(b^3+5) 0044C20C |. E8 F365FBFF CALL 00402804 ; Cos(sqrt(b^3+5)) = U 0044C211 |. DB7D B8 FSTP TBYTE PTR SS:[EBP-48] 0044C214 |. 9B WAIT 0044C215 |. D905 54C34400 FLD DWORD PTR DS:[44C354] ; Coje a 0044C21B |. DC45 E8 FADD QWORD PTR SS:[EBP-18] ; a+1 0044C21E |. D9FA FSQRT ; sqrt(a+1) 0044C220 |. D9E0 FCHS ; -sqrt(a+1) = V 0044C222 |. DB6D B8 FLD TBYTE PTR SS:[EBP-48] 0044C225 |. DEC1 FADDP ST(1),ST 0044C227 |. DB7D AC FSTP TBYTE PTR SS:[EBP-54] 0044C22A |. 9B WAIT 0044C22B |. D905 58C34400 FLD DWORD PTR DS:[44C358] ; coje c 0044C231 |. DC4D D8 FMUL QWORD PTR SS:[EBP-28] ; c*3 0044C234 |. D805 54C34400 FADD DWORD PTR DS:[44C354] ; c*3+1 0044C23A |. D9ED FLDLN2 ; Ln(c*3+1) = X 0044C23C |. D9C9 FXCH ST(1) 0044C23E |. D9F1 FYL2X 0044C240 |. DB6D AC FLD TBYTE PTR SS:[EBP-54] 0044C243 |. DEC1 FADDP ST(1),ST ; U+V+X 0044C245 |. DB7D A0 FSTP TBYTE PTR SS:[EBP-60] 0044C248 |. 9B WAIT 0044C249 |. D905 5CC34400 FLD DWORD PTR DS:[44C35C] ; coje d 0044C24F |. DC45 D0 FADD QWORD PTR SS:[EBP-30] ; d+2 0044C252 |. D9FA FSQRT ; sqrt(d+2) = Y 0044C254 |. DB6D A0 FLD TBYTE PTR SS:[EBP-60] 0044C257 |. DEE1 FSUBRP ST(1),ST ; U+V+X+(-Y) 0044C259 |. D905 58C34400 FLD DWORD PTR DS:[44C358] ; coje e 0044C25F |. DC4D C8 FMUL QWORD PTR SS:[EBP-38] ; e*3 0044C262 |. D835 5CC34400 FDIV DWORD PTR DS:[44C35C] ; (e*3)/2 = Z 0044C268 |. DEC1 FADDP ST(1),ST ; U+V+X+Y+Z 0044C26A |. DB2D 60C34400 FLD TBYTE PTR DS:[44C360] 0044C270 |. DEC1 FADDP ST(1),ST ; U+V+X+Y+Z+0.37 0044C272 |. D80D 6CC34400 FMUL DWORD PTR DS:[44C36C] ; (U+V+X+Y+Z+0.37)*1000 0044C278 |. DD5D F0 FSTP QWORD PTR SS:[EBP-10] 0044C27B |. 9B WAIT 0044C27C |. DD45 F0 FLD QWORD PTR SS:[EBP-10] 0044C27F |. E8 9065FBFF CALL 00402814 ; Redondea((U+V+X+Y+Z+0,37)*1000) 0044C284 |. 8945 98 MOV DWORD PTR SS:[EBP-68],EAX 0044C287 |. 8955 9C MOV DWORD PTR SS:[EBP-64],EDX 0044C28A |. DF6D 98 FILD QWORD PTR SS:[EBP-68] 0044C28D |. 83C4 F4 ADD ESP,-0C 0044C290 |. DB3C24 FSTP TBYTE PTR SS:[LOCAL.33] 0044C293 |. 9B WAIT 0044C294 |. 8D45 FC LEA EAX,[EBP-4] 0044C297 |. E8 68BFFBFF CALL 00408204 0044C29C |. 8D45 FC LEA EAX,[EBP-4] 0044C29F |. E8 5CFCFFFF CALL 0044BF00 ; Llamada de generación de hash ........ 0044BF04 |. 8BF0 MOV ESI,EAX 0044BF06 |. 8B06 MOV EAX,DWORD PTR DS:[ESI] ; EAX = 5415 0044BF08 |. E8 677BFBFF CALL 00403A74 0044BF0D |. 8B15 98EE4400 MOV EDX,DWORD PTR DS:[44EE98] 0044BF13 |. 8902 MOV DWORD PTR DS:[EDX],EAX 0044BF15 |. 8B06 MOV EAX,DWORD PTR DS:[ESI] 0044BF17 |. E8 587BFBFF CALL 00403A74 0044BF1C |. 84C0 TEST AL,AL 0044BF1E |. 76 38 JBE SHORT 0044BF58 0044BF20 |. 880424 MOV BYTE PTR SS:[LOCAL.3],AL 0044BF23 |. B3 01 MOV BL,1 0044BF25 |> B8 1C000000 /MOV EAX,1C 0044BF2A |. E8 516AFBFF |CALL 00402980 0044BF2F |. 0D 80000000 |OR EAX,00000080 0044BF34 |. 8BFB |MOV EDI,EBX 0044BF36 |. 81E7 FF000000 |AND EDI,000000FF 0044BF3C |. 8B16 |MOV EDX,DWORD PTR DS:[ESI] 0044BF3E |. 0FB6543A FF |MOVZX EDX,BYTE PTR DS:[EDI+EDX-1] ; Coje dig a dig el hash, en este caso 5415 0044BF43 |. 33C2 |XOR EAX,EDX ; 1 dig XOR 83; 2 dig XOR 89; 3 dig XOR 86; 4 dig XOR 8D 0044BF45 |. 50 |PUSH EAX 0044BF46 |. 8BC6 |MOV EAX,ESI 0044BF48 |. E8 F77CFBFF |CALL 00403C44 0044BF4D |. 5A |POP EDX 0044BF4E |. 885438 FF |MOV BYTE PTR DS:[EDI+EAX-1],DL 0044BF52 |. 43 |INC EBX 0044BF53 |. FE0C24 |DEC BYTE PTR SS:[LOCAL.3] 0044BF56 |.^ 75 CD \JNZ SHORT 0044BF25 ........ 0044C2AC |. E8 D378FBFF CALL 00403B84 ; Llamada a comparación ........ 00403BAD |> /8B0E /MOV ECX,DWORD PTR DS:[ESI] ; ECX = nuestro Serial XOReado 00403BAF |. |8B1F |MOV EBX,DWORD PTR DS:[EDI] ; EBX = Serial bueno 00403BB1 |. |39D9 |CMP ECX,EBX ; Compara 00403BB3 |. |75 58 |JNE SHORT 00403C0D ; Chico malo 00403BB5 |. |4A |DEC EDX 00403BB6 |. |74 15 |JZ SHORT 00403BCD 00403BB8 |. |8B4E 04 |MOV ECX,DWORD PTR DS:[ESI+4] 00403BBB |. |8B5F 04 |MOV EBX,DWORD PTR DS:[EDI+4] 00403BBE |. |39D9 |CMP ECX,EBX 00403BC0 |. |75 4B |JNE SHORT 00403C0D 00403BC2 |. |83C6 08 |ADD ESI,8 00403BC5 |. |83C7 08 |ADD EDI,8 00403BC8 |. |4A |DEC EDX 00403BC9 |.^\75 E2 \JNZ SHORT 00403BAD
En resumen
1) Siendo nuestro serial : 1 2 3 4 5
a b c d e
2) Realiza las operaciones matemáticas:
Round(((Cos(sqrt(b^3+5)) + (-sqrt(a+1)) + Ln(c*3+1) + (-sqrt(d+2)) + ((e*3)/2))+0.37)*1000))
3) Obtenemos un hash resultante de 5415
4) XORea los dígitos de la siguiente manera:
(5)35 xor 86 = B6
(4)34 xor 83 = BD
(1)31 xor 86 = B7
(5)35 xor 8D = B8
De modo que tenemos B6BDB7B8
5) Compara B6BDB7B8 con B5BAB2BA
6) Revertimos el XOR para obtener el hash bueno
B5 xor 86 = 36(6)
BA xor 83 = 33(3)
B2 xor 86 = 34(4)
BA xor 8D = 37(7)
Luego el hash bueno es 6347
7) Debemos hacer fuerza bruta buscando:
Round(((Cos(sqrt(b^3+5)) + (-sqrt(a+1)) + Ln(c*3+1) + (-sqrt(d+2)) + ((e*3)/2))+0.37)*1000)) = 6347
Para obtener los seriales válidos podemos hacer bucles recursivos hasta recorrer las 10^5 opciones posibles. Una forma de hacerlo en VBNet es la siguiente.
Dim tmp As Double
Dim an, bn, cn, dn, en As Integer
For an = 0 To 9
For bn = 0 To 9
For cn = 0 To 9
For dn = 0 To 9
For en = 0 To 9
tmp = Round(((Cos(Sqrt((Pow(bn, 3)) + 5)) + (-Sqrt(an + 1)) + Log(cn * 3 + 1) + (-Sqrt(dn + 2)) + ((en * 3) / 2) + 0.37) * 1000))
txtdebug.Text = "a-b-c-d-e = Hash || " & an & "-" & bn & "-" & cn & "-" & dn & "-" & en & " = " & tmp
If tmp = 6347 Then
ListBox1.Items.Add("Serial: " & an & bn & cn & dn & en)
End If
Application.DoEvents()
Next
Next
Next
Next
Next
Os dejo como siempre el crackme y el keygen en los enlaces.

Hace unos días intenté contactar con Karpoff ya que fué una inspiración para mi y muchos otros, lo conseguí y se me ocurrió hacerle una entrevista, aquí tenéis el resultado.
Para los recién llegados diré que, Karpoff Spanish Tutor era (y sigue siendo aunque no se actualice), una gran web colaborativa donde encontrar cantidad de manuales y programas en Castellano.
deurus: ¿Qué te llevó a realizar la web?, es decir, que te hizo levantarte una mañana y decir, venga, voy a realizar una web sobre ingeniería inversa.
Karpoff: Pues mira, fue de la siguiente manera. Por aquel entonces (te hablo de los 90 y poco) yo pasaba mi tiempo libre intentando saltar las protecciones de los programas que conseguía generalmente en revistas de informática.
Desconocía que existía un mundillo dedicado a esas artes.
En los años 90 no había internet ni nada parecido que yo sepa, sobre el 95 creo recordar, telefónica saco una cosa que se llamaba Infobia y era una especie de intranet de telefónica donde accedías a un contenido muy limitado, pero te permitía salir de alguna manera bastante limitada también a lo que conocemos como internet (todo era mega lento, velocidades de uno o dos kb por segundo) con módem y llamadas analógicas.
No se como, ya que no existia o no era conocido Google tampoco había casi buscadores, conocí la famosa y maravillosa pagina de «Fravia» dedicada a la ingeniería inversa con muchísima documentación, y proyectos de estudio de protecciones, lamentablemente para el momento hispano, toda la documentación estaba en ingles .
Investigando conocí paginas hispanas con proyectos interesantes (aunque muchas de ellas aun siendo hispanas publicaban todo en ingles)
Conocí también otra pagina, el “ECD” estudio colectivo de desprotecciones + WTK en castellano e ingles que me sorprendió gratamente y donde se publicaban proyectos propios del grupo WTK y de otros grupos como estado+porcino.
los tres grupos hispanos del momento eran WTK, TNT y KUT, pertenecí a TNT durante algún tiempo, aunque el objetivo del grupo no me convencía ya que era exclusivamente la creación de cracks a mansalva por lo que no estuve más de un año.
Yo echaba de menos un sitio como “Fravia” pero en castellano donde todos los interesados pudiéramos colaborar y ayudarnos con temas de ingeniería inversa.
Ya en los 90 y mucho, todo lo relacionado con internet había evolucionado bastante, las conexiones también eran mas rápidas, ya no hacia falta conectarte a infobia sino directamente a internet.
Yo disponía de mucho tiempo libre y empecé un proyecto en solitario “Karpoff Spanish Tutor” mas conocido como “la pagina de karpoff” con proyectos de mi cosecha y con temas que me gustaban mucho, como la programación, los compiladores el software en general etc.
Luego todo lo demás fue llegando poco a poco, a la gente le gustaba y tenia muchísimas ganas de aprender y sobre todo de colaborar.
El proyecto alcanzo unos niveles impresionantes en cuanto a colaboración y recepción de material, había días que estaba mas de 14 horas actualizando la pagina y buscando nuevos servidores para alojarla, ya que me los cerraban casi semanalmente. Y la verdad.. cada vez me costaba mas tiempo mantener la pagina.
Luego gracias a Red Futura tuvimos un hostin de calidad y gratuito.
El proyecto era tan amplio que me fue imposible conciliar vida laboral y vida en internet todo esto empezaba a ser incompatible.
deurus: ¿Empezaste solo o erais un grupo de amiguetes?
Karpoff: Esta te la he contestado en la primera pregunta, vamos… que empecé yo solo.
deurus: ¿Echas de menos el proyecto?
Karpoff: Hoy en día no. Hace falta muchísimo tiempo libre y muchísima dedicación a nivel organizativo.
Echo de menos el movimiento que se creo y la actividad que alcanzo el movimiento cracking hispano. Salían grupos de cracker con nuevos proyectos y paginas hasta de debajo de las piedras 🙂 la ingenieria inversa se puso un poco de moda, conocí a gente muy interesante como Ricardo Narvaja, Numi_tor, Demian y muchas otras personas con muchos conocimientos.
Después de cerrar la pagina todo se quedo un poco cojo y todo el movimiento se empezó a diluir bastante rápido.
deurus: ¿Lo retomarías día de hoy?
Karpoff: La verdad es que no, ya no es mi tiempo, ahora me dedico al trabajo y mi familia y en ratos libres intento reventar algún programa. Sobre todo crackmes.
deurus: ¿Tienes o colaboras activamente en algún proyecto relacionado con la Ingeniería Inversa?
Karpoff: No, no tengo tiempo. Mantengo contacto por correo con gente de que conocí en esa época y me sorprende que la gente no se olvida de mí. Recibo bastante correo en esta cuenta pidiéndome alguna entrevistilla, opiniones y muchos muchos agradecimientos de mucha gente por la página.
deurus: Yo por aquel entonces tenía 17 años, ¿se le puede preguntar la edad a Karpoff?
Karpoff: Pues yo tengo 45, por aquel entonces tenia unos 29 . La ingeniería inversa siempre fue mi pasión. Desde bien pequeño mi obsesión ha sido conocer como y porque funcionaba todo 🙂 hasta el punto de desmontar todo aquello que me llamaba la atención, mi madre estaba desesperada ya que dejaba todo destripado y muchas veces sin posiblilidad de reparacion.
deurus: ¿Te dedicas a algo relacionado con la informática?
Karpoff: Si, desde esos tiempos me encargo de los sistemas informáticos y equipos técnicos de una empresa bastante conocida, además ese fue uno de los principales motivos del cierre de la página.
Hubo gente interesada en seguir con el proyecto, aunque finalmente todo quedó en nada. Supongo que vieron que el proyecto requería muchísimo tiempo y mucho mucho trabajo.
Me dio mucha lastima no poder seguir con la página y mucha más que nadie se hiciera cargo de ella.
No hace mucho al desaparecer los redireccionadores “come.to” adquirí un dominio “karpoff.es” donde enlace tres mirror de la página para dejar un punto de acceso a ellos.
deurus: Finalmente ¿quieres decir algo a los lectores?
Karpoff: Pues sí, sobre todo dar las gracias a los que me conocen y tuvieron relación con la página, siempre me han hecho sentir grande y siempre tuve mucha colaboración y muchos ánimos por parte de los lectores.
Para los que no me conocen y les gusta la ingeniería inversa, decirles que lo que se aprende crackeando no lo enseñan en ningún sitio 🙂 y es muy muy gratificante.
deurus: Muchas gracias por tu atención, ha sido un placer.
Karpoff: Muchas gracias a ti, me ha hecho mucha ilusión y me ha gustado mucho tu blog.
Saludos !!
Karpoff

La película «Contact«, estrenada en 1997 y dirigida por Robert Zemeckis, es una adaptación de la novela homónima de Carl Sagan. Más allá de su profunda exploración sobre la existencia de vida extraterrestre y el debate entre ciencia y fe, la película ofrece un interesante vistazo a la tecnología de la época. En este análisis, nos enfocaremos en los aspectos tecnológicos presentes en la película, detallando los sistemas operativos, software y hardware utilizados por los protagonistas.
La Dra. Eleanor «Ellie» Arroway, interpretada por Jodie Foster, es una científica dedicada al proyecto SETI (Búsqueda de Inteligencia Extraterrestre). Tras años de búsqueda, capta una señal proveniente del espacio profundo que contiene instrucciones para construir una máquina enigmática. A medida que se desarrolla la trama, Ellie enfrenta desafíos políticos, religiosos y personales mientras lucha por interpretar el mensaje y lo que podría significar para la humanidad.
Uno de los aspectos más destacados en Contact es la presencia del sistema operativo UNIX. A lo largo de la película, se observan pistas que indican su uso, como pegatinas en las pantallas con mensajes del estilo: «Join the UNIX PARTY (The open system platform)». UNIX, desarrollado en la década de 1970, es conocido por su estabilidad y eficiencia, características esenciales en entornos científicos y de investigación.
La utilización de Netscape Navigator es recurrente. El logo de Netscape aparece en varias ocasiones, especialmente durante las videoconferencias que se muestran sin retrasos apreciables. Netscape fue uno de los primeros navegadores web ampliamente utilizados y jugó un papel crucial en la expansión de Internet durante los años 90.
Es importante destacar que, aunque la película promueve la idea de sistemas abiertos a través del uso de UNIX, Netscape Navigator no era software libre en el momento en que se rodó la película. Durante esa época, antes de 1997, Netscape era un navegador propietario. Sin embargo, en sistemas UNIX, Netscape tenía poca competencia y era el navegador predominante, soportando estándares abiertos como HTTP y HTML. Curiosamente, en 1998, poco después del estreno de la película, Netscape liberó el código fuente de su navegador, iniciando el proyecto Mozilla y contribuyendo significativamente al movimiento del software libre.
El software o plataforma denominada MADDEN HADDEN es utilizado por los protagonistas en diversas localizaciones, sugiriendo que es un estándar en su campo. Aunque en la realidad no existe un software conocido con ese nombre en el ámbito científico, en la película parece ser una herramienta integral para el análisis de datos y comunicación.
Las videoconferencias sin «lags» (retrasos) que se muestran en la película son notables, especialmente considerando las limitaciones tecnológicas de la época. La presencia del logo de Netscape durante estas comunicaciones resalta el optimismo sobre las capacidades de Internet en 1997. En ese entonces, las conexiones de alta velocidad no eran comunes, y las videollamadas de calidad eran más una aspiración que una realidad.
La promoción de sistemas abiertos es evidente en la película. El uso de UNIX, basado en estándares abiertos, refleja una filosofía de colaboración y accesibilidad en el ámbito científico. Aunque Netscape Navigator no era software libre durante la producción de la película, su soporte para estándares abiertos de Internet lo convirtió en una herramienta esencial para la comunicación y el intercambio de información entre científicos y profesionales.
En términos de hardware, la película presenta una variedad de equipos representativos de la tecnología de los años 90:
Monitor NEC MultiSync XE21: Un monitor CRT de 21 pulgadas conocido por su alta resolución y calidad de imagen, ideal para aplicaciones que requieren detalles precisos.
Monitores con marcas ocultas: Es interesante notar que en varios monitores se utilizan post-its o adhesivos para cubrir la marca y el modelo. Esto podría deberse a decisiones de producción para evitar publicidad no deseada o cuestiones legales relacionadas con derechos de marca.
Monitor CTX: Aunque no se especifica el modelo, los monitores CTX eran populares por su fiabilidad y rendimiento a un costo razonable.
Monitor Hansol Mazellan 17px: Los monitores Hansol eran reconocidos por su calidad en la reproducción de gráficos, siendo utilizados en diseño y aplicaciones multimedia.
Monitor IBM: IBM fue pionera en tecnología informática, y sus monitores eran sinónimo de calidad y durabilidad. Aunque no se especifica el modelo exacto, es probable que se trate de uno de sus populares monitores CRT utilizados en entornos profesionales.
Para entender el contexto tecnológico de la época, es útil comparar la evolución de UNIX y Windows, así como de los navegadores Netscape Navigator e Internet Explorer.
Cobertura de marcas: La práctica de cubrir las marcas y modelos en los monitores podría indicar un intento de la producción por crear un entorno más universal y atemporal, evitando asociar la tecnología presentada con productos específicos que podrían quedar obsoletos rápidamente. En bastantes fotogramas se nota que esto es completamente intencionado.
Representación de la tecnología: La película equilibra la precisión técnica con las necesidades narrativas. Si bien algunas representaciones, como las videoconferencias fluidas, eran tecnológicamente avanzadas para la época, sirven para enfatizar la conectividad y colaboración global entre los científicos.
SETI y la Búsqueda de Vida Extraterrestre: En Contact, la Dra. Ellie Arroway dedica su vida al proyecto SETI (Search for Extraterrestrial Intelligence), reflejando el esfuerzo real de la comunidad científica por encontrar señales de inteligencia extraterrestre. SETI es una iniciativa internacional que utiliza radiotelescopios para detectar posibles comunicaciones de civilizaciones fuera de la Tierra. La película captura la pasión y los desafíos asociados con este tipo de investigación, destacando la dedicación de los científicos que trabajan en el límite de lo conocido.
El Mensaje de Arecibo: El radiotelescopio de Arecibo en Puerto Rico juega un papel significativo tanto en la realidad como en la película. En 1974, desde este observatorio, se envió el famoso Mensaje de Arecibo, una transmisión de radio dirigida al cúmulo estelar M13, diseñada para demostrar los avances tecnológicos humanos y nuestra existencia a posibles civilizaciones extraterrestres. El mensaje contenía información codificada sobre la composición humana, nuestro sistema numérico, la estructura del ADN y nuestra posición en el sistema solar. En «Contact», aunque la señal recibida por Ellie proviene de Vega y no está directamente relacionada con el Mensaje de Arecibo, la película establece paralelismos con este acontecimiento histórico. La utilización de Arecibo como escenario subraya la conexión entre los esfuerzos reales y ficticios en la búsqueda de inteligencia extraterrestre. La película explora la posibilidad de que, así como enviamos mensajes al espacio, podríamos recibir respuestas o comunicaciones de otras civilizaciones.
Matthew McConaughey: Es interesante notar cómo este actor ha participado en dos de las películas más destacadas de la ciencia ficción: Contact e Interstellar. En Contact, McConaughey interpreta un papel secundario como Palmer Joss, un escritor y asesor espiritual que cuestiona las implicaciones éticas y filosóficas del descubrimiento científico. Diecisiete años después, en Interstellar, asume el rol protagonista de Cooper, un ex piloto de la NASA que emprende una misión interestelar para salvar a la humanidad.
Números primos: El inicio de la investigación seria de la señal extraterrestre en la película se desencadena cuando, al analizar la señal recibida, los científicos descubren que esta codifica una secuencia de números primos. Este hallazgo resulta crucial, ya que los números primos, al ser divisibles únicamente por 1 y por sí mismos, no surgen de forma aleatoria en procesos naturales conocidos. Su presencia en la señal sugiere intencionalidad e inteligencia detrás de su emisión, lo que confirma que no se trata de ruido cósmico sino de una posible comunicación deliberada desde una civilización avanzada. Este descubrimiento impulsa a los científicos a profundizar en la decodificación, marcando el verdadero inicio de la búsqueda de vida extraterrestre.
Contact no solo es una obra que invita a reflexionar sobre nuestro lugar en el universo y la posibilidad de vida más allá de la Tierra, sino que también es un retrato de la tecnología de su tiempo. La inclusión de sistemas operativos como UNIX, navegadores como Netscape y hardware específico refleja una atención al detalle que enriquece la narrativa. A pesar de que Netscape Navigator no era software libre durante la producción de la película, su presencia destaca la importancia de los estándares abiertos y la colaboración en el avance científico.
También destaca por su compromiso con la precisión científica, en gran parte debido a la influencia de Carl Sagan, autor de la novela original y asesor en la producción. La representación de los procedimientos del SETI, el análisis de señales y las discusiones éticas y filosóficas reflejan debates reales en la comunidad científica. La inclusión de elementos como el Mensaje de Arecibo y las operaciones del radiotelescopio añaden autenticidad a la narrativa y acercan al público a la realidad de la exploración espacial.



























































































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.
This crackme is for the crack challenge 6 of canyouhack.it.

AVISO: Debido a que este reto está en activo no publicaré a donde pertenece.
En este reto stego nos proporcionan un archivo MP3 y nos dan una pequeña pista con el título.
Inicialmente lo pasé con GoldWave y me fijé en el la parte de control en el SPECtrogram y en el SPECtrum, pero no conseguí ver nada. A punto de rendirme di con un programa online llamado SPEK, que me dio la respuesta al instante.

Se puede apreciar una palabra que escrita en Inglés nos da la solución al reto.


Se nos proporciona la imagen anterior y se nos invita a resolver la ecuación para el menor entero positivo que representa cada fruta. La solución del reto es concatenar «Flag-» a la suma de los valores de las tres frutas.
El enunciado es breve pero ya nos adelanta que existen varias soluciones y que además sólo quieren los números más pequeños que podamos encontrar.
Las frutas están muy bien y son muy sanas pero a nosotros se nos hace más sencillo plantear la ecuación con letras.
\begin{align}
& \frac{x}{y+z}+\frac{y}{x+z}+\frac{z}{x+y}=4\\
\end{align}Para arrojar algo de luz veamos la representación gráfica en 2D y 3D con la ayuda de Desmos.

Las gráficas más que luz nos traen oscuridad de modo que preguntemos a ChatGPT.

resuelve: (x/y+z)+(y/x+z)+(z/x+y)=4 para enteros positivos

Dado que las variables x, y, z son enteros positivos, podemos intentar encontrar una solución para la ecuación bajo estas condiciones. Sin embargo, encontrar una solución exacta puede ser complejo debido a la naturaleza no lineal de la ecuación. Aun así, podemos intentar algunos enfoques:
Voy a realizar un análisis numérico con un rango limitado de valores para ver si encontramos alguna solución que cumpla con las condiciones. Vamos a probar con valores de 1 a 10 para cada variable.
El análisis numérico para valores de en el rango de 1 a 10 no ha encontrado ninguna solución que satisfaga la ecuación. Esto sugiere que, dentro de este rango, no existen combinaciones de enteros positivos que cumplan con la ecuación.
Dado que la ecuación es bastante compleja y no lineal, es posible que las soluciones, si existen, se encuentren fuera del rango considerado o que requieran un enfoque diferente para ser identificadas. Si tienes un rango específico de valores en mente o si hay alguna otra restricción o contexto relevante, por favor házmelo saber para poder ajustar el análisis en consecuencia.
Básicamente nos está invitando a utilizar prueba y error para encontrar una solución, y el prueba y error de las matemáticas no es más que la fuerza bruta en programación.

Partiendo del problema anterior dame un código en python que realice una comprobación recursiva de todas las variables con un rango de 1 a 999.

soluciones = []
rango_valores_x = range(1, 999)
rango_valores_y = range(1, 999)
rango_valores_z = range(1, 999)
for x in rango_valores_x:
for y in rango_valores_y:
for z in rango_valores_z:
# Calculamos el valor de la expresión para cada combinación de x, y, z
valor = x / (y + z) + y / (x + z) + z / (x + y)
# Comprobamos si el valor es igual a 4 y agregamos la solución a la lista
if abs(valor - 4) < 1e-6: # Usamos una pequeña tolerancia para evitar errores de precisión
soluciones.append((x, y, z))
print(soluciones)
Dejo resaltada la línea 12 del código ya que en ella reside el problema. Está comprobando con un margen de tolerancia de 10-6 ya que el resultado de las diferentes fracciones no da como resultado exacto 4. Esto es un problema ya que nosotros necesitamos que de exactamente 4 para validar los valores enteros de x, y y z. Pongo un ejemplo para el que se haya perdido con una solución válida para la tolerancia 10-6 siendo x=2, y=264 y z=993.
\begin{align}
& \frac{2}{264+993}+\frac{264}{2+993}+\frac{993}{2+264}=4.000000429\\
\end{align}En otras palabras, ChatGPT nos ha brindado una solución aproximada que no sirve para nuestro propósito. Seguimos probando con el código anterior quitando la tolerancia y con rangos mayores hasta que en 106 paro. Me acaba de quedar claro que con la fuerza bruta no vamos a ninguna parte, o más bien, no tenemos capacidad de computación para resolverlo de ésta manera.
Lo que pasa es que estamos ante una ecuación algebraica de 3 incógnitas que deben ser enteros positivos cuya solución se alcanza mediante la teoría de curvas elípticas.
Las curvas elípticas son fundamentales en matemáticas avanzadas, representadas por la ecuación y2=x3+Ax+B, donde A y B son constantes. Estas curvas son un punto de encuentro entre la geometría, la teoría de números y el álgebra, ofreciendo un campo rico para la exploración y el análisis. En este CTF, nos enfocaremos en los puntos racionales de las curvas elípticas. Utilizando el método tangente-secante, un procedimiento geométrico iterativo, buscaremos ampliar un conjunto finito de soluciones conocidas a la ecuación de la curva. Este método nos permite indagar en la estructura de las soluciones racionales, que potencialmente pueden ser infinitas. Además, estableceremos una conexión entre las soluciones enteras de las ecuaciones diofánticas y los puntos racionales en las curvas elípticas partiendo de la ecuación (1) especificada en el análisis inicial. A pesar de su aparente simplicidad, esta ecuación es conocida por presentar soluciones mínimas de gran tamaño.
Antes de nada, necesitamos saber el grado de la ecuación, de modo que planteamos la ecuación en forma polinómica estándar deshaciéndonos de los denominadores.
\begin{align}
\begin{split}
n(a+b)(b+c)(c+a)=a(a+b)(c+a)+b(b+c)(a+b)+c(c+a)(b+c)
\end{split}
\end{align}Ahora necesitamos expandir y simplificar para llegar a la conclusión de que estamos ante una ecuación diofántica de grado 3. Este proceso es engorroso por la cantidad de términos a manejar así que vamos a utilizar Mathematica como software de respaldo para finalmente obtener el polinomio en la forma de Weierstrass según la ecuación 4.
\begin{align}
& y^2=x^3+109x^2+224x\\
\end{align}donde:
\begin{align}
x = \frac{−28(a+b+2c)}{(6a+6b−c)}\\
y = \frac{364(a−b)}{(6a+6b−c)}
\end{align}Las relación entre la ecuación 3 y los puntos de la curva elíptica se establecen mediante la ecuación 4. Las transformaciones entre las soluciones (a, b, c) y los puntos (x, y) en la curva elíptica vienen dados por las ecuaciones 5 y 6. Con estas transformaciones, cada solución de la ecuación diofántica se puede representar como un punto en la curva elíptica, y las operaciones de suma de puntos en la curva elíptica pueden usarse para encontrar nuevas soluciones de la ecuación diofántica.
El código que tenéis a continuación pertenece al gran trabajo de Aditi Kulkarni [7], que además nos da el resultado para cualquier valor de n. Ojo porque para n=4 el resultado tiene 81 dígitos, para n=6 tiene 134, para n=10 tiene 190 y para n=12 asciende a 2707 dígitos.
(* Asignar un valor numérico a n *)
n = 4;
(* Definir la ecuación de una curva elíptica en términos de n *)
curve4 = y^2 == x^3 + (4*n^2 + 12*n - 3)*x^2 + 32*(n + 3)*x;
(* Encontrar un punto racional en la curva que no sea (4,0) *)
P4 = {x, y} /. First[FindInstance[curve4 && x != 4 && y != 0, {x, y}, Integers]];
(* Función para calcular la pendiente entre dos puntos en la curva,
o la derivada en el punto si son iguales *)
Slope4[{x1_, y1_}, {x2_, y2_}] :=
If[x1 == x2 && y1 == y2,
ImplicitD[curve4, y, x] /. {x -> x1, y -> y1},
(y2 - y1)/(x2 - x1)];
(* Función para calcular la intersección en y de la línea entre dos puntos
o la tangente en el punto si son iguales *)
Intercept4[{x1_, y1_}, {x2_, y2_}] := y1 - Slope4[{x1, y1}, {x2, y2}]*x1;
(* Función para encontrar el siguiente punto racional en la curva *)
nextRational4[{x1_, y1_}, {x2_, y2_}] :=
{Slope4[{x1, y1}, {x2, y2}]^2 - CoefficientList[curve4[[2]], x][[3]] - x1 - x2,
-Slope4[{x1, y1}, {x2, y2}]^3 + Slope4[{x1, y1}, {x2, y2}]*(CoefficientList[curve4[[2]], x][[3]] + x1 + x2) - Intercept4[{x1, y1}, {x2, y2}]};
(* Función para convertir un punto en la curva elíptica a una solución diofántica *)
ellipticToDiophantine[n_, {x_, y_}] :=
{(8*(n + 3) - x + y)/(2*(4 - x)*(n + 3)),
(8*(n + 3) - x - y)/(2*(4 - x)*(n + 3)),
(-4*(n + 3) - (n + 2)*x)/((4 - x)*(n + 3))};
(* Usar nextRational4 para iterar desde P4 hasta encontrar una solución
válida y positiva para la ecuación diofántica *)
sol4 = ellipticToDiophantine[n,
NestWhile[nextRational4[#, P4] &, P4,
! AllTrue[ellipticToDiophantine[n, #], Function[item, item > 0]] &]];
(* Escalar la solución para obtener enteros mínimos *)
MinSol4 = sol4*(LCM @@ Denominator[sol4])
(* Suma de las tres variables*)
Total[MinSol4]
Concatenando Flag- con el resultado de Mathematica tenemos la ansiada flag.
Flag-195725546580804863527010379187516702463973843196699016314931210363268850137105614
ChatGPT ha demostrado ser eficaz en el análisis y la resolución de problemas, siempre que se le proporcione el contexto adecuado. Sin embargo, es importante ser conscientes de que la respuesta proporcionada puede ser aproximada, especialmente si la solución requiere una gran cantidad de recursos computacionales. Por ejemplo, al trabajar con una ecuación diofántica y valores específicos para (x) e (y), ChatGPT puede ayudar a calcular puntos como (P), (2P), (3P), etc., pero hay que tener en cuenta que los resultados para estos puntos pueden ser estimaciones.
Finalmente, os invito a leer la solución de Mingliang Z. [4], en la que se resuelve el problema por completo y de forma muy detallada.

Esta vez vamos a analizar los CrackMes de un antiguo colaborador de Karpoff Spanish Tutor, CrkViZ. En estas cinco soluciones vamos a pelearnos con Visual Basic 5/6 nativo y Pcode, con el registro de Windows y tendremos que parchear algúna rutina antidebug. Los CrackMes son del año 2000 y aunque algunos estaban ya solucionados, los analizaremos igualmente para ver la diferencia que existe con los análisis realizados en aquellos años, sí, estamos hablando del Softice.
Cuando hablamos de Visual Basic 5/6, podemos destacar 3 herramientas que nos facilitan mucho la vida, VB Decompiler, VB Reformer y ExDec. Las dos primeras se defienden bien tanto con código nativo como pcode y ExDec solamente nos sirve para pcode. Aún así, si todo lo demás falla, Ollydbg nos sacará de apuros.
Este primer crackme está compilado en Pcode y hoy día, con las herramientas de que disponemos no supone ninguna dificultad. Tan solo debemos abrirlo con VB Decompiler y ya nos encontramos con el serial válido.
Los opcodes obtenidos con ExDec se ven de la siguiente manera.
...... 402F14: 04 FLdRfVar local_008C 402F17: 21 FLdPrThis 402F18: 0f VCallAd 7b3fc340 402F1B: 19 FStAdFunc local_0088 402F1E: 08 FLdPr local_0088 402F21: 0d VCallHresult 7b3fbe88 402F26: 6c ILdRf local_008C 402F29: 1b LitStr: 57230198 <-------------- 402F2C: Lead0/30 EqStr 402F2E: 2f FFree1Str local_008C 402F31: 1a FFree1Ad local_0088 402F34: 1c BranchF: 403012 402F37: 21 FLdPrThis 402F38: 0d VCallHresult 7b3fc2b0 402F3D: 3a LitVarStr: ( local_00AC ) Gracias por Registrar!! 402F42: Lead2/00 FStVarCopy 402F46: 27 LitVar_Missing 402F49: 27 LitVar_Missing 402F4C: 3a LitVarStr: ( local_00AC ) CrkViz 402F51: 4e FStVarCopyObj local_00BC 402F54: 04 FLdRfVar local_00BC 402F57: f5 LitI4: 0x40 64 (...@) 402F5C: 04 FLdRfVar local_009C 402F5F: 0a ImpAdCallFPR4: _rtcMsgBox 402F64: 36 FFreeVar 402F6D: 27 LitVar_Missing 402F70: 25 PopAdLdVar 402F71: 27 LitVar_Missing ......
Este segundo crackme también está compilado en pcode. La rutina del serial es muy sencilla pero al introducir un número aleatorio nos obliga a parchear. Cargamos el crackme en VB Decompiler y nos muestra esto:
Básicamente vemos que genera un número aleatorio entre 1 y 999999999 y luego le suma 1. La forma de afrontar esto es parcheando. Nos fijamos en el offset aproximado (4037F2) y abrimos el crackme en un editor hexadecimal. La forma de convertir el offset que nos muestra VB Decompiler a lo que nos muestra un editor hexadecimal es la siguiente.
VBdec_offset - Image Base - VirtualOffset + RawOffset = Offset_Editor.H 4037F2 - 400000 - 1000 + 400 = 2BF2
Una vez localizados los bytes, los cambiamos por ceros y guardamos.
Una vez parcheado, el serial correcto es 1.
En esta tercera entrega, CrkViz aumentó la dificultad. El crackme está compilado en código nativo y nos enfrentamos a un serial asociado a un nombre y a una rutina antidebug que en realidad es una Nag, ya que se muestra siempre.
Afrontar la nag es muy sencillo, basta con localizarla y parchear la llamada.
CPU Disasm Address Hex dump Command Comments 004058E2 8D4D DC LEA ECX,[EBP-24] 004058E5 C785 BCFDFFFF B MOV DWORD PTR SS:[EBP-244],CrkMeViz-3.004033B8 ; UNICODE " Debugger detectado!!! " 004058EF C785 B4FDFFFF 0 MOV DWORD PTR SS:[EBP-24C],8 004058F9 FFD7 CALL EDI 004058FB B9 04000280 MOV ECX,80020004 00405900 B8 0A000000 MOV EAX,0A 00405905 898D FCFDFFFF MOV DWORD PTR SS:[EBP-204],ECX 0040590B 898D 0CFEFFFF MOV DWORD PTR SS:[EBP-1F4],ECX 00405911 8D95 B4FDFFFF LEA EDX,[EBP-24C] 00405917 8D8D 14FEFFFF LEA ECX,[EBP-1EC] 0040591D 8985 F4FDFFFF MOV DWORD PTR SS:[EBP-20C],EAX 00405923 8985 04FEFFFF MOV DWORD PTR SS:[EBP-1FC],EAX 00405929 C785 BCFDFFFF 8 MOV DWORD PTR SS:[EBP-244],CrkMeViz-3.00403188 ; UNICODE "Error" 00405933 C785 B4FDFFFF 0 MOV DWORD PTR SS:[EBP-24C],8 0040593D FF15 C8914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDup>] 00405943 8D85 F4FDFFFF LEA EAX,[EBP-20C] 00405949 8D8D 04FEFFFF LEA ECX,[EBP-1FC] 0040594F 50 PUSH EAX 00405950 8D95 14FEFFFF LEA EDX,[EBP-1EC] 00405956 51 PUSH ECX 00405957 52 PUSH EDX 00405958 8D45 DC LEA EAX,[EBP-24] 0040595B 6A 10 PUSH 10 0040595D 50 PUSH EAX 0040595E FF15 50914000 CALL DWORD PTR DS:[<&MSVBVM50.#595>] ; rtcMsgBox - NOPear para evitar la NAG 00405964 8D8D F4FDFFFF LEA ECX,[EBP-20C]
Antes de llegar al keygen vemos que realiza unas llamadas al registro de Windows, ponemos un breakpoint «bp RegOpenKeyW» y ejecutamos.
CPU Disasm Address Hex dump Command Comments 00405677 |. 8B8D B8FDFFFF MOV ECX,DWORD PTR SS:[EBP-248] 0040567D |. B8 54334000 MOV EAX,CrkMeViz-3.00403354 ; UNICODE "<Unregister>" 00405682 |. 68 B4304000 PUSH CrkMeViz-3.004030B4 ; UNICODE "Serial number" 00405687 |. 894A 04 MOV DWORD PTR DS:[EDX+4],ECX 0040568A |. 8985 BCFDFFFF MOV DWORD PTR SS:[EBP-244],EAX 00405690 |. 68 84304000 PUSH CrkMeViz-3.00403084 ; UNICODE "Register" 00405695 |. 68 58304000 PUSH CrkMeViz-3.00403058 ; UNICODE "CrkMeViz3" 0040569A |. 8942 08 MOV DWORD PTR DS:[EDX+8],EAX 0040569D |. 8B85 C0FDFFFF MOV EAX,DWORD PTR SS:[EBP-240] 004056A3 |. 8942 0C MOV DWORD PTR DS:[EDX+0C],EAX 004056A6 |. FF15 C0914000 CALL DWORD PTR DS:[<&MSVBVM50.#689>] ; rtcGetSetting - Lee el numero de serie del registro ........ 0040574F |. 68 9C304000 PUSH CrkMeViz-3.0040309C ; UNICODE "User Name" 00405754 |. 68 84304000 PUSH CrkMeViz-3.00403084 ; UNICODE "Register" 00405759 |. 68 58304000 PUSH CrkMeViz-3.00403058 ; UNICODE "CrkMeViz3" 0040575E |. 8948 08 MOV DWORD PTR DS:[EAX+8],ECX 00405761 |. 8B8D C0FDFFFF MOV ECX,DWORD PTR SS:[EBP-240] 00405767 |. 8948 0C MOV DWORD PTR DS:[EAX+0C],ECX 0040576A |. FF15 C0914000 CALL DWORD PTR DS:[<&MSVBVM50.#689>] ; rtcGetSetting - Lee el Usuario del registro
Reconstruyendo la llamada al registro vemos que lee de esta ruta: HKEY_CURRENT_USER\Software\VB and VBA Program Settings\CrkMeViz3\Register el contenido de User Name y del Serial number.
Quizá uno de los fallos de éste crackme, es que no comprueba la autenticidad de estos parámetros y si los modificas parece que estás registrado. Un ejemplo:
La rutina de comprobación del serial no es para nada complicada pero recordemos que estamos tratando con VB y éste delega el trabajo duro en otras librerias de modo que tenemos que «meternos» a tracear las llamadas para ver los valores que multiplica y divide.
CPU Disasm Address Hex dump Command Comments 00405A86 FF15 3C914000 CALL DWORD PTR DS:[<&MSVBVM50.#518>] ;MSVBVM50.rtcLowerCaseVar 00405A8C 8D95 14FEFFFF LEA EDX,[EBP-1EC] 00405A92 8D8D ACFEFFFF LEA ECX,[EBP-154] 00405A98 FFD6 CALL ESI 00405A9A 8D95 ACFEFFFF LEA EDX,[EBP-154] 00405AA0 8D8D 4CFEFFFF LEA ECX,[EBP-1B4] 00405AA6 FFD7 CALL EDI 00405AA8 8D95 4CFEFFFF LEA EDX,[EBP-1B4] 00405AAE 8D8D 7CFFFFFF LEA ECX,[EBP-84] 00405AB4 FFD7 CALL EDI 00405AB6 8D85 14FEFFFF LEA EAX,[EBP-1EC] 00405ABC 8D8D 7CFFFFFF LEA ECX,[EBP-84] 00405AC2 50 PUSH EAX 00405AC3 6A 01 PUSH 1 00405AC5 8D95 04FEFFFF LEA EDX,[EBP-1FC] 00405ACB 51 PUSH ECX 00405ACC 52 PUSH EDX 00405ACD C785 1CFEFFFF 0 MOV DWORD PTR SS:[EBP-1E4],1 00405AD7 C785 14FEFFFF 0 MOV DWORD PTR SS:[EBP-1EC],2 00405AE1 FF15 68914000 CALL DWORD PTR DS:[<&MSVBVM50.#632>] ;MSVBVM50.rtcMidCharVar (Esto lo hace 6 veces, lo omito para abreviar.) ........ 00405CE1 FF15 34914000 CALL DWORD PTR DS:[<&MSVBVM50.#516>] ;MSVBVM50.rtcAnsiValueBstr (Lo mismo, otras 6) ........ 00405E7C C785 BCFDFFFF 2 MOV DWORD PTR SS:[EBP-244],52E 00405E86 C785 B4FDFFFF 0 MOV DWORD PTR SS:[EBP-24C],2 00405E90 50 PUSH EAX 00405E91 FF15 84914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>] | ->MSVBVM50.__vbaVarMul ........ 741C19D3 0FB745 FE MOVZX EAX,WORD PTR SS:[EBP-2] ;Valor1 741C19D7 0FB74D F2 MOVZX ECX,WORD PTR SS:[EBP-0E] ;Valor2 741C19DB 6BC0 12 IMUL EAX,EAX,12 ;Valor1*Valor2 ........ 00405E97 8D8D 04FEFFFF LEA ECX,[EBP-1FC] 00405E9D 50 PUSH EAX 00405E9E 51 PUSH ECX 00405E9F FF15 84914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>] 00405EA5 8D95 F4FDFFFF LEA EDX,[EBP-20C] 00405EAB 50 PUSH EAX 00405EAC 52 PUSH EDX 00405EAD FF15 84914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>] 00405EB3 50 PUSH EAX 00405EB4 8D85 E4FDFFFF LEA EAX,[EBP-21C] 00405EBA 50 PUSH EAX 00405EBB FF15 84914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>] 00405EC1 8D8D D4FDFFFF LEA ECX,[EBP-22C] 00405EC7 50 PUSH EAX 00405EC8 51 PUSH ECX 00405EC9 FF15 84914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>] 00405ECF 50 PUSH EAX 00405ED0 8D95 B4FDFFFF LEA EDX,[EBP-24C] 00405ED6 8D85 C4FDFFFF LEA EAX,[EBP-23C] 00405EDC 52 PUSH EDX 00405EDD 50 PUSH EAX 00405EDE FF15 94914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDiv>] | ->MSVBVM50.__vbaVarDiv ........ 741C8094 DD43 08 FLD QWORD PTR DS:[EBX+8] ;Recupera el resultado de las multiplicaciones anteriores 741C8097 0FBF47 08 MOVSX EAX,WORD PTR DS:[EDI+8] ;EAX = 1326 (52E) 741C809B 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX 741C809E DA75 F8 FIDIV DWORD PTR SS:[EBP-8] ;Divide los dos resultados 741C80A1 DD5E 08 FSTP QWORD PTR DS:[ESI+8] ........ 00405F44 FF15 24914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaLenBstr>] ;Len(nombre) ........ 00405F85 FF15 94914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDiv>] ;Resultado anterior / Len(nombre) ........
En resumen:
Ejemplo para deurus
64*65*75*72*75*73 = 1A605D70EB8 1A605D70EB8 / 52E = 5179FBF4 5179FBF4 / 6 = D9454A9
Al estar correctamente registrados desaparece el botón de registrar.
El cuarto crackme es prácticamente igual que el tercero salvo que en vez de nag ahora contamos con limitación de ejecuciones. Del mismo modo utiliza el registro de Windows para guardar los datos de registro y las ejecuciones que llevamos.
Ponemos un breakpoint «bp RegOpenKeyW» y llegamos a la conclusión de que la ruta es HKEY_CURRENT_USER\Software\VB and VBA Program Settings\ODBC\Register y los valores se guardan en Counter, User Name y Serial number respectivamente. Este crackme hereda el fallo del anterior y si alteramos los valores el crackme nos muestra como usuarios autorizados, aunque sabemos que no estamos registrados ya que seguimos limitados por ejecuciones. Ni que decir tiene que lo mismo que modificamos el nombre y número de serie, podemos modificar el contador a nuestro favor. Crear un archivo «Reiniciar_contador.reg» con el siguiente contenido sería suficiente.
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\VB and VBA Program Settings\ODBC] [HKEY_CURRENT_USER\Software\VB and VBA Program Settings\ODBC\Register] "Counter"="0" "User Name"="deurus" "Serial number"="12345"
El keygen es prácticamente igual que en el crackme anterior, solo cambia el divisor.
CPU Disasm
Address Hex dump Command Comments
........
00404BD2 C785 BCFDFFFF C MOV DWORD PTR SS:[EBP-244],6C1
00404BDC C785 B4FDFFFF 0 MOV DWORD PTR SS:[EBP-24C],2
00404BE6 FF15 A0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
|
->MSVBVM50.__vbaVarMul
741C19F9 0FBF4F 08 MOVSX ECX,WORD PTR DS:[EDI+8] ;Valor1
741C19FD 0FBF43 08 MOVSX EAX,WORD PTR DS:[EBX+8] ;Valor2
741C1A01 0FAFC8 IMUL ECX,EAX ;Valor1*Valor2
........
00404BEC 8D8D 04FEFFFF LEA ECX,[EBP-1FC]
00404BF2 50 PUSH EAX
00404BF3 51 PUSH ECX
00404BF4 FF15 A0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00404BFA 8D95 F4FDFFFF LEA EDX,[EBP-20C]
00404C00 50 PUSH EAX
00404C01 52 PUSH EDX
00404C02 FF15 A0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00404C08 50 PUSH EAX
00404C09 8D85 E4FDFFFF LEA EAX,[EBP-21C]
00404C0F 50 PUSH EAX
00404C10 FF15 A0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00404C16 8D8D D4FDFFFF LEA ECX,[EBP-22C]
00404C1C 50 PUSH EAX
00404C1D 51 PUSH ECX
00404C1E FF15 A0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00404C24 50 PUSH EAX
00404C25 8D95 B4FDFFFF LEA EDX,[EBP-24C]
00404C2B 8D85 C4FDFFFF LEA EAX,[EBP-23C]
00404C31 52 PUSH EDX
00404C32 50 PUSH EAX
00404C33 FF15 B0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDiv>]
|
->MSVBVM50.__vbaVarDiv
741C8094 DD43 08 FLD QWORD PTR DS:[EBX+8] ; Recupera el resultado de las multiplicaciones anteriores
741C8097 0FBF47 08 MOVSX EAX,WORD PTR DS:[EDI+8] ; EAX = 1729 (6C1)
741C809B 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
741C809E DA75 F8 FIDIV DWORD PTR SS:[EBP-8]
00404C39 8BD0 MOV EDX,EAX
........
00404CA0 FF15 3C914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaLenBstr>] ;Len(nombre)
........
00404CF1 FF15 B0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDiv>] ;Resultado anterior / Len(nombre)
En resumen:
Ejemplo para deurus
64*65*75*72*75*73 = 1A605D70EB8 1A605D70EB8 / 6C1 = 3E7C594A 3E7C594A / 6 = A6A0EE2
Este último crackme está compilado en código nativo y simplemente se trata de una comparación lineal. La única diferencia reside en que no hay botón de registro, la comprobación la gestiona un evento «On Change«, de modo que está comprobando el tamaño del serial que introducimos y cuando éste tiene 8 dígitos llegamos aquí.
........ 0040A64F . C745 9C CDD4DD02 MOV DWORD PTR SS:[EBP-64],2DDD4CD ;2DDD4CD = 48092365 0040A656 . C745 94 03800000 MOV DWORD PTR SS:[EBP-6C],8003 0040A65D . FF15 08C14000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVa> ;MSVBVM50.__vbaVarTstEq 0040A663 . 66:85C0 TEST AX,AX 0040A666 . 0F84 BA000000 JE CrkMeViZ.0040A726 ;Si salta BAD BOY ........
Luego el serial correcto es 48092365.
¿Ha sido indoloro no?, claro que sí, Visual Basic es un coñazo de tracear pero hay que reconocer que con el tiempo las herramientas han mejorado mucho y nuestra vida es mucho más sencilla. Bueno, pués esto ha sido todo, como siempre os dejo todo el material utilizado y un Keygen.

Antes que nada, es importante saber que un archivo ELF en Linux es equivalente a un archivo EXE en Windows. Dicho esto, es bastante común encontrarnos con ejecutables ELF en diversos CTFs (Capture The Flag), y a menudo representan un desafío para aquellos no familiarizados con el uso cotidiano de Linux. Sin embargo, tengo una buena noticia si no eres aficionado de Linux: existen herramientas que permiten realizar un análisis preliminar para determinar si es necesario abordar el problema desde Linux o si podemos resolverlo directamente desde Windows. Estas herramientas facilitan una transición más cómoda para los usuarios de Windows, permitiéndoles interactuar eficazmente con archivos ELF.
Un archivo ELF (Executable and Linkable Format) es un formato común de archivo para archivos ejecutables, código objeto, bibliotecas compartidas y volcados de memoria en sistemas basados en Unix, como Linux. Es el estándar de formato de archivo para programas compilados y enlazados en este tipo de sistemas operativos.
La cabecera de un archivo ELF es una estructura de datos al comienzo del archivo que proporciona información esencial sobre el contenido y la forma de procesar el archivo. Esta cabecera es fundamental para que el sistema operativo y otros programas puedan interpretar correctamente el archivo ELF. Aquí están los componentes clave de la cabecera de un archivo ELF:
0x7F 'E' 'L' 'F'. También incluye información como la clase del archivo (32 o 64 bits), la codificación de datos (endianness), y la versión del formato ELF.Se nos proporciona un fichero de 20KB que rápidamente catalogamos como ELF.

Para realizar un análisis preliminar siempre uso DogBolt, que no es más que un decompilador online con la ventaja de que usa varios motores y de esta forma casi siempre te da una decompilación aceptable. La versión actual tiene disponibles 11 motores y además es open source, ¿Qué más se puede pedir?

Echamos un vistazo y enseguida encontramos algo interesante.

La flag parece codificada de modo que vamos a indagar acerca de la función FUN_0010285d

Dentro de la función FUN_0010285d vemos que nuestra flag codificada la procesa la función FUN_00102752

Aquí os diría que depende de vuestra experiencia en programación veríais que se está procesando byte a byte la cadena de entrada (param_1) y haciendo a cada byte un XOR (^) con el param_3 (que es 1 según vemos en la llamada de la función FUN_00102752), pero en estos tiempos que corren vamos a preguntar a ChatGPT que opina.
Le pido a ChapGPT que me analice el código y me responde:
Este código en C define una función llamada
FUN_00102752que realiza una operación de XOR (exclusivo OR) byte a byte sobre un bloque de memoria. La función toma tres parámetros:
long param_1: Este parámetro es tratado como una dirección de memoria. Se utiliza como la base de un bloque de memoria sobre el que se realizará la operación.ulong param_2: Este parámetro especifica el tamaño del bloque de memoria que será afectado por la operación.byte param_3: Este es el valor de un solo byte que se utilizará en la operación XOR.El cuerpo de la función consiste en un bucle
forque itera sobre el bloque de memoria:
int local_cse declara como una variable local y se inicializa en 0. Esta variable actúa como un contador para el bucle.- La condición del bucle
(ulong)(long)local_c < param_2asegura que el bucle se ejecute sobre el rango completo del bloque de memoria especificado porparam_2.- Dentro del bucle,
*(byte *)(param_1 + local_c) = *(byte *)(param_1 + local_c) ^ param_3;realiza la operación XOR. Aquí,*(byte *)(param_1 + local_c)accede al byte actual en el bloque de memoria. Este byte se modifica aplicándole un XOR conparam_3. La operación XOR se realiza entre el byte actual en la memoria y el valor deparam_3, y el resultado se escribe de nuevo en la misma ubicación de memoria.En resumen, la función
by ChatGPTFUN_00102752modifica un bloque de memoria aplicando una operación XOR con un valor dado (param_3) a cada byte dentro del rango de memoria especificado desdeparam_1hastaparam_1 + param_2. Este tipo de operación es común en tareas como la manipulación de datos para cifrado/descifrado o para la generación de patrones específicos en un bloque de datos.
Ahora imaginad que no sois muy dados a programar o simplemente estáis vagos de modo que volvemos a recurrir a ChatGPT con el promt «Haz un XOR 1 con javascript a la cadena: gmfzuihr^vr^o^drx^nod^shfiu|» a lo que responde:
function xorString(str) {
return Array.from(str).map(char => String.fromCharCode(char.charCodeAt(0) ^ 1)).join(»);
}console.log(xorString(‘gm
by ChatGPTfzuihr^vr^o^drx^nod^shfiu|’));
Copiamos el código y lo pegamos en un entorno online como por ejemplo playcode.io.

Este es un ejemplo simple, pero ¿percibís su potencial?
La imagen de portada de esta entrada ha sido generada con ChatGPT.