Strange behavior with constraints on symbolic command-line argument
See original GitHub issueI have this very simple C program with an obvious buffer-overflow on the stack:
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
char buf[32];
strcpy(buf,argv[1]);
printf("Input:%s\n",buf);
return 0;
}
I’ve compiled this with -fno-stack-protector
and -z execstack
.
I can smash the stack on this and gain control of rip
with the input string python -c 'from struct import pack;print("A"*40 + str(pack("<Q", 0x424242424242), "utf-8"))'
. I can also verify in gdb that rip
gets set to 0x424242424242
.
However, I cannot solve for this rip
value in angr. But I am able to solve for rbp
.
This is my code:
proj = angr.Project("./csbo", exclude_sim_procedures_list=["strcpy"])
# Make command-line arg symbolic
num_input_chars = 64
sym_commandline_arg = claripy.BVS("argv1", 8 * num_input_chars)
state = proj.factory.entry_state(
args=["csbo", sym_commandline_arg],
add_options={
angr.options.ZERO_FILL_UNCONSTRAINED_MEMORY,
angr.options.CONSTRAINT_TRACKING_IN_SOLVER
}
)
# Looking for unconstrained paths
sm = proj.factory.simulation_manager(state, save_unconstrained=True)
# Step execution until we find an unconstrained path
while sm.active and not sm.unconstrained:
sm.step()
# Make a copy of the state
if not sm.unconstrained:
raise Exception("Did not find any unconstrained paths!")
s = sm.unconstrained[0].copy()
pattern = 0x4142434445464748
s.add_constraints(s.regs.rbp == pattern)
assert s.satisfiable()
This works and I am also able to solve for a value of the command-line arg that will satisfy the constraints. However, when I add s.add_constraints(s.regs.rip == 0x0000424242424242)
, the constraints are no longer satisfiable. Why is that? There is clearly an input that can achieve that, so why is the solver not able to find it?
I notice that when I print out rip
, I get <BV64 0x0 .. argv1_39_512[167:160] .. argv1_39_512[175:168] .. argv1_39_512[183:176] .. argv1_39_512[191:184]>
, which shows that there are clearly bits that are influenced by the input.
I’m still learning how to use angr, so my apologies if I have missed something obvious.
EDIT: I noticed that when I use the value 0x0000000042424242
in the rip
constraint, it works. Is there some implicit range for the rip
that angr uses?
Issue Analytics
- State:
- Created 4 years ago
- Comments:14 (8 by maintainers)
Top GitHub Comments
Yep, that’s what I did. Here’s my script:
I found that the difference between pypi and master for this testcase is caused by https://github.com/angr/claripy/commit/4ed61924880af1ea8fb778047d896ec0156412a6. This fixes a bug which caused inconsistent results to come out of the solver. There should be a new pypi release fairly soon.