Note: Re-write/Re-upload due to dead links

This write up are my thoughts and steps to statically analyze a given unknown binary. I want to understand the binary to a point where I can freely write about it. So here it is. I'm always open for you pointing out mistakes or giving feedback to me. The steps taken in the following write-up can probably be done in a different order as well.

Binary

To get the binary yourself you copy&paste the base64 version below as anothah_one.base64 and execute this one liner:

base64 -d < anothah_one.base64 | gunzip > anothah_one.bin && chmod +x anothah_one.bin
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
uhW6LwAA

First assessment

Let's take a look at the binary:

> file anothah_one
anothah_one: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=ba03a27bfca2eb401a35c28e69e661173d9c82cd, not stripped

We got a 32-bit non stripped ELF binary. This sounds fair enough, since we still have the debugging symbols available. First, let's run strings against it

> strings anothah_one
[...]
/lib/ld-linux.so.2
libc.so.6
_IO_stdin_used
exit
fopen
__isoc99_sscanf
puts
__stack_chk_fail
stdin
tolower
printf
fgets
strlen
sleep
strcmp
[...]
Welcome to the Poly Bomb. Three levels to solve and you get a key at the completion of each level. Good Luck...
Good Job with Phase One on to the next
Wow you solved phase two??? On to the next
Woot You solved the binary bomb
Tick...Tick...Tick...
[...]
[some ASCII ART HERE]
[...]
H0Tf00D:<
%d %d %d %d %d %d
Key problem contact ctf-owner@isis.poly.edu
;*2$"
BinaryBomb:(
GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3
.symtab
.strtab
.shstrtab
[...]

So at the beginning we seem to have some function strings which might get called. We already can assume that we have to deal with different read/print and input compare functions. Another function which stands out is int tolower(int c), which casts every input to lowercase. Next the output gives us a rough idea what we are dealing with here. Similar to the write-up before we have some kind of bomb defuse scenario with a total of 3 phases.

Note: I intentionally omitted the ASCII art since its not of major importance and would not help us reverse the binary.

Following this we have some weird and shady looking strings we might wanna keep in mind for the next steps. Last but not least we also have some binary internal strings like the symbol table or string table.

Second assessment

After the first recon phase we have a rough idea what we are dealing with here. Let's fire up our favorite tool for disassembly and take a look at the binary. Time for some fun in depth analysis! Since we still have all the debugging symbols we can easily navigate through the binary:

We can clearly see that we have 3 phases almost always with a preceding call to readLine(), which will ask for our input to solve the respective phase. If we manage to finish all phases win() gets called.
In the beginning, a function named sphinx is called though..

Since I omitted the ASCII art before I will just solve the riddle of the sphinx. This function prepares the ASCII art which is shown to us in the beginning (I omitted that part in the strings output).

So let's start with analyzing all the 3 phases :)

Phase 1

This one is pretty straight forward, we see that IDA recognizes at offset change a string literal: "BinaryBomb:(", which is loaded into [ebp+s1] and then into eax. This is repeated 6 times.

Each time the string is loaded into eax an offset (0 <= offset <= 5)  is added to access the the first 6 elements in the string to change them to the shown hex values, which conveniently for us, IDA already converted into ASCII characters automatically. So the original "BinaryBomb:(" string is changed to "=bJd{cBomb:(" via a byte by byte access.


Phase 2

So let's directly dive into phase 2! Here the call to readline() got moved into the phase instead of preceeding it in the main function.

After reading the user input and set [ebp-0x74] to 0 as it is serving as a loop counter to do 8 iterations:

0x08048931	cmp [ebp-0x74], 7
0x08048935  jle loc_80488c8

But what does the code in the loop body do? We can see a lot of mov(zx/sx) operations, some arithmetic right shift (sar), some
integer division(idiv), as well as a bunch of additions(add). So let's examine the more interesting parts.

0x080488d0	movzx   eax, byte [eax]
0x080488d3	mov   ecx, eax

This basically takes the first byte of our input and saves it in ecx!

0x080488eb  sar   edx,0x1f	; 0x1f = 31

This here does a right shift of 31 bits on edx. This will always zero out the edx register. Let's take a look at the next interesting operation

0x080488e3	mov   ebx, dword [modulus]	 ; ebx is set to 10 here
...
0x080488ee	idiv ebx

The idiv operation looks harmless but it might be a little confusing what it actually does!

idiv 	<ebx>
eax = eax / <ebx>
edx = edx % <ebx>

So eax holds the quotient and edx will hold the remainder after this operation. With this in mind the following line may make more sense now

0x080488f0	mov	 eax, edx
0x080488f2	add  eax, ecx

Now eax holds the remainder of the integer division, while ecx is holding one byte of the input we provided and did the integer division on. Now we're adding these and storing the result back in eax. How can we interpret this? Basically what we are are doing here is some kind of shift/encryption of the input. Recall that we enter this loop 8 times. So we're changing 8 bytes of our input! Let's briefly look at what happens after we finish looping!

So we're comparing our shifted input to something at hard coded that is stored at offset s1. As we can already see, IDA resolves the offset to the string "H0Tf00D:<". If our "encrypted" input matches this string we will have solved phase2! The used algorithm can be easily ported to a python script:

flag = ""
inp = "ABCDEFGH"
mod = 0xa
ctr = 0
while(ctr < 7):
	flag += chr(ord(inp[ctr]) % mod + ord(inp[ctr]))
    ctr += 1
print(flag)

FHJLNFH 

So how do we get the flag?

2 possibilities  come to mind right away.

  • First: try to map every input to the appropriate output by using dynamic analysis methods
  • Second: Look at the done mathematical operations and reverse their order starting with the hard coded result as the starting point.
  • Third, just take a dumb brute force approach as the used algorithm is very very lightweight
mod = 0xa
flag = "H0Tf00D:<"
inp = ""
for k in range(0, 8):
    for i in range(0, 127):
        j = i + i%mod
        if chr(j) == flag[k]:
            inp += chr(i)
            break
print(inp + "<")
B'M`'';1<

So why am I manually appending "<"? Look at the length of this string. It has a length of 9, but we're only looping 8 times! So we already have a part of our flag before even starting! "<" will always be the last character of the flag!


Phase 3

So as always let's take a look at the last phase for this binary!

At first glance phase 3 might not look much more difficult compared to phase 2. If we look closer we can see another function call this time around though: sanitize(). Also we can identify 2 separate loop constructs. Let's take a quick peak at the sanitize function first:

Keep in mind that another readline() function call was executed before entering phase 3! Anyhow, in here strlen is used to get the length of our provided input. When returning len(input) is stored in eax. ebx was set to 0 before the call to strlen. So it seems like we're entering the loop as many times as our input is long! The next basic block just checks whether the current input byte is != 0x20 (SPACE). When this is not the case we enter the third bigger block in the loop. This one casts the current input byte to lowercase and stores the result back in the input buffer!

As a conclusion we can note that no matter what we input for phase 3 it will always be converted to a lower case representation. We can focus on providing lower case input then anyway! Back in phase 3 there is another call to strlen() for our now lower case input. It gets pushed to [ebp-0x10] and then compared to 0x4!

0x080489a4	mov 	dword [ebp-0x10], eax
0x080489a7	cmp 	dword [ebp-0x10], 0x4

We can conclude another thing now. Our input has to have a length > 4, because if its <= 4 we jump right to explode_bomb(). Next [ebp-0x14] and eax are set to 0! The former is used as a loop counter, while the latter is only holding the current loop counter for the comparison part against the string length of the user input:

0x080489F1 mov     eax, [ebp-0x14]
0x080489F4 cmp     eax, [ebp-0x10]
0x080489F7 jl      short loc_80489BB

If eax is still < len(input) we enter the first loop. What happens here should be obvious by now. We are looping over every input byte again. But for what reason this time?

What the cmp instruction does is essentially subtracting operand 2 from operand 1. If op2 == op1 the result will obviously be 0 and the ZERO flag is set. In all other cases the flag will not be set. In our case only iff the ZERO flag is not set the loop continues by incrementing the loop counter. So this loop construct makes sure that for every byte n in the input buffer byte n+1 is different! Once we passed this input verification we enter the next loop construct:

0x080489fb	mov    eax, dword[ebp+0x8]      ; loads our input into eax
0x080489fe	movzx  edx, byte [eax]          ; loads first byte of it in edx
0x08048a01	mov    eax, dword [ebp-0x10]    ; len(input) = eax
0x08048a04	lea    ecx, [eax-0x1]           ; len(input-1) = ecx
0x08048a07	mov    eax, dword [ebp+0x8]     ; loads our input into eax again
0x08048a0a	add    eax, ecx                 ; eax looks at last input element
0x08048a0c	movzx  eax, byte [eax]          ; set that last element as eax
0x08048a0f	cmp    dl, al                   ; see below :)
0x08048a11	je     0x8048a18 <phase_3+161>
0x08048a13	call   0x8048b3b <explode_bomb> ; bang ;(
0x08048a18	add    dword [ebp+0x8],0x1
0x08048a1c	sub    dword [ebp-0x10], 0x2    ; subtract 2 of len(input)

This is resulting in:

  • Compare 1st and nth element and check if equal, if yes continue
  • Compare 2nd and nth-1 element and check if equal, if yes continue.
  • ...

This happens until we reach the middle element of our input and the check above with len(input) > 1 fails. That's the conditions to leave the loop and if that happens we solved phase 3.

Let's conclude what we know to pass this phase:

  • Input has to have more than 4 characters
  • In the end operations are done lowercase ASCII characters
  • 2 following characters must be distinct from each other
  • We need a palindrome
  • Input length has to be an uneven number

So you can choose a flag on your own, for example: abcba


Conclusion

I hope this static binary analysis was somewhat helpful and easy to understand. I know it was a bit longer, and probably took some time to read through, but I didn't feel like splitting this little binary into 3 separate articles. If you have any questions shoot them.