Last active
November 26, 2018 13:37
-
-
Save ercoppa/fb665eeac593c25d6e3512e8774c1b38 to your computer and use it in GitHub Desktop.
angr on BIAR-1.6.5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
biar@pfp-VirtualBox:~$ python2 -m pip install --user pip | |
biar@pfp-VirtualBox:~$ python -m pip install --user angr |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "Reached the target" | |
print pg | |
state = pg.found[0].state | |
print "Solution: " + state.se.eval(arg, cast_to=str) | |
break | |
print "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB" | |
print "Elapsed time: " + str(time.time() - start_time) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "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 "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB" | |
print "Elapsed time: " + str(time.time() - start_time) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "Reached the target" | |
print pg | |
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 "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB" | |
print "Elapsed time: " + str(time.time() - start_time) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "Reached the target" | |
print pg | |
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 "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB" | |
print "Elapsed time: " + str(time.time() - start_time) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "Reached the target" | |
print pg | |
state = pg.found[0].state | |
print "Solution: " + str(state.se.eval(arg, cast_to=str)) | |
break | |
print "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB" | |
print "Elapsed time: " + str(time.time() - start_time) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "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 "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB" | |
print "Elapsed time: " + str(time.time() - start_time) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "Reached the target" | |
print pg | |
state = pg.found[0].state | |
print "Solution: " + state.se.eval(arg, cast=str) | |
break | |
print "Memory usage: " + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024) + " MB" | |
print "Elapsed time: " + str(time.time() - start_time) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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