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 [email protected] ;*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 ), someinteger 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:

This is resulting in:

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)

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.