Write-up intro

Let’s make a write-up of the easiest of the easiest reverse engineering challenges (not even entry CTF level).

I will show you how I, as a total beginner, approached it and how I made it through.

For the reversing tool I will be using Binary Ninja ($149) since it’s much more affordable than IDA Pro ($589).

Goal

The goal as with many other crackme challenges is to find the correct password.

Link to the exercise

Reversing

First I checked the downloaded executable.

E:\tmp\re\julia>ls Exer2_Juila.exe

E:\tmp\re\julia>file Exer2_Juila.exe Exer2_Juila.exe; PE32 executable for MS Windows (console) Intel 80386 32-bit

As expected it is a standard 32-bit Windows executable.

Let’s run it then.

E:\tmp\re\julia>Exer2_Juila.exe Please provide the password.

E:\tmp\re\julia>Exer2_Juila.exe AAAAA Incorrect Password.

Now open it in Binary Ninja and look for the two strings which we’ve seen.

After executing the Linear Sweep we get lots of functions, and we need to get to know which could be the main() function.

To do so we search for the reference of one of the previously found strings.

It has been found in sub_401040 function, so I’ll rename it to main().

The first check is being made against arg1 and in case of it not being equal to 2 we branch to code responsible for printing Please provide the password. string.

Now we’re pretty sure it in fact is the main function and therefore we can rename arg1 to argc and arg2 to argv.

This is how the other branch looks like.

The first block of code calculates length of the password provided as an argument. Then it allocates a buffer of the same length (including null byte) as the provided password.

In case of malloc returning a null pointer (failed at allocating the bytes) the program exists. We do now care about this part.

The next block copies the provided password to the allocated buffer.

Here we come to the interesting part of the function.

We can clearly see a loop there. The loop iterates over the allocated buffer until it reaches a null byte. During each pass it calls sub_401160 function with one byte of data. Now let’s look what’s inside of this function.

Function presented above checks if the provided byte is a lower-case or an upper-case letter. If it is then data located at data_403008 is added to the byte. At this address there is a constant which is equal to 4.

Coming back to our main function.

After the loop is finished the first 11 characters of the modified buffer are compared against “VIMwXliFiwx” sting. That means that to decode it we need to subtract 4 from each of these characters.

Let’s write one line of Python (3) to decode it.

C:\Users\matishadow>ipython -c " for char in ‘VIMwXliFiwx’: print(chr(ord(char) - 4), end = ‘') REIsTheBest

The password looks pretty legit but we can check it on the website.

This is indeed correct!

Summary

Even though the encoding of the password was close to none the whole process showed how to quickly get to the interesting part of the binary.