0

I'm playing with angr and I'm trying to constraint my input to printable chars. I did it in the "well-known" way like this:

import angr
import claripy

base_addr = 0x800000 
proj = angr.Project("binary", main_opts={'base_addr': base_addr})

flag_chars = [claripy.BVS('%d' % i, 8) for i in range(16)]
flag = claripy.Concat( *flag_chars + [claripy.BVV(b'\n')]) 

state = proj.factory.full_init_state(
        args=['binary'],
        add_options=angr.options.unicorn,
        stdin=flag,
)

for k in flag_chars:
     init_state.solver.add(k <= 0x7f)
     init_state.solver.add(k >= 0x20)

simgr = proj.factory.simulation_manager(state)
find_addr  = 0x807bf5 
avoid_addr = 0x807c55 
simgr.explore(find=find_addr, avoid=avoid_addr)

if (len(simgr.found) > 0):
    for found in simgr.found:
        print(found.posix.dumps(0))

So far, so good, this is working. But now I need to do something different: my input should be constrained only to letters and numbers. This is not going to work obviously, because in this interval we have also other chars (slash, backslash, dot, etc).

I'm struggling in getting this working. I tried something like

init_state.solver.add(Or(And(k >= ord('A'),k <= ord('Z')),And(k >= ord('a'),k <= ord('z'))))

and several other variations, but no luck. Any suggestion on this?

Thanks!

cips
  • 95
  • 1
  • 8
  • When you say "no luck," what do you mean? It produces an error message, or doesn't do the right thing? a minimum-reproducible-example would help a lot. See: https://stackoverflow.com/help/minimal-reproducible-example – alias Apr 19 '23 at 16:49
  • It does not work: no error messages, but it looks like it's ignored (so the wrong chars are still there) – cips Apr 19 '23 at 19:32
  • 1
    Please provide a minimal-reproducible example. Running the program you gave issues: `NameError: name 'proj' is not defined`, because it isn't clear where `proj` is coming from. It's impossible for readers of this forum to fill in those gaps. – alias Apr 19 '23 at 19:50
  • Again, this doesn't "run" because there's no such thing as "binary". Without a minimal-reproducible-example, stack-overflow will be useless for you. – alias Apr 20 '23 at 14:53
  • Here's something to try: Does claripy allow you to see what constraints it is sending to z3? If it does, see if it has the extra constraints you added. Then you'd know if the problem is in the z3 side or in the claripy/angr side. – alias Apr 20 '23 at 14:55

1 Answers1

0

OK, I found the solution:

  for byte in flag.chop(8):
    initial_state.solver.add(And(byte >= ord('A'), byte <= ord('Z')) | \
                             And(byte >= ord('a'), byte <= ord('z')) )

A small change to the script is required, this

flag_chars = [claripy.BVS('%d' % i, 8) for i in range(16)]
flag = claripy.Concat( *flag_chars + [claripy.BVV(b'\n')]) 

must be replaced with

flag = claripy.BVS("flag", 16 * 8)
cips
  • 95
  • 1
  • 8