angr / simuvex

[DEPRECATED] A symbolic execution engine for the VEX IR
BSD 2-Clause "Simplified" License
79 stars 57 forks source link

stuck in fgets() SimProcedure? #112

Open zzloo7 opened 7 years ago

zzloo7 commented 7 years ago

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
zzloo7 commented 7 years ago

So, angr has trouble in simulating newlines?

zardus commented 7 years ago

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.

zzloo7 commented 7 years ago
^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?

salls commented 7 years ago

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

zzloo7 commented 7 years ago

OK, I got it. Thank you so much~ Have a nice day~