Tags: python rev angr 


This was the first reverse engineering challenge in the TrollCat CTF.
First, I checked the file type:
$ file crackme
crackme: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=da0b706ba33eedf2a1c6122a3054203e69a4d343, for GNU/Linux 3.2.0, stripped

When running it, it simply asks for a key, and tells if the key entered is correct.

Since the simple techniques, such as strings, strace, ltrace didn't work, i analyzed the file using Cutter.
I collected the success and failure addresses, and wrote a python script using angr to retrieve the key:

import angr
import claripy

success_addr = 0x00001832

failure_addr = 0x00002095 # ;-- str.Invalid_key:
# 0x00002095 .string "Invalid key" ; len=12

flag_length = 15 # >>> sys.getsizeof('A'*15)
# 64

proj = angr.Project("crackme") # create a projects

# create stdin variable that angr can work with
key_chars = [claripy.BVS(f"key_{i}", 8) for i in range(flag_length)]
key = claripy.Concat(*key_chars + [claripy.BVV(b"\n")])

# define the simulation manager's state
state = proj.factory.full_init_state(

# limit to pritable characters only
for c in key_chars:
state.solver.add(c <= 0x7f)
state.solver.add(c >= 0x20)

sm = proj.factory.simulation_manager(state)
sm.explore(find=success_addr, avoid=failure_addr)

# print all dead ends - stdin and stdout
for end in sm.deadended:
print(end.posix.dumps(0), end.posix.dumps(1))


The most "readable" output was "dumbha", and since there was some unknown characters at the end, I guessed that the pasword
is "dumbhacker". Bingo! After performing the netcat connection that was included in the description, I got the flag: