Welcome to Part 2 of this series on cracking CMU’s Bomblab using Angr! If you are new, I would recommend starting with part 1 here.

### Phase 2

First we create a function stub for phase 2, which can be appended to our phase 1 exploit:

Let’s see how Phase 2 is called:

So similarly to Phase 1, it gets its input from read_line, which is then passed to phase_2.

Let’s disassemble Phase 2 and see what we’ve got:

We see that read_six_numbers is passed with the result of read_line in rdi, and a pointer to the stack in rsi. We can infer that it most likely tries to extract 6 integers from the buffer passed by read_line into the buffer pointed by rsi, which would look something like int[6]. We know that it must be an 32 bit int and not a 64 bit long long, because otherwise the buffer would require at least 0x30 bytes, but we see that the stack is only decremented by 0x28.

A good place to start our program execution will be after returning from read_six_numbers. The reason why we want to avoid read_six_numbers is again due to state explosion - if you disassemble the function, you see lots of branches and jumps. Not good!

We can set this up by pushing symbolic values on the stack. Since this is a 64 bit binary and we are dealing with 32 bit ints, each time we push we will actually be pushing 2 ints:

In more complicated functions, we may actually have to set up the stack nicely (i.e ensuring rbp is at a reasonable value, potentially adding other padding onto the stack). However, in this case, we can easily see that there are no memory references using rbp as an offset, and there seems to be no other local variables being used on the stack. We will also set our termination condition to be within this stack frame, so we do not need to worry about setting things like return addresses on the stack correctly.

Let’s initialize our simulation manager, and also define our find and avoid conditions:

We set our success address to be right before phase_2 returns, since we did not set the return address as mentioned previously. Similarly as before, we avoid the explode_bomb function as well.

### Some Final Housekeeping

Finally, let’s deal with getting our solution:

Here, we get a 64 bit int in num_12_sol and so on. We then unpack it to retrieve the individual values. Based on the ordering on the stack, the first number would be in the lower 32 bits, and the second number would be in the higher 32 bits.

### Full Solution Script

Here is the full script for phase 2:

Let’s run it!

Now try it on the bomb itself:

Awesome! We got the solution without even having to deal with the headache of figuring what Phase 2 is actually doing. While Phase 1 was relatively trivial and Angr solving it was probably not really impressive, this is something that should be making you excited now! :)

Thanks for reading, and I hope you’ve enjoyed the journey so far. You can go straight to the next part here.