Taha Azzaoui

The Binary Bomb: Part 4

2017/12/27

Introduction

Okay, by now we know the drill. Let's run the bomb inside of GDB and set a break point at phase_4. We can run the program with our file of passwords and enter an arbitrary test string when prompted for input. Once we reach the breakpoint, we can disassemble phase_4 and view the assembler dump:

The Solution

Once again, we see the call to sscanf at +27, so by the same reasoning from phase 3, we know we should be looking for a format string of some sort. This will tell us the type and number of elements that make up this phase's password. Looking at +13 we can see that the contents of a hardcoded location in memory are being pushed onto the stack. Let's inspect the contents of that location in memory by running the following command:

There's the format string! This tells us that the password consists of a single integer. Let's analyze the following code to learn more about the properties of this number. The interesting bit is at +51 where our input is being pushed onto the stack followed by a call to the function func4. After func4 returns, the program is checking to make sure our input has turned into the value 0x961 (2401 in decimal). Our next course of action is to determine the behavior of func4 and apply it inversely to the value 2041. Let's analyze func4 to learn more about what it does to our input.

It’s clear that the instruction at +24 is recursive since the function is calling itself. Knowing that, every recursive function basically has two parts: a base case and a recursive case.

We can see the base case at +14 where the function tests for the zero flag being set and returns if the value stored in edx is equal to zero. According to the instruction at +6, our input is being stored in the register edx. Otherwise, it goes on to subtract 1 from the value and calls the itself with the new value. So we know that our mystery integer is lower bounded by 0. Note that on +9 the program stores the value of 1 into eax, which remains unchanged untill we reach +38, at which point +36 and +38 implement the following logic: eax = edx - eax.

The final step in determining the return value of func4, is to determine the pattern of values that show up in edx. Some knowledge about the load effective address (leal) instruction is required at this point. In general, the instruction leal a(%eax, %edx, b), %ecx results in the operation: %ecx = %eax + b * %edx + a. Therefore, we can express the instruction at +29 as: %edx = 8 * %eax. The first time the function runs, it will set %eax to 1, multiply it by 8, then subtract 1. The next time it runs it will multiply %eax now 7, by 8 then subtract 7, yeilding 49. You can keep going but the pattern is becoming obvious. The function is iteratively raising 7 to the power of whatever number the user provides as input.

We can encode everything we've learned so far into the following equation: $2041 = 7^x$ where $x$ is our input. So our answer is $log_7 2041 = 4$.

Sure enough our password is correct and with that we're one step closer to finishing.