Number of crackmes:
Number of solutions:
Comments:
Name | Author | Language | Arch | Difficulty | Quality | Platform | Date | Solution | Comments |
---|
Crackme | Infos |
---|
Comment | Link |
---|---|
I found the flag, but I also had to patch out some conditional jumps. There's a check in the WNDPROC of the window for WM_COMMAND, and when it processes that message, it checks if some functions are 0 instead of calling them and checking the return value. dMsg = Msg; if ( Msg 0x10 ) { if ( dMsg != 0x111 ) // dMsg != WM_COMMAND return DefWindowProcW(hWndParent, Msg, wParam, lParam); set_rf_debug_resume_flag_func(); check_debug_registers_func(); if ( sub_401210 || sub_401160 ) // have to patch this out { MessageBoxA(hWndParent, "Try harder! Muahahahaha..", "Exploit Pack - http://exploitpack.com", 0x40u); exit(0); } v65 = (unsigned __int16)wParam; if ( (unsigned __int16)wParam == 100 ) { // ... } } | ==> |
Spoiler alert!!! Enter password: thinkingthonking Result: true All of the functions used to generate the hash that gets checked are reversible. One of them is just very hard to find the inverse of. I hope to post some code for how I got this later. This should probably be harder than a level 2 if you plan on not patching it. | ==> |
Spoilers below! [+] CrackMe made by mike.ac#2770. [+] Tune credits to cncpp.divilabs.com. Please enter the secret password: 55-1-1-1 Press any key to continue . . . It plays the Mario song on the PC speakers when you are successful. The 1s in the password can be replaced with any hex number, as long as there are 4 numbers total and the first is 55 (the first number is compared against an instruction in memory). The trick is that jumps are written into the executable code while it is running, and then later removed, so it is difficult to follow what is going on unless you step through it. The code scans for a specific magic number and replaces it with a jump when the jump should be taken, and replaces it afterwards. Unfortunately, it crashes after the song is done, but I have figured out why. The reason for the crash at the end, even if you succeed, is that the same magic number is used twice, 0F DA DD EE 0F. This magic number is used for the last jump, but since it is used twice, that last jump does not get written in, and some previous jump gets written instead. But, the chiptunes still play. It is less satisfying to win and still crash, so I patched out the last jump to get it to not crash. After the song is done, it calls system("pause"). | ==> |
The problem comes about with the pointer value included. It is a pointer to the login string itself stored somewhere on the stack. That will be different every time this program executes, so it seems like a keygen would have to scan the process memory for the login string text in order to find this pointer, maybe? return (hashcode & 0x7FF ^ (v5 + login_ptr + other_negative_hash) & 0x7FF) == (sum_login_chars & 0x7FF); If I just patch that pointer out of this expression in the executable, I can make a keygen. It also seems like you have to choose login strings very specifically in order to find ones that can be brute forced. Some login strings just don't seem to have a possible matching password, but I haven't invested enough time brute forcing these to be able to verify this. | ==> |
for (int i = 0; i | ==> |
I had to make one patch to be able to get this to work. Login: coyote11111111 Password: aaaaaaaaaaa220 Logged in successfully. The seemingly random values mentioned above are not entirely random. One is a pointer and maybe should not be (so I patched it out), one always seems to be 0, and one is a different hash of the login, which yields a negative number. This code successfully finds that different hash: int getNegativeHash(string input) { int hash = 0xFFFFFFFC; for (int i = 0; i | ==> |
I tried embedding a self-keygen by patching the executable with ollydbg. The assembly code is available here: https://pastebin.com/55thWHsm | ==> |
username: coyote_0x90 serial: 55300355 | ==> |
it looks like the function that throws exceptions is checking for VMWare | ==> |
I finally found it as well. it looks like it checks for debuggers attached, checks that an exception that it triggers gets handled properly (i'm curious what this is looking for?), scans the processes running looking for known ones like IDA, and checks for int 3 breakpoints. it checksums some of these protection functions to look for patches: it looks like it checksums the process scanning function and the int3 breakpoint scanning function. i enjoyed this one. | ==> |
spoiler alert "Simple?" It cleverly sends us on a wild goose chase if a debugger is attached. I'm not sure how this debugger detection works yet, but if it is detected, then it runs different code that accepts all kinds of passwords that include chars over 128 and prints "You did it!" | ==> |
w works for a password. It looks like it only checks the first char: .text:004015E5 movzx eax, byte ptr [eax] .text:004015E8 cmp dl, al .text:004015EA jz short loc_4015F3 But if you step through the get_pwd function, you can see it generate all the chars in "w0n1t4" | ==> |
That looks like last serial. [*] You Won! Happy Cracking! I only had to patch over the conditional jumps after the IsDebuggerPresent calls while I was debugging it. Otherwise, it does not seem to detect that it is running in a VM (VirtualBox 6.0.8). There is an exception thrown, but if it is passed to the program, then the proper exception handler is used and it does not seem to exit. | ==> |
this key works: HaVf3z8AA2 | ==> |
OldSoft's KeyGenMe #2 -- Upgraded from DOS by wolverine2k Enter your name: coyote_0x90 Enter a serial number: 26-1126 Good Job. You have cracked OldSoft's KeyGenMe #2 Press any key to continue . . . C++ keygen https://pastebin.com/2A3uWbfM | ==> |