Linux Keygenme 1
In Today’s post we’ll be solving a basic level crackme which does some basic arithmetic calculations and then later checks our serial-key according to our input.
This is gonna be interesting and besides that we’ll also get to learn some basics of GDB and IDA alongside.
Disclaimer : This post might be a bit longer than I expected it to be but it seems that it was necessary to emphasize a little bit more so that beginners do not get stuck.
keyGme
by rion
Strings always makes our initial analysing part easy!!
We find their references and jump to their usage in the binary.
The main function looks similar to most of the crackmes as $eax is being compared to 2 and then there is a jump if it is not equal to 2. Basically here 2 is the argc parameter, as we’ve to specify the serial-key in the argument.
1 | Usage: ./keyGme [serial-key] |
This message is printed on the console if eax is not 2.
Also our serial-key’s length is then put into the eax register which is later compared to 10h (1610)
1 | Your key must be 16 characters. |
This message is printed on the console if eax is not 16 and our program exits.
After entering our serial-key of 16 characters, there is a call to a function 8048323.
We observe that func 8048323 further calls to other functions ie. 80482C1 and 80482F2 and there is a loop.
The above function ie. 80482C1 checks whether each of our input character is in the range of (41h, 5Ah) ie. (‘A’, ‘Z’).
So basically it should be an uppercase alphabet.
The latter function checks for the range (30h, 39h) ie. (‘1’, ‘9’)
And if there is a character other than the ranges specified it breaks the loop and prints out the message.
1 | Found invalid character! |
If there is no such invalid character then the control is passed to the above func 80483A9.
It does the main key “building” function in our program.
To understand this crackme a little bit more, we fire up GDB for dynamic analysis. Although, It doesn’t require us to do so, I’m just walking you through a basic tutorial.
We can set up a break point on the starting address of the above function and run the program with an input such as “1234ABCD1234ABCD” as we know from our initial analysis that only uppercase letters and numeric digits are valid.
1 | b *0x80483a9 |
Now as we can see in the above screenshot, currently our whole input is in the ECX register and EAX has the first character .
Now we keep on stepping a single instruction using :
1 | s |
Now when we step through the sar instruction, the value in the EAX register becomes 0x18 from 0x31.
This is because sar in assembly means Shift Arithmetic Right
For instance :
1 | 0x31 >> 1 = 0x18 |
Stepping further, the value 0xf00 ie. 384010 is moved into register ECX
Also after stepping through the idiv instruction, value of EAX and EDX gets changed.
This is because the value stored in EAX gets divided by value stored in ECX and the remainder and quotient is later saved in register EDX and EAX respectively.
Read more about the IDIV instruction here.
Afterwards the EAX register gets is value back from the stack.
And the add instruction adds 0xa ie 1010 to the EAX register.
So the Value in EAX now becomes 0x22.
After the add istruction there is a jump.
As we can all obviously figure out that this will be a loop to repeat this process for all of the succeeding characters in our input.
So the EAX value becomes 0x1 ie. the counter variable.
But wait, there’s a fish, value of EAX also changes to 0xf !!
hmm…
No Problem, let us continue stepping till the last character is stored in EAX.
When the loop iterates further through the second character in our input, we find that EAX becomes 0x54 and also there was an add instruction which adds EDX and EAX.
So, this basically means our previous result is added to our second character’s hex value.
1 | 0x22(previous) + 0x32(current) = 0x54 |
Now the same operation continues with 0x54.
ie.
1 | 0x54 >> 1 = 0x2a |
Now when we iterate through our last character of our input, we find that there is a cmp instruction which compares EAX to EDX.
So Now I get it, the value of EAX is always compared to 0xf after each iteration so that if it reaches the 16th character it jumps out of the loop and this cmp instruction is executed.
I traced back the cmp instruction on IDA too.
But in our case, the EAX and EDX values are not similar. So our input isn’t right.
So I tried entering our last character as ‘T’ as it was stored in EAX at last.
And B00mYa!! We did it.
We are presented with the Congratulations message.
I wrote a small keygen in python which takes random uppercase letters and numeric digits and crafts a string of length 15, and then later we append our last character to it by doing similar calculations as the program does.
1 | import random,string |
Wait x2 !! You’ve to read this too.. LOL
Make sure to subscribe to the newsletter to learn together with me.
Also Comment your feedbacks and share this writeup with your friends.
You can also ping me over Twitter @mrT4ntr4
Happy Reversing Gang!!