I’ve been doing plenty of crackmes as a way to improve my RE skills, although I do stay away from Keygen challenges as I don’t find them particularly interesting. Instead, I’m attempting those that require you to key in a right username or password.
This write up is about a pretty interesting and challenging crackme which involves XOR encoding and decoding of strings and timing analysis.
XOR encoding ensures that you can’t simply find the strings by “searching for strings” using the debugger. If you could do that, you can simply jump straight to the code to analyze. XOR encoding just simply makes your life harder to find the segment code of interest.
On the other hand, timing analysis is meant to try to defeat debugging efforts by timing how long it takes for a piece of code to run. When running the code without debugging, it typical takes a very short amount of time. But as we’re debugging and slowly stepping through the program, the amount of time increases. Again, it’s really simple to defeat this by simple removing the check (NOP), or by altering the final time for comparison.
Let’s begin with the crackme!
Running the program prompts us to enter a password, and when it’s wrong, it shows an error message, and the number of times you’ve made a guess
We set a breakpoint to the code segment of interest. I’ve renamed the XOR code to
Here we see a XOR_FUNC called, printing a statement (puts), and XOR_FUNC called again. What this does is to decode the string “Enter Password”, print the string on the console, and encode the string
We take a look at the XOR function, and it’s here that we see the timing analysis being done after the XOR operations are completed. If EAX > 5, it jumps to
CALL <JMP.&exit>. We can replace the JG comparison to NOP, so that nothing happens.
We can follow the dump of the values its using to XOR the strings with, and its “a8hf238fgnert23asethne”
Once we know the key to the XOR, we try to find what it is comparing the final string to, since we can reverse the required input string with those 2 inputs
Input ^ Key = Output
Input = Output ^ Key
The code exits if the input length is not equals to 15h, or 21
We get to this code segment that does the comparison of strings. If the strings are different, 1 is moved to EDX. At the end of the loop, if EDX = 1, it means that the password is wrong
With this, we can follow the dump to find out the string it’s comparing to. Since this is the final output we need, we can XOR these values with the key we found above to reverse what input is needed
Overall a pretty easy challenge with some patching involved!