Skip to content

Instantly share code, notes, and snippets.

@ercoppa
Last active November 26, 2018 13:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ercoppa/fb665eeac593c25d6e3512e8774c1b38 to your computer and use it in GitHub Desktop.
Save ercoppa/fb665eeac593c25d6e3512e8774c1b38 to your computer and use it in GitHub Desktop.
angr on BIAR-1.6.5
biar@pfp-VirtualBox:~$ python2 -m pip install --user pip
biar@pfp-VirtualBox:~$ python -m pip install --user angr
biar@pfp-VirtualBox:~/Desktop/angr$ python solve.py
WARNING | 2018-11-26 14:31:21,834 | angr.analyses.disassembly_utils | Your version of capstone does not support MIPS instruction groups.
<SimulationManager with 1 active>
<SimulationManager with 2 active>
<SimulationManager with 3 active>
<SimulationManager with 3 active, 1 avoid>
Reached the target
%edi = [2L, 2147483650L]
%esi = [0]
biar@pfp-VirtualBox:~/Desktop/angr$ ./example 2 2147483650
biar@pfp-VirtualBox:~/Desktop/angr$ ./example 2 0
example: example.c:12: foobar: Assertion `x-y != 0' failed.
Aborted
biar@pfp-VirtualBox:~/Desktop/angr$ ./example 2147483650 0
example: example.c:12: foobar: Assertion `x-y != 0' failed.
Aborted
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
void foobar(int a, int b) {
int x = 1, y = 0;
if (a != 0) {
y = 3+x;
if (b == 0)
x = 2*(a+b);
}
assert(x-y != 0);
}
int main(int argc, char * argv[]) {
if (argc != 3)
return 1;
int a = atoi(argv[1]);
int b = atoi(argv[2]);
foobar(a, b);
//printf("%d %d\n", a, b);
return 0;
}
import angr, logging
import claripy
import pdb
import resource
import time
proj = angr.Project('bomb', load_options={'auto_load_libs' : False})
start = 0x400ee0
avoid = [0x40143a]
end = [0x400ef7]
# initial state is at the beginning of phase_one()
state = proj.factory.blank_state(addr=start, remove_options={angr.options.LAZY_SOLVES,})
# a symbolic input string with a length up to 128 bytes
arg = state.se.BVS("input_string", 8 * 128)
# an ending byte
arg_end = state.se.BVS("end_input_string", 8)
# add a constraint on this byte to force it to be '\0'
# the constraint is added to the state.
# Another way to do same is with:
# arg_end = state.se.BVV(0x0, 8)
# in this case arg_end is a concrete value
state.se.add(arg_end == 0x0)
# concat arg and arg_end
arg = state.se.Concat(arg, arg_end)
# an address where to store my arg
bind_addr = 0x603780
# bind the symbolic string at this address
state.memory.store(bind_addr, arg)
# phase_one reads the string [rdi]
state.regs.rdi = bind_addr
# make rsi concrete
state.regs.rsi = 0x0
pg = proj.factory.simulation_manager(state, veritesting=False)
#pg = proj.factory.simulation_manager(state, veritesting=True, veritesting_options={'boundaries': end + avoid})
start_time = time.time()
while len(pg.active) > 0:
print pg
# step 1 basic block for each active path
# if veritesting is on: this will step more than one 1 BB!
pg.explore(avoid=avoid, find=end, n=1)
# Bazinga!
if len(pg.found) > 0:
print
print "Reached the target"
print pg
state = pg.found[0].state
print "Solution: " + state.se.eval(arg, cast_to=str)
break
print
print "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB"
print "Elapsed time: " + str(time.time() - start_time)
import angr, logging
import claripy
import pdb
import resource
import time
proj = angr.Project('bomb', load_options={'auto_load_libs' : False})
start = 0x400f0a # after calling read_six_numbers()
avoid = [0x40143a]
end = [0x400f3c]
# initial state is at the beginning of phase_one()
state = proj.factory.blank_state(addr=start, remove_options={angr.options.LAZY_SOLVES,})
# push six numbers into the stack
# as done by read_six_numbers
# since this is a x86_64 binary:
# each push into the stack works as a pair of ints
N = []
for i in xrange(3):
a = state.se.BVS('int{}'.format(i * 2), 32)
b = state.se.BVS('int{}'.format(i * 2 + 1), 32)
N.append(a)
N.append(b)
c = state.se.Concat(a, b)
state.stack_push(c)
pg = proj.factory.simulation_manager(state, veritesting=False)
#pg = proj.factory.path_group(state, veritesting=True, veritesting_options={'boundaries': end + avoid})
start_time = time.time()
while len(pg.active) > 0:
print pg
# step 1 basic block for each active path
# if veritesting is on: this will step more than one 1 BB!
pg.explore(avoid=avoid, find=end, n=1)
# Bazinga!
if len(pg.found) > 0:
print
print "Reached the target"
print pg
state = pg.found[0].state
#print state.se.constraints
for i, n in enumerate(reversed(N)):
print "n[" + str(i) + "]: " + str(state.se.eval_upto(n, 2))
break
print
print "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB"
print "Elapsed time: " + str(time.time() - start_time)
import angr, logging
import claripy
import pdb
import resource
import time
proj = angr.Project('bomb', load_options={'auto_load_libs' : False})
start = 0x400F60 # after calling sscanf
avoid = [0x40143a]
end = [0x400fc9]
# initial state is at the beginning of phase_one()
state = proj.factory.blank_state(addr=start, remove_options={angr.options.LAZY_SOLVES,})
# push two numbers into the stack
N = [state.se.BVS('int{}'.format(0), 32), state.se.BVS('int{}'.format(1), 32)]
state.memory.store(state.regs.rsp + 0x8, N[0].reversed, 4)
state.memory.store(state.regs.rsp + 0xc, N[1].reversed, 4)
pg = proj.factory.simulation_manager(state, veritesting=False)
#pg = proj.factory.simulation_manager(state, veritesting=True, veritesting_options={'boundaries': end + avoid})
start_time = time.time()
while len(pg.active) > 0:
print pg
# step 1 basic block for each active path
# if veritesting is on: this will step more than one 1 BB!
pg.explore(avoid=avoid, find=end, n=1)
if len(pg.found) > 0:
print
print "Reached the target"
print pg
print
for k in range(len(pg.found)):
print "Found state #" + str(k)
state = pg.found[k].state
for i, n in enumerate(N):
print "n[" + str(i) + "]: " + str(state.se.eval_upto(n, 2))
print
print
print "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB"
print "Elapsed time: " + str(time.time() - start_time)
import angr, logging
import claripy
import pdb
import resource
import time
proj = angr.Project('bomb', load_options={'auto_load_libs' : False})
start = 0x40102e # after calling sscanf
avoid = [0x40143a]
end = [0x40105d]
# initial state is at the beginning of phase_one()
state = proj.factory.blank_state(addr=start, remove_options={angr.options.LAZY_SOLVES,})
# push two numbers into the stack
N = [state.se.BVS('int{}'.format(0), 32), state.se.BVS('int{}'.format(1), 32)]
state.memory.store(state.regs.rsp + 0x8, N[0].reversed, 4)
state.memory.store(state.regs.rsp + 0xc, N[1].reversed, 4)
pg = proj.factory.simulation_manager(state, veritesting=False)
#pg = proj.factory.path_group(state, veritesting=True, veritesting_options={'boundaries': end + avoid})
start_time = time.time()
while len(pg.active) > 0:
print pg
# step 1 basic block for each active path
# if veritesting is on: this will step more than one 1 BB!
pg.explore(avoid=avoid, find=end, n=1)
if len(pg.found) > 0:
print
print "Reached the target"
print pg
print
for k in range(len(pg.found)):
print "Found state #" + str(k)
state = pg.found[k].state
for i, n in enumerate(N):
print "n[" + str(i) + "]: " + str(state.se.eval_upto(n, 2))
print
print
print "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB"
print "Elapsed time: " + str(time.time() - start_time)
import angr, logging
import claripy
import pdb
import resource
import time
proj = angr.Project('bomb', load_options={'auto_load_libs' : False})
start = 0x401062
avoid = [0x40143a]
end = [0x4010ee]
# initial state is at the beginning of phase_one()
state = proj.factory.blank_state(addr=start, remove_options={angr.options.LAZY_SOLVES,})
arg = state.se.BVS("input_string", 8 * 128)
for o in arg.chop(8): #ensure that the character has to be readable
state.se.add(state.se.Or(state.se.And(o >= 0x20, o <= 0x7e), o == 0))
# read_line() reads a line from stdin and stores it a this address
bind_addr = 0x603780
# bind the symbolic string at this address
state.memory.store(bind_addr, arg)
state.regs.rdi = bind_addr
pg = proj.factory.simulation_manager(state, veritesting=False)
#pg = proj.factory.path_group(state, veritesting=True, veritesting_options={'boundaries': end + avoid})
start_time = time.time()
while len(pg.active) > 0:
print pg
# step 1 basic block for each active path
# if veritesting is on: this will step more than one 1 BB!
pg.explore(avoid=avoid, find=end, n=1)
# Bazinga!
if len(pg.found) > 0:
print
print "Reached the target"
print pg
state = pg.found[0].state
print "Solution: " + str(state.se.eval(arg, cast_to=str))
break
print
print "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB"
print "Elapsed time: " + str(time.time() - start_time)
import angr, logging
import claripy
import pdb
import resource
import time
proj = angr.Project('bomb', load_options={'auto_load_libs' : False})
start = 0x40110B # after calling read_six_numbers()
avoid = [0x40143a]
end = [0x4011f7]
# initial state is at the beginning of phase_one()
state = proj.factory.blank_state(addr=start, remove_options={angr.options.LAZY_SOLVES,})
# push six numbers into the stack
# as done by read_six_numbers
# since this is a x86_64 binary:
# each push into the stack works as a pair of ints
N = []
for i in xrange(3):
o1 = state.se.BVS('int{}'.format(i * 2), 32)
o2 = state.se.BVS('int{}'.format(i * 2 + 1), 32)
N.append(o1)
N.append(o2)
o3 = state.se.Concat(o1, o2)
state.stack_push(o3)
state.regs.rax = state.se.BVV(0x6, 64)
state.regs.rbx = state.se.BVV(0x0, 64)
state.regs.rdx = state.se.BVV(0x0, 64)
state.regs.rsi = state.se.BVV(0x0, 64)
state.regs.r12 = state.se.BVV(0x0, 64)
state.regs.r13 = state.regs.rsp
pg = proj.factory.simulation_manager(state, veritesting=False)
#pg = proj.factory.path_group(state, veritesting=True, veritesting_options={'boundaries': end + avoid})
start_time = time.time()
while len(pg.active) > 0:
print pg
# step 1 basic block for each active path
# if veritesting is on: this will step more than one 1 BB!
pg.explore(avoid=avoid, find=end, n=1)
#pg.run(n=1)
# Bazinga!
if len(pg.found) > 0:
print
print "Reached the target"
print pg
state = pg.found[0].state
for i, n in enumerate(reversed(N)):
print "n[" + str(i) + "]: " + str(state.se.eval_upto(n, 2))
break
print pg
print
print "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB"
print "Elapsed time: " + str(time.time() - start_time)
import angr, logging
import claripy
import pdb
import resource
import time
proj = angr.Project('bomb', load_options={'auto_load_libs' : False})
start = 0x401248 # after readline()
avoid = [0x40143a]
end = [0x401282]
# initial state is at the beginning of phase_one()
state = proj.factory.blank_state(addr=start, remove_options={angr.options.LAZY_SOLVES,})
# a symbolic input string with a length up to 128 bytes
arg = state.se.BVS("input_string", 8 * 128)
# an ending byte
arg_end = state.se.BVS("end_input_string", 8)
# add a constraint on this byte to force it to be '\0'
# the constraint is added to the state.
# Another way to do same is with:
# arg_end = state.se.BVV(0x0, 8)
# in this case arg_end is a concrete value
state.se.add(arg_end == 0x0)
# concat arg and arg_end
arg = state.se.Concat(arg, arg_end)
# an address where to store my arg
bind_addr = 0x603780
state.memory.store(bind_addr, arg)
# phase_one reads the string [rdi]
state.regs.rax = bind_addr
# make some regs concrete
state.regs.rsi = 0x0
state.regs.rdi = 0x0
pg = proj.factory.simulation_manager(state, veritesting=False)
#pg = proj.factory.path_group(state, veritesting=True, veritesting_options={'boundaries': end + avoid})
start_time = time.time()
while len(pg.active) > 0:
print pg
# step 1 basic block for each active path
# if veritesting is on: this will step more than one 1 BB!
pg.explore(avoid=avoid, find=end, n=1)
# Bazinga!
if len(pg.found) > 0:
print
print "Reached the target"
print pg
state = pg.found[0].state
print "Solution: " + state.se.eval(arg, cast=str)
break
print
print "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB"
print "Elapsed time: " + str(time.time() - start_time)
import angr
proj = angr.Project('example')
# customize XXX, YYY, and ZZZ!!!
start = XXX # addr of foobar
avoid = [YYY] # point(s) that are not interesting (e.g., early exits)
end = ZZZ # point that I want to reach
# blank_state since exploration should start from an arbitrary point
# otherwise, use entry_state()
state = proj.factory.blank_state(addr=start)
# arguments are inside registers in x86_64
a = state.regs.edi
b = state.regs.esi
sm = proj.factory.simulation_manager(state)
while len(sm.active) > 0:
print sm # get a feeling of what is happening
sm.explore(avoid=avoid, find=end, n=1)
if len(sm.found) > 0: # Bazinga!
print "\nReached the target\n"
state = sm.found[0].state
print "%edi = " + str(state.se.eval_upto(a, 10))
print "%esi = " + str(state.se.eval_upto(b, 10))
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment