Flag checker with library call path explosion designed to thwart Angr's symbolic execution. This pitfall can be resolved via Angr's Dynamic Memory implementation.
Challenge Overview
babyrev is yet another flag checker program, but connects over socket to increase its complexity.
Angr is known to struggle against library calls. The use of socket to receive user input is similar to one of the common roadblocks in Angr where library functions such as scanf are used.
I came across this tutorial by Federico that uses Angr's symbolic memory to hook library calls.
Determine Start Address
To overcome this roadblock, we will try to avoid all instructions that are related to socket, and configure Angr's Simulation Manager to start directly from the flag-checking logic.
First, we create a symbolic bitvector flag that will substitute our input. In our case, the original input that recv() receives is stored in rbp-0xd0; hence we would also define our symbolic bitvector to store in the same memory address.
flag_chars = [claripy.BVS(f"c_{i}", 8)for i inrange(FLAG_LEN)]flag = claripy.Concat(*flag_chars)initial_state.memory.store(initial_state.regs.rbp-0xd0, flag)# Define the address at which the symbolic bitvector will be stored.
Determine Good & Bad Address
The rest is pretty much straightforward, which involves performing light-reversing to find good and bad addresses.
Solution
Angr solved this pretty quickly, taking only 4 minutes.