CipherCombat2.0 CTF Write-up : Shifter 2

Saket Upadhyay
5 min readApr 13, 2020

Reverse Engineering Challenge of Hacker Earth CipherCombat2.0

What we get?

A zip file with password “hakerearth”… In there we find a PNG image

Checking the file for strings and embedded files we find nothing, and this is reverse engineering challenge so we will not go for stenography mumbo jumbo.

Let’s Solve this

Looking at the image, we can see it’s Graph representation of assembly code, and here is the image we get :-

Now let’s try to understand what this is trying to do.

1st Block

The first block is our MAIN() function taking some arguments

int main(int argc,char **argv,char **envp);

argc = no of arguments

argv = argument pointer

envp = enviornment pointer

It initializes bunch of variables and then stack setting routine.

we also see that it compares argc with 1 followed by JE condition

checking number of arguments should be equal to 2, argv[0] is always program name and argv[1] is our supplied password. That means we have to give exactly ONE parameter to the program.

If the condition is not satisfied it’s putting 1 in EAX (that’s our return register) and then returning from the main() routine, that’s equivalent to exit(1);, but here implemented through return 1;

2nd Block

Most of this block is just initialization of some variables and then a jump statement to get to next block.

also interesting thing to notice is that address spaces are separated by 4bytes each, looks similar? Yes, it’s character array allocation of 15 characters.

then it sets var_4h = 1

Let’s start building the program to side by side…

Array Recreated in Python

3rd Block

Now this looks like

Initialize a var > do something > add 1 to it> check if var =>0xf i.e (15)base > repeat

Looks familiar? loops something with increasing variable?

It’s nothing but a for()/while() loop implementation which iterates for 15 times, same as our character array length.

so let’s define it as for(int i=1;i≤15;i++){ loop body }

also, at the end of loop body it compares something and if it fails it shows “Better Luck next time” and then exit.

Other wise it completes the loop and exit with “c0ngrats!” message

The loop body

The loop body is pretty interesting, it might look intimidating to new reverse engineer but it’s really simple.With some experience, you can already tell what it’s doing.

Let’s have a look at it.

now as we know it’s a loop and var_4h is our control variable let’s call it “i”. First we load the value of i in EAX, then we load the address of rax*8 to RDX, and then move our ARGUMENT(var_60h) into RAX. Then we do logical and RAX,RDX and mov Quad Word value at address of RAX to RAX, now we Move with Zero extended (movzx) byte value of RAX to …… ahhhhh… i am pretty sure this does not make it easier for you to understand it, all i am doing is dictating the instructions one by one…

Know this : Look at it, remember the pattern and know that it is one of the methods compilers implement fetching an element at some given index

You can ofcourse take some values yourself and try this but the full explaination is out of scope for this writeup, also it will make it boring and long enough.

Some important instruction reference (links):

Convert Doubleword to Quadword (CDQE)

Move with Zero-Extend (MOVZX)

Move with Sign-Extension (MOVSX)

Okay so what it actually did? Lemme explain:

  1. Take value at [i-1] index from our argument =argv[i-1] let’s say = arg
  2. Take value at [i-1] index from our character array = charp[i-1]
  3. Add i to our charp = charp[i-1]+i
  4. Add 1 to Step3 = charp[i-1]+i+1 , let’s say = charpnew
  5. Compare arg == charpnew.

These instructions are responsible for step 3 and 4, remember we stored our i in EAX ? and then we add EAX (i.e. i )to ECX, our element which is stored in EAX and then again add 1 to new EAX.

and now converting it to code we have :

Code reversed from Assembly Graph

Now instead of checking the flag we can print it !!

Here’s is relatively clean Python Implementation of above algorithm, Running it spits out the flag.

And we got the flag HE{shift3r_returns} we can also check it with the C++ program we reconstructed.

That’s it for this challenge, actually an easy one, just some experience in reverse engineering needed.

About CTF

Hacker Earth’s CipherCombat2.0 was great CTF for beginners in the security field. Overall great experience

--

--