Rev2 Write up- Angstrom CTF

This was a 80 point challenge from AngstromCTF that I competed in with the ENUSEC>_ gang <33 in 2018.

Disclaimer and prerequisites: I’m quite new to RE and I have noticed a severe lack of beginner write-ups that gently introduce you to the topic and actually explain the thought process. So here is mine. It is probably not the best way to do this challenge – I believe it can still help you beginners that have never looked at RE before ! You will need to be able to run an ELF (if you aren’t running Linux then you should probably look at getting a VM with it) and download IDA. I don’t think you need any more knowledge! Please let me know if you think some more explanations are necessary.

You can download the file here: rev2. I will be using Hexray’s IDA free.

After downloading the file and dropping it into my Kali vm, running the ‘file’ command on it shows us that it’a a 32-bit ELF. If you don’t know what that means read up on it here.

root@kali# file rev3_32 root@kali# ELF 32-bit LSB executable

We can run the file and see what it does.
root@kali# ./rev2_32

I loaded the file into IDA and took look at the structure. We can immediately see that we have some kind of checks going on and various end outputs before the program finishes.

I’ll take a few moments here to explain what all these cryptic eax, ebp, mov, call things mean, or at least the ones we will be dealing with:

mov eax, [ebp+var_2]

lets say [ebp+var_2] contains the number “8”. The instruction above, puts 8 into the eax register. eax now contains 8

imul eax, ebx

imul means multiply, it will put the product of eax * ebx into eax

cmp eax, 100

cmp compares the contents of eax and 100, depending on if they are the same, which one is smaller etc, the conditional jumps that often come after these statements will go one way or another.

jz short_loc834701787

jz is a arithmetic jump. It means “jump if zero”. It will usually come after operations such as add or sub. In IDA you can see that these jumps usually come at the end of a box – that means that depending on the result of the previous operations, the code will take a certain path.

We can also see that there are two levels, because we can see the strings that are printed in various steps.

Let’s focus on level 1 first.

We see _printf called (this prints the first prompt for the level 1 number) and then the program must have some way of getting our input. It’s easy enough to conclude that this is done when ___isoc99_scanf is called (scanf is the important bit here. I assume the __isoc99 part is due to compiling with C89 gcc standards, but it doesn’t really matter anyway, don’t worry about this bit for now). So where does the input go? Where is it compared? call ___isoc99_scanf add esp, 10h mov eax, [ebp+var_1C] cmp eax, 11D7h jz ...... In this bit of code we can see that we put [ebp_var1C] into eax and then compare eax to 11D7h (that’s in hex, we can easily convert it to decimal by right clicking on the value in IDA)

Bingo, level 1 solved. Let’s run the program with the new info, just to check.
root@kali# ./rev2_32

So let’s try and do level 2. In retrospect, I should have approached it from the bottom ie. focus on the last function that gets compared before the “success message” rather than trying to go through all the steps, but you live and you learn. I’ll describe my thought process, because it makes this article longer and prospective employers will be more impressed (??)

Due to the fact that the prompt asks for 2 2-digit numbers, the scan_f statements and the logic shown above we can assume these variables hold what we need.

So we will focus on : [ebp+var_18] & [ebp+var_14]

The structure of L2 looked like there was a series of steps checking two variables.

Level 2 logic

It’s a good idea to take a look at the different possible outcomes – if the supplied numbers fulfil the criteria in the logic shown below, the outcome can either be “Sorry, your guess was incorrect…” or “Congrats…” and the flag. In the boxes below we can see the variables we are concerned with being compared to certain numbers. So we can check out the logic, by running our binary with the numbers supplied: 9, 99 or 99 and 9.

Running the numbers with “99 9” and “9 99” seems to take us to the “Numbers don’t meet specs” – of course, the program asks us for 2 two digit numbers. This means that most of the logic we’ve just looked at means that it’s comparing our variables to these numbers and jumping to the answer if they AREN’T the same. (Of course the better way to do this is to look into what jle, jg, jnz etc jumps actually do. The comment from user johnfound on this stackoverflow post is in my bookmarks if I need to refresh my knowledge. A trial and error method is also ok for simple challenges like this one.)

The code puts our variables into edx and eax:

mov edx, [ebp+var_18] mov eax, [ebp+var_14]

then multiplies them:

imul eax, edx

next, the product is put into [ebp+var_10]
mov [ebp+var_10], eax

and [ebp+var_10] is compared to 0x0D67 which is 3431 in decimal.
cmp [ebp+var_10], 0D67h

Right so the numbers are factors of 3431. Googling that gets us the result: 47, 73.

Yay! Let’s run the binary with our new information

The flag is actf{4567_47_73}

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.