I'm new to reverse engineering and I've just recently learned about angr
, a framework that uses symbolic execution to get the input for a given output. I'm trying to complete a crackme using angr
. My code so far is:
import angr
import claripy
strlen = 10
base_addr = 0x00000000
flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(strlen)]
flag = claripy.Concat(*flag_chars)
proj = angr.Project("./d4rkfl0w-Crackme-4", main_opts={'base_addr': base_addr})
state = proj.factory.full_init_state(args=["./d4rkfl0w-Crackme-4"], add_options=angr.options.unicorn, stdin=flag)
state.memory.store(state.regs.rbp-0x8, flag)
for k in flag_chars:
state.solver.add(k > 0x20)
state.solver.add(k < 0x7e)
sm = proj.factory.simulation_manager(state)
sm.run()
for de in sm.deadended:
print(de.posix.dumps(0), de.posix.dumps(1))
The output is:
> python3 test.py
WARNING | 2020-08-24 18:55:24,821 | angr.state_plugins.symbolic_memory | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2020-08-24 18:55:24,822 | angr.state_plugins.symbolic_memory | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2020-08-24 18:55:24,822 | angr.state_plugins.symbolic_memory | 1) setting a value to the initial state
WARNING | 2020-08-24 18:55:24,823 | angr.state_plugins.symbolic_memory | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2020-08-24 18:55:24,823 | angr.state_plugins.symbolic_memory | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY_REGISTERS}, to suppress these messages.
WARNING | 2020-08-24 18:55:24,823 | angr.state_plugins.symbolic_memory | Filling memory at 0x7fffffffffefff8 with 64 unconstrained bytes referenced from 0x38e0d0 (strlen+0x0 in libc.so.6 (0x8e0d0))
b'((0$0(0(0(' b'\nPlease enter the password: \nSorry that is incorrect.\n'
b'0(0$0(:(((' b'\nPlease enter the password: \nSorry that is incorrect.\n'
b'U($>"(:($(' b'\nPlease enter the password: \nSorry that is incorrect.\n'
b'U(6>$(:(0(' b'\nPlease enter the password: \nSorry that is incorrect.\n'
b'U(6>-(:($(' b'\nPlease enter the password: \nSorry that is incorrect.\n'
b'U(6$-(:(Y(' b'\nPlease enter the password: \nSorry that is incorrect.\n'
This should be a relatively easy crackme (I had solved it with static analysis already and I want to get the flag a different way). Am I doing something wrong in the code?
The actual flag should be:
U6-:YL."+
angr
is not the best at handling c++ objects likecin
&cout
(esp. the former). I would expect that's the culprit for not finding the solution.