When I started writing this posts about radare2, I was expecting to learn how to work with this tool. That was the objective and what drove me to start this blog. What I was not expecting, was to learn something about Assembly. Crackme0x05 is the first from this series of exercises that made learn a new instruction. GREAT!!!
Getting the Crackme0x05 password through analysis
Just like Crackme0x04, this crackme has multiple solutions. Also, it has multiple functions. Let’s start digging.
We’ve got a new function: parell.
The main function seems to be the same, then I won’t go through it. Check function, at the first sight, has the same code as the previous exercise, the only thing that has changed is the result of the sum. Let’s see.
Instead of being 15, the result of the sum must be 16. At this point, I was like “Really?! It’s just this???”. So I ran the program and the result was not quite what I expect…
This is good news. It means that this crackme it’s not as simple as I expected. In fact, if at some point the variable local_8h holds 0x10 (16 in decimal) we will be “redirect” to parell function. So, the only answer is that parell make some calculations itself. Time to check it.
We can see the whole input being passed to sscanf function. If you put a breakpoint right after the sscanf call, you’ll see that local_4h holds our input converted to hexadecimal.
The and & test
For those who are not used to Assembly, the next 3 lines can be confusing. First, we’ve got an and. Roughly speaking, the and operation returns 1 if the matching bits in both operands is 1, otherwise it will return 0. The result will be saved in the first operand. Let me give you an example.
Imagine that you have the instruction “and eax, 0x7”, where eax holds 0xd. After this instruction, eax will hold 0x5.
Now, imagine you want to clear the register. You can just use the instruction “and eax, 0”.
In our case, we have a 1 as a second operator, so everything will be zero except the least significant bit. This tell us if we are dealing with a even or odd number, but let’s move on.
Second operation is a test. Let me just take a break to tell you that I’ve neither knew what was the purpose of this instruction nor I used it before. So this just became a great opportunity to learn it.
So, for starters, the test operation is very similar to and, except this last one writes the result to the first operand. test operation performs a bitwise and but the result of the operation is discarded. It only modifies the SF, ZF and PF flags. In this case, only ZF (zero flag) matters. If the zero flag is set, then the flow of the program will continue. Otherwise, and due to the jne instruction, the program will terminate this function. Bear in mind that je is an alias to jz and jne an alias to jnz.
This means that if the zero flag is set, the string “Password OK” will be printed!
Did you get it all?
Crackme0x05 asks for a password to the user. That password must be a number, where the sum from the left to the right sums to 0x10 (16 in decimal) to pass in the first condition. Note that the sum of all digits doesn’t need to result in 0x10. It also needs to be an even number in order to pass the second condition inside parell function.
Modifying Crackme0x05 to accept any password
To make this program accept any password, we could put an unconditional jump to the string “Password OK”, right after the compare instruction in the check function. But let’s go a little further.
We’re going to need to modify the program in two points because, two conditions must be met in order to obtain the “Password OK”.
So, first let’s overwrite the the first jump to the string “Password Incorrect” and replace it with a nop.
At this point, all the even numbers inserted will lead to “Password OK”.
Second, let’s be lazy and change just the and operation. Using the and operator with a zero as a second operand will make the eax register be zero as well. This will set the zero flag and make the program print “Password OK”.
Let’s check if that worked.
Do you have another solution? Drop me a comment!