simuvex
simuvex copied to clipboard
stuck in fgets() SimProcedure?
I used pathgroup.explorer() to explore paths in Aeon which was reported as vulnerable before in several vulnerability databases(Advisory ID: CVE-2005-1019). I noticed it stuck in a fgets() in the third cycle of a loop, just no response. I have no idea why this woud happen. And I'm unsure what I should do.
Running environment: Ubuntu 15.10 python version: 2.7 angr version: 6.7.3.26
The source code as follow:
int getConfig(char settings[MAX_SETTINGS][MAX_LEN])
{
char home[MAX_LEN];
FILE *fp; /* .rc file handler */
int numSet = 0; /* number of settings */
strcpy(home, getenv("HOME")); /* get home path */
strcat(home, "/.aeonrc"); /* full path to rc file */
fp = fopen(home, "r");
if (fp == NULL) return -1; /* no cfg - ERROR */
while (fgets(settings[numSet], MAX_LEN-1, fp) && (numSet < MAX_SETTINGS)) numSet++; //stuck here
fclose(fp);
return numSet;
}
Corresponding disassembly code as follow:
while (fgets(settings[numSet], MAX_LEN-1, fp) && (numSet < MAX_SETTINGS)) numSet++;
402474: 83 85 e4 fd ff ff 01 addl $0x1,-0x21c(%rbp)
40247b: 8b 85 e4 fd ff ff mov -0x21c(%rbp),%eax
402481: 48 98 cltq
402483: 48 c1 e0 09 shl $0x9,%rax
402487: 48 89 c2 mov %rax,%rdx
40248a: 48 8b 85 d8 fd ff ff mov -0x228(%rbp),%rax
402491: 48 8d 0c 02 lea (%rdx,%rax,1),%rcx
402495: 48 8b 85 e8 fd ff ff mov -0x218(%rbp),%rax
40249c: 48 89 c2 mov %rax,%rdx
40249f: be ff 01 00 00 mov $0x1ff,%esi
4024a4: 48 89 cf mov %rcx,%rdi
4024a7: e8 44 e9 ff ff callq 400df0 <fgets@plt> //stuck here
4024ac: 48 85 c0 test %rax,%rax
4024af: 74 09 je 4024ba <getConfig+0xfc>
4024b1: 83 bd e4 fd ff ff 05 cmpl $0x5,-0x21c(%rbp)
4024b8: 7e ba jle 402474 <getConfig+0xb6>
And I checked fgets.py in the simuvex, the process stopped at following statement.
# read in up to the newline
ret = self.inline_call(simuvex.SimProcedures['libc.so.6']['read'], fd, dst, distance).ret_expr
So, angr has trouble in simulating newlines?
Are you saying that the whole python process is stuck? If so, can you Ctrl-C it and paste the backtrace? It's either in Z3, or our fgets is bugged. In the latter case, we can try running without the fgets simprocedure.
^CTraceback (most recent call last):
File "./explore.py", line 38, in <module>
print(pg.explore(find=(int(target, 16),)))
File "/home/ying/angr-dev/angr/angr/path_group.py", line 831, in explore
n=n)
File "/home/ying/angr-dev/angr/angr/path_group.py", line 855, in run
return self.step(n=n, step_func=step_func, until=until_func, stash=stash)
File "/home/ying/angr-dev/angr/angr/path_group.py", line 544, in step
pg = pg._one_step(stash=stash, selector_func=selector_func, successor_func=successor_func, check_func=check_func, **kwargs)
File "/home/ying/angr-dev/angr/angr/path_group.py", line 305, in _one_step
out = hook(pg, stash, selector_func=selector_func, successor_func=successor_func, check_func=check_func, **kwargs)
File "/home/ying/angr-dev/angr/angr/exploration_techniques/looplimiter.py", line 17, in step
pg = pg.step(stash=stash, **kwargs).move(stash, self.discard_stash,
File "/home/ying/angr-dev/angr/angr/path_group.py", line 544, in step
pg = pg._one_step(stash=stash, selector_func=selector_func, successor_func=successor_func, check_func=check_func, **kwargs)
File "/home/ying/angr-dev/angr/angr/path_group.py", line 328, in _one_step
r = self._one_path_step(a, successor_func=successor_func, check_func=check_func, **kwargs)
File "/home/ying/angr-dev/angr/angr/path_group.py", line 218, in _one_path_step
successors = a.step(**kwargs)
File "/home/ying/angr-dev/angr/angr/path.py", line 205, in step
self._make_successors(throw=throw)
File "/home/ying/angr-dev/angr/angr/path.py", line 238, in _make_successors
self._run = self._project.factory.successors(self.state, **self._run_args)
File "/home/ying/angr-dev/angr/angr/factory.py", line 77, in successors
r = engine.process(state, inline=inline,**kwargs)
File "/home/ying/angr-dev/angr/angr/engines.py", line 143, in process
force_addr=force_addr)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/engines/procedure.py", line 34, in process
force_addr=force_addr)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/engines/engine.py", line 44, in process
self._process(new_state, successors, *args, **kwargs)
File "/home/ying/angr-dev/angr/angr/engines.py", line 173, in _process
return super(SimEngineHook, self)._process(state, successors, procedure, **kwargs)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/engines/procedure.py", line 71, in _process
procedure.execute(state, successors, ret_to=ret_to)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/s_procedure.py", line 145, in execute
r = run_func(*sim_args, **self.kwargs)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/procedures/libc___so___6/fgets.py", line 63, in run
ret = self.inline_call(simuvex.SimProcedures['libc.so.6']['read'], fd, dst, distance).ret_expr
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/s_procedure.py", line 271, in inline_call
p.execute(self.state, None, arguments=e_args)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/s_procedure.py", line 145, in execute
r = run_func(*sim_args, **self.kwargs)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/procedures/libc___so___6/read.py", line 18, in run
length = self.state.posix.read(fd, dst, length)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/plugins/posix.py", line 212, in read
return self.get_file(fd).read(dst_addr, length)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/storage/file.py", line 134, in read
self.content.copy_contents(dst_addr, self.pos, real_length , dst_memory=self.state.memory)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/storage/memory.py", line 843, in copy_contents
return self._copy_contents(dst, src, size, condition=condition, src_memory=src_memory, dst_memory=dst_memory)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/plugins/symbolic_memory.py", line 964, in _copy_contents
_,max_size = self._resolve_size_range(size)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/plugins/symbolic_memory.py", line 333, in _resolve_size_range
max_size = self.state.se.max_int(size)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/plugins/solver.py", line 145, in concrete_shortcut_scalar
return f(self, *args, **kwargs)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/s_action_object.py", line 53, in ast_stripper
return f(*new_args, **new_kwargs)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/plugins/solver.py", line 86, in wrapped_f
return f(*args, **kwargs)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/simuvex/plugins/solver.py", line 373, in max
return self._solver.max(e, extra_constraints=self._adjust_constraint_list(extra_constraints), exact=exact)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/claripy/frontend_mixins/concrete_handler_mixin.py", line 30, in max
return super(ConcreteHandlerMixin, self).max(e, **kwargs)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/claripy/frontend_mixins/constraint_filter_mixin.py", line 48, in max
return super(ConstraintFilterMixin, self).max(e, extra_constraints=ec, **kwargs)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/claripy/frontend_mixins/sat_cache_mixin.py", line 84, in max
extra_constraints=extra_constraints, **kwargs
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/claripy/frontend_mixins/simplify_helper_mixin.py", line 4, in max
return super(SimplifyHelperMixin, self).max(*args, **kwargs)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/claripy/frontend_mixins/constraint_expansion_mixin.py", line 24, in max
m = super(ConstraintExpansionMixin, self).max(e, extra_constraints=extra_constraints, exact=exact, **kwargs)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/claripy/frontends/composite_frontend.py", line 300, in max
r = ms.max(e, extra_constraints=extra_constraints, exact=exact)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/claripy/frontend_mixins/sat_cache_mixin.py", line 84, in max
extra_constraints=extra_constraints, **kwargs
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/claripy/frontend_mixins/model_cache_mixin.py", line 269, in max
m = super(ModelCacheMixin, self).max(e, extra_constraints=extra_constraints, **kwargs)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/claripy/frontends/full_frontend.py", line 141, in max
model_callback=self._model_hook
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/claripy/backends/__init__.py", line 548, in max
return self._max(self.convert(expr), extra_constraints=self.convert_list(extra_constraints), solver=solver, model_callback=model_callback)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/claripy/backends/backend_z3.py", line 77, in z3_condom
return f(*condom_args, **kwargs)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/claripy/backends/backend_z3.py", line 697, in _max
if solver.check() == z3.sat:
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/z3/z3.py", line 6135, in check
r = Z3_solver_check_assumptions(self.ctx.ref(), self.solver, num, _assumptions)
File "/root/.virtualenvs/angr/local/lib/python2.7/site-packages/z3/z3core.py", line 4117, in Z3_solver_check_assumptions
r = lib().Z3_solver_check_assumptions(a0, a1, a2, a3)
KeyboardInterrupt
So, it's Z3's problem?
For functions like fgets we avoid path explosion by combining many possible states. The side effect here is the constraints get large quickly. If may be that in cases like this you would want to hook it with a custom version that doesn't fully model it, but has less constraints
OK, I got it. Thank you so much~ Have a nice day~