Driller: augmenting AFL with symbolic execution!

Overview

Driller

Driller is an implementation of the driller paper. This implementation was built on top of AFL with angr being used as a symbolic tracer. Driller selectively traces inputs generated by AFL when AFL stops reporting any paths as 'favorites'. Driller will take all untraced paths which exist in AFL's queue and look for basic block transitions AFL failed to find satisfying inputs for. Driller will then use angr to synthesize inputs for these basic block transitions and present it to AFL for syncing. From here, AFL can determine if any paths generated by Driller are interesting, it will then go ahead and mutate these as normal in an attempt to find more paths.

The "Stuck" heuristic

Driller's symbolic execution component is invoked when AFL is 'stuck'. In this implementation, AFL's progress is determined by its 'pending_favs' attribute which can found in the fuzzer_stats file. When this attribute reaches 0, Driller is invoked. Other heuristics could also be used, and it's infact likely that better heuristics exist.

Use in the Cyber Grand Challenge

This same implementation of Driller was used team Shellphish in DARPA's Cyber Grand Challenge (CGC) to aid in the discovery of exploitable bugs. To see how Driller's invokation was scheduled for the CGC you can look at the Mechanical Phish's scheduler component 'meister'.

Current State and Caveats

The code currently supports three modes of operation:

  • A script that facilitates AFL and driller on one machine (over many cores if needed): https://github.com/shellphish/fuzzer/blob/master/shellphuzz
  • A monitor process watches over the fuzzer_stats file to determine when Driller should be invoked. When Driller looks like it could be useful, the monitor process schedules 'jobs' to work over all the inputs AFL has discovered / deemed interesting.
  • Celery tasks are assigned over a fleet of machines, some number of these tasks are assigned to fuzzing, some are assigned to drilling. Fuzzer tasks monitors the stats file, and invokes driller tasks when Driller looks like it could be useful. Redis is used to sync testcases to the filesystem of the fuzzer.

Driller was built and developed for DECREE binaries. While some support for other formats should work out-of-the-box, expect TracerMisfollowErrors to occur when unsupported or incorrectly implemented simprocedures are hit.

Example

Here is an example of using driller to find new testcases based off the trace of a single testcase.

import driller

d = driller.Driller("./CADET_00001",  # path to the target binary
                    "racecar", # initial testcase
                    "\xff" * 65535, # AFL bitmap with no discovered transitions
                   )

new_inputs = d.drill()

Dependencies

  • Mechaphish Fuzzer component
  • Mechaphish Tracer component
Comments
  • AttributeError: 'module' object has no attribute 'Tracer'

    AttributeError: 'module' object has no attribute 'Tracer'

    Hello, I want this err fix..

    I tried these command

    • [ sudo pip install tracer]
    • [ git clone https://github.com/angr/tracer && pip install tracer]
    • [python test_driller]

    How can i fix this err

    Traceback (most recent call last):
      File "test_driller.py", line 34, in <module>
        run_all()
      File "test_driller.py", line 31, in run_all
        all_functions[f]()
      File "test_driller.py", line 19, in test_drilling_cgc
        new_inputs = d.drill()
      File "/root/.environments/angr/local/lib/python2.7/site-packages/driller/driller.py", line 113, in drill
        list(self._drill_input())
      File "/root/.environments/angr/local/lib/python2.7/site-packages/driller/driller.py", line 139, in _drill_input
        t = tracer.Tracer(self.binary, self.input, hooks=self._hooks, argv=self.argv)
    **AttributeError: 'module' object has no attribute 'Tracer'**
    

    attributeerr

    please help me

    opened by skybluehold 13
  • Out of paths

    Out of paths

    I'm not sure if this issue belongs here or in the angr repo, but here's the error I'm getting:

    Traceback (most recent call last):
      File "./demo.py", line 17, in <module>
        solutions = d.drill()
      File "/home/adam/.virtualenvs/driller/local/lib/python2.7/site-packages/driller/driller.py", line 110, in drill
        list(self._drill_input())
      File "/home/adam/.virtualenvs/driller/local/lib/python2.7/site-packages/driller/driller.py", line 138, in _drill_input
        self._set_concretizations(t)
      File "/home/adam/.virtualenvs/driller/local/lib/python2.7/site-packages/driller/driller.py", line 244, in _set_concretizations
        state = t.path_group.one_active.state
      File "build/bdist.linux-x86_64/egg/angr/path_group.py", line 381, in __getattr__
        return self.stashes[k[4:]][0]
    IndexError: list index out of range
    

    Here's the demo program that I'm using to create this error:

    #!/usr/bin/env python
    from driller.driller import Driller
    from logging import DEBUG, getLogger
    from os import environ
    from traceback import print_exc
    
    getLogger("tracer.Tracer").setLevel(DEBUG)
    getLogger("angr.path_group").setLevel(DEBUG)
    
    target = "/home/grimm/targets/xz-5.2.3/src/xz/.libs/xz"
    afl_input_filename = "a.xz"
    with open(afl_input_filename, "rb") as f:
            afl_input = f.read()
    environ['LD_PRELOAD'] = "/home/grimm/targets/xz-5.2.3/src/liblzma/.libs/liblzma.so.5"
    d = Driller(target, afl_input)
    try:
            solutions = d.drill()
    except Exception as e:
            print_exc()
    

    The debugging output from path_group is extremely helpful in telling us that there are no active paths. This explains why we get the unhandled exception.

    <snip>
    DEBUG   | 2017-03-20 16:56:43,073 | angr.path_group | Round 72: stepping <PathGroup with 39 unsat, 1 active, 2 errored>
    DEBUG   | 2017-03-20 16:56:43,074 | angr.path_group | Out of paths in stash active
    <Traceback>
    

    It seems path_group's getattr assumes that if the caller is accessing one_active, then self.stashes['active'] must have a length > 0.

    I feel like the "right" thing to do in getattr is to return None in this case, but I'm not familiar enough with the code base to know if this is a reasonable way to handle this. More importantly, I don't understand why the path exploration can't find its way to the entry point! Presumably it's related to the LD_PRELOAD, but I'm not sure how. Whatever ingests the executable should be getting a snapshot of memory with the library loaded...

    You guys have been giving me great support. Any pointers on this one?

    opened by anon8675309 10
  • driller.driller.DrillerEnvironmentError

    driller.driller.DrillerEnvironmentError

    I tried to run driller starter code below with CADET_00001 file that i downloaded from https://github.com/angr/angr-doc/tree/master/examples/CADET_00001 (there are two types of binary files in here) but it cannot running well for those binary files with code error like picture below

    import driller d = driller.Driller("./CADET_00001", # path to the target binary "racecar", # initial testcase "\xff" * 65535, # AFL bitmap with no discovered transitions ) new_inputs = d.drill()

    screenshot from 2018-01-25 14-11-52

    Is there anyone can solve this problem?

    opened by Bennoli13 9
  • Diverted state not satisfiable when using strncmp

    Diverted state not satisfiable when using strncmp

    Hi, I'm experimenting a bit with driller and I noticed that it fails dramatically when dealing with strncmp. The diverted state is not satisfiable due to the symbolic length concretization (i think). You are aware of this for sure and my question is: is there a workaround?

    My test program is the following:

    int main(int argc, char** argv) {
        char buf[100]; 
        memset(buf, 0, 100);
        read(0, buf, 100);
        fprintf(stderr, "%s\n", buf);
        if(strncmp(buf, "pippo", 5) == 0) {
            //0x4006ea
            if(strncmp((char*)buf +6, "franco", 6) == 0) {
                int i;
                int s = 0;
                for(i = 0; i < 12; ++i)
                    s += buf[i];
                if(s == 1217)
                    abort();
            }
        }
      return 0;
    }
    

    I invoke driller with:

    d = driller.Driller("./test1", b"foo")
    print(d.drill())
    

    The relevant part of the logs are:

    DEBUG   | 2019-02-03 11:05:44,316 | driller.driller | Drilling into b'foo'.
    DEBUG   | 2019-02-03 11:05:44,316 | driller.driller | Input is b'foo'.
    DEBUG   | 2019-02-03 11:05:44,631 | angr.exploration_techniques.driller_core | Found 0x4004d0 -> 0x4004e0 transition.
    DEBUG   | 2019-02-03 11:05:44,631 | angr.exploration_techniques.driller_core | State at 0x4004e0 is not satisfiable even remove preconstraints.
    DEBUG   | 2019-02-03 11:05:44,641 | angr.exploration_techniques.driller_core | Found 0x4007c1 -> 0x4007e6 transition.
    DEBUG   | 2019-02-03 11:05:44,641 | angr.exploration_techniques.driller_core | State at 0x4007e6 is not satisfiable even remove preconstraints.
    DEBUG   | 2019-02-03 11:05:44,669 | angr.exploration_techniques.driller_core | Found 0x4005c0 -> 0x4005df transition.
    DEBUG   | 2019-02-03 11:05:44,669 | angr.exploration_techniques.driller_core | State at 0x4005df is not satisfiable even remove preconstraints.
    DEBUG   | 2019-02-03 11:05:44,689 | angr.exploration_techniques.driller_core | Found 0x4007dd -> 0x4007d0 transition.
    DEBUG   | 2019-02-03 11:05:44,689 | angr.exploration_techniques.driller_core | State at 0x4007d0 is not satisfiable even remove preconstraints.
    WARNING | 2019-02-03 11:05:44,817 | angr.state_plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
    DEBUG   | 2019-02-03 11:05:44,877 | angr.exploration_techniques.driller_core | Found 0x4006e1 -> 0x4006ea transition.
    DEBUG   | 2019-02-03 11:05:44,905 | angr.exploration_techniques.driller_core | State at 0x4006ea is not satisfiable.
    

    The last state is the interesting one but driller fails. On the other hand setting set_length=False in s.preconstrainer.preconstrain_file(self.input, s.posix.stdin, True) (in Driller._drill_input) in order to avoid to concretize the length the state is inserted in the diverted stash but the generated input is wrong.

    DEBUG   | 2019-02-03 11:26:54,536 | angr.exploration_techniques.driller_core | Found 0x4004d0 -> 0x4004e0 transition.
    DEBUG   | 2019-02-03 11:26:54,536 | angr.exploration_techniques.driller_core | State at 0x4004e0 is not satisfiable even remove preconstraints.
    DEBUG   | 2019-02-03 11:26:54,546 | angr.exploration_techniques.driller_core | Found 0x4007c1 -> 0x4007e6 transition.
    DEBUG   | 2019-02-03 11:26:54,546 | angr.exploration_techniques.driller_core | State at 0x4007e6 is not satisfiable even remove preconstraints.
    DEBUG   | 2019-02-03 11:26:54,573 | angr.exploration_techniques.driller_core | Found 0x4005c0 -> 0x4005df transition.
    DEBUG   | 2019-02-03 11:26:54,573 | angr.exploration_techniques.driller_core | State at 0x4005df is not satisfiable even remove preconstraints.
    DEBUG   | 2019-02-03 11:26:54,592 | angr.exploration_techniques.driller_core | Found 0x4007dd -> 0x4007d0 transition.
    DEBUG   | 2019-02-03 11:26:54,592 | angr.exploration_techniques.driller_core | State at 0x4007d0 is not satisfiable even remove preconstraints.
    WARNING | 2019-02-03 11:26:55,105 | angr.state_plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
    DEBUG   | 2019-02-03 11:26:55,487 | angr.exploration_techniques.driller_core | Found 0x4006e1 -> 0x4006ea transition.
    DEBUG   | 2019-02-03 11:26:55,534 | angr.exploration_techniques.driller_core | Found a completely new transition, putting into 'diverted' stash.
    DEBUG   | 2019-02-03 11:26:55,534 | driller.driller | Found a diverted state, exploring to some extent.
    DEBUG   | 2019-02-03 11:26:55,535 | driller.driller | [test1] dumping input for 0x4006e1 -> 0x4006ea.
    DEBUG   | 2019-02-03 11:26:55,535 | driller.driller | Generated: b'70697000000000000000000000000000000000000000000000000000000000000000000000000000000000008080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080806f70'
    DEBUG   | 2019-02-03 11:26:55,536 | driller.driller | [test1] started symbolic exploration at Sun Feb  3 11:26:55 2019.
    DEBUG   | 2019-02-03 11:26:55,877 | driller.driller | [test1] stopped symbolic exploration at Sun Feb  3 11:26:55 2019.
    DEBUG   | 2019-02-03 11:26:55,878 | driller.driller | [test1] dumping input for 0x4000058 -> 0x4000058.
    DEBUG   | 2019-02-03 11:26:55,878 | driller.driller | Generated: b'70697000000000000000000000000000000000000000000000000000000000000000000000000000000000008080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808066406f70'
    DEBUG   | 2019-02-03 11:26:55,879 | driller.driller | [test1] dumping input for 0x10406c0 -> 0x10406c0.
    DEBUG   | 2019-02-03 11:26:55,879 | driller.driller | Generated: b'706970000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080806f636e617266206f70'
    DEBUG   | 2019-02-03 11:26:55,880 | driller.driller | [test1] dumping input for 0x4000058 -> 0x4000058.
    DEBUG   | 2019-02-03 11:26:55,880 | driller.driller | Generated: b'706970000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080806f636e617266406f70'
    

    This is interesting because the generated input is almost right but the bytes are in the wrong place.

    • how is -> how should be
    • pip\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80op -> pippo
    • pip\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80f@op -> pippo@f
    • pip\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80ocnarf op -> pippo franco
    • pip\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80ocnarf@op -> pippo@franco

    Another case is when i give an input with size > len("pippo") like "foooooooo" the results are correct also with the regular set_length=True

    In this specific case filling with 0 is enough but in general this can alter the behaviour (think about a program that takes different paths using the return value of read) so I'd love to know if there is a more general workaround that you use.

    I'm using angr from git (cloned yesterday).

    opened by andreafioraldi 5
  • angr.exploration_techniques.Tracer() got an unexpected keyword argument 'copy_states'

    angr.exploration_techniques.Tracer() got an unexpected keyword argument 'copy_states'

    When I run shellphuzz I get the following:

    WARNING | 2018-11-28 13:11:27,135 | local_callback | starting drilling of buggy, id:000000,orig:seed-0 Traceback (most recent call last): File "/home/kburova/.virtualenvs/devis/lib/python3.5/site-packages/driller/local_callback.py", line 122, in <module> for new_input in d.drill_generator(): File "/home/kburova/.virtualenvs/devis/lib/python3.5/site-packages/driller/driller_main.py", line 101, in drill_generator for i in self._drill_input(): File "/home/kburova/.virtualenvs/devis/lib/python3.5/site-packages/driller/driller_main.py", line 128, in _drill_input t = angr.exploration_techniques.Tracer(trace=r.trace, crash_addr=r.crash_addr, copy_states=True) TypeError: __init__() got an unexpected keyword argument 'copy_states' (b'', None)

    I assume the version of tracer.py is wrong under angr/exploration_techniques/. I installed angr using command pip install angr. When I use python setup.py install within angr repo folder, I get correct tracer.py, but then lib/angr_native.so is missing. Any suggestions on how to fix all this, and what needs to be installed/reinstalled? Thanks

    opened by kburova 5
  • How to run driller

    How to run driller

    Hello, Could someone explain me how to run Driller? When I execute the run.py script, Driller listens for crashes but the fuzzer doesn't seem to start fuzzing. Thank you in advance.

    $ python2 ~/software/driller/run.py bin/
    INFO    | 2017-04-05 13:29:15,025 | driller | 1 binaries found
    INFO    | 2017-04-05 13:29:15,025 | driller | 1 binaries found
    INFO    | 2017-04-05 13:29:15,025 | driller | going to work on 1
    INFO    | 2017-04-05 13:29:15,074 | driller | listening for crashes..
    
    opened by ash09 5
  • "Too much TLS data" with more complex binary

    Am looking for any tips on an issue that is cropping up with running the shellphuzz from Docker on Ubuntu. Toy examples and simple .c files work just fine but when going to a more complex binary with function callbacks I run into the following issue.

    (angr) angr@cd4e2244ab3c:~/$ shellphuzz -c 1 -d 1 -w work-dir/ ./a.out
    [*] Drilling...
    [*] Creating fuzzer...
    WARNING | 2019-06-25 16:46:06,982 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000.
    Traceback (most recent call last):
      File "/home/angr/.virtualenvs/angr/bin/shellphuzz", line 7, in <module>
        exec(compile(f.read(), __file__, 'exec'))
      File "/home/angr/angr-dev/fuzzer/shellphuzz", line 87, in <module>
        memory=args.memory, seeds=seeds, timeout=args.run_timeout,
      File "/home/angr/angr-dev/fuzzer/fuzzer/fuzzer.py", line 162, in __init__
        p = angr.Project(binary_path)
      File "/home/angr/angr-dev/angr/angr/project.py", line 121, in __init__
        self.loader = cle.Loader(self.filename, concrete_target=concrete_target, **load_options)
      File "/home/angr/angr-dev/cle/cle/loader.py", line 127, in __init__
        self.initial_load_objects = self._internal_load(main_binary, *preload_libs, preloading=True)
      File "/home/angr/angr-dev/cle/cle/loader.py", line 683, in _internal_load
        self.tls_object.register_object(obj)
      File "/home/angr/angr-dev/cle/cle/backends/tls/elf_tls.py", line 93, in register_object
        raise CLEError("Too much TLS data to handle... file this as a bug")
    cle.errors.CLEError: Too much TLS data to handle... file this as a bug
    
    opened by JacobBarthelmeh 4
  • Is this show my driller successfully installed?

    Is this show my driller successfully installed?

    yzb@ubuntu:~/Downloads/driller-master/tests$ python test_driller.py WARNING | 2017-03-30 04:31:28,820 | tracer.cachemanager.LocalCacheManager | caching state to /tmp/sc1_0b32aa01_01-8955a29d51c1edd39b0e53794ebcf464.tcache Exception AttributeError: "'NoneType' object has no attribute 'release_handle'" in <bound method UcCleanupManager._finalizer of <unicorn.unicorn.UcCleanupManager object at 0x7fd665999e50>> ignored screenshot from 2017-03-30 04 35 17

    opened by SOSCapture 4
  • Unable to correct discrepancy between qemu and angr.

    Unable to correct discrepancy between qemu and angr.

    Hi, all. I am testing the driller with CGC binaries that are compiled for x86. Unfortunately, when I run the driller, I got an error "Unable to correct discrepancy between qemu and angr." I am not sure it is normal or I make some mistakes.

    import driller
    
    d = driller.Driller("./CROMU_00005",
                            '6,0 5,21,6 1,55,2 6,42,6 2,56,4 4,50,6 0,54,5 6,61,5 1,46,6 7,89')
    new_inputs = d.drill()
    

    Here is the binary. I only changed syscall to equivalent x86 syscall. CROMU_00005.zip

    Thanks.

    opened by insuyun 4
  • AttributeError: 'module' object has no attribute 'UNICORN_HANDLE_TRANSMIT_SYSCALL'

    AttributeError: 'module' object has no attribute 'UNICORN_HANDLE_TRANSMIT_SYSCALL'

    Hi, I get the following error when I run Driller, I'm not able to figure out what is the problem.

    import driller
    d = driller.Driller("./test","a"*1024,"\xff" * 65535)
    n = d.drill()
    
    Traceback (most recent call last):
      File "test-driller.py", line 4, in <module>
        n = d.drill()
      File "/usr/lib/python2.7/site-packages/driller/driller.py", line 110, in drill
        list(self._drill_input())
      File "/usr/lib/python2.7/site-packages/driller/driller.py", line 136, in _drill_input
        t = tracer.Tracer(self.binary, self.input, hooks=self._hooks)
      File "/usr/lib/python2.7/site-packages/tracer/tracer.py", line 216, in __init__
        self.path_group = self._prepare_paths()
      File "/usr/lib/python2.7/site-packages/tracer/tracer.py", line 921, in _prepare_paths
        return self._linux_prepare_paths()
      File "/usr/lib/python2.7/site-packages/tracer/tracer.py", line 1081, in _linux_prepare_paths
        options.add(so.UNICORN_HANDLE_TRANSMIT_SYSCALL)
    AttributeError: 'module' object has no attribute 'UNICORN_HANDLE_TRANSMIT_SYSCALL'
    

    Thank you for your help.

    opened by ash09 4
  • Driller not generating valid inputs

    Driller not generating valid inputs

    I have been playing with Driller for a bit, and I noticed something that looks weird when drilling certain inputs. I wrote a toy program to illustrate this (below).

    Basically, I ran driller using AFL to fuzz it first with the seed fuzzmesoftly here. AFL ran for a while and sent a few inputs to drill. However, the drilled input in question is Aset option\x00. Since AFL had already explored some paths, it modified its bitmap, so I had to capture both the bitmap and input to reproduce the result.

    What I was expecting was driller to generate an output that makes the program crash. However, none of the generated output will make the toy program crash, and AFL wasn't smart enough to combine the results from driller and its own findings.

    The generated output 00bada552100000000000000 from transition 4006d8 -> 4006dd contains the crash string, but it lacks the 'A' magic number prefix that would make the program crash during a real run.

    $ echo -e "\x00\xba\xda\x55!" | ./listing_stdin
    Bad magic number
    

    vs.

    $ echo -e "A\xba\xda\x55!" | ./listing_stdin
    Segmentation fault
    

    I am wondering how I could fix this? I looked a bit, and I think it comes down to this code in the tracer when it removes the preconstraints. It looks like it removes the 'A' because it was preconstrained when the tracer was initialized, but that constraint is necessary to even check for the crash string.

    Thank you for the help!! Let me know if anything isn't clear.

    Resources

    Here are the resources: test script, input file, program, program source and binary, and output log. I'm pretty sure I tested on this commit (unless I've messed something up in my workspace...)

    Test Script

    import driller
    import listing_stdin_c13fd238a6ed9a0311be4cd5426bb42f as in_data
    
    import logging
    l = logging.getLogger("driller.Driller")
    l.setLevel(logging.DEBUG)
    
    binary = "./listing_stdin"
    d = driller.Driller(binary, in_data.input, in_data.fuzz_bitmap, "whatever~")
    
    new_inputs = d.drill()
    

    Input File

    Here: listing_stdin_c13fd238a6ed9a0311be4cd5426bb42f.py.zip. It contains the binary path, input used, time run, and fuzz bitmap.

    Program Source and Binary

    I compiled this on Ubuntu 16.04 with gcc listing_stdin.c -o listing_stdin. Here is the compiled binary in case the fuzzing bitmap causes problems with a recompilation... listing_stdin.zip

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    #define MAGICNUMBER 'A'
    #define OPTION_STR "set option"
    
    int main(int argc, char *argv[]) {
        int* null_ptr = NULL;
        char config[20];
        read(0, config, sizeof(config));
    
        if (!config) {
            puts("Configuration syntax error");
            return 1;
        }
        if (config[0] != MAGICNUMBER) {
            puts("Bad magic number");
            return 2;
        }
    
        // Increment to next character
        char *directive = config + 1;
        if (strstr(directive, "\xba\xda\x55!")) {
        //if (strstr(directive, "badass!")) {
            int k = *null_ptr;
        }
        else if (!memcmp(directive, OPTION_STR, strlen(OPTION_STR))) {
            char *option = directive + strlen(OPTION_STR);
            puts(option);
        }
        else {
            puts("Unknown");
        }
        return 0;
    }
    

    Output

    [23:55:06] $ python test_proof.py
    INFO    | 2017-03-08 23:55:12,177 | driller.Driller | [listing_stdin] drilling started on Wed Mar  8 23:55:12 2017
    DEBUG   | 2017-03-08 23:55:18,033 | driller.Driller | drilling into 'Aset option\x00'
    DEBUG   | 2017-03-08 23:55:18,033 | driller.Driller | input is 'Aset option\x00'
    DEBUG   | 2017-03-08 23:55:18,657 | driller.Driller | found 4004d0 -> 4004e0 transition
    DEBUG   | 2017-03-08 23:55:18,657 | driller.Driller | 4004d0 -> 4004e0 has already been encountered
    DEBUG   | 2017-03-08 23:55:18,677 | driller.Driller | found 400781 -> 4007a6 transition
    DEBUG   | 2017-03-08 23:55:18,677 | driller.Driller | 400781 -> 4007a6 has already been encountered
    DEBUG   | 2017-03-08 23:55:18,705 | driller.Driller | found 400640 -> 400650 transition
    DEBUG   | 2017-03-08 23:55:18,705 | driller.Driller | 400640 -> 400650 has already been encountered
    DEBUG   | 2017-03-08 23:55:18,727 | driller.Driller | found 4005e0 -> 400603 transition
    DEBUG   | 2017-03-08 23:55:18,727 | driller.Driller | 4005e0 -> 400603 has already been encountered
    DEBUG   | 2017-03-08 23:55:18,748 | driller.Driller | found 40079d -> 400790 transition
    DEBUG   | 2017-03-08 23:55:18,748 | driller.Driller | 40079d -> 400790 has already been encountered
    DEBUG   | 2017-03-08 23:55:18,832 | driller.Driller | found 4006a2 -> 4006aa transition
    INFO    | 2017-03-08 23:55:18,849 | driller.Driller | found a completely new transition, exploring to some extent
    INFO    | 2017-03-08 23:55:18,851 | driller.Driller | [listing_stdin] dumping input for 4006a2 -> 4006aa
    INFO    | 2017-03-08 23:55:18,851 | driller.Driller | generated: be0000000000000000000000
    INFO    | 2017-03-08 23:55:20,509 | driller.Driller | [listing_stdin] started symbolic exploration at Wed Mar  8 23:55:20 2017
    INFO    | 2017-03-08 23:55:20,658 | driller.Driller | [listing_stdin] symbolic exploration stopped at Wed Mar  8 23:55:20 2017
    INFO    | 2017-03-08 23:55:20,659 | driller.Driller | [listing_stdin] dumping input for 4000050 -> 4000050
    INFO    | 2017-03-08 23:55:20,660 | driller.Driller | generated: be0000000000000000000000
    DEBUG   | 2017-03-08 23:55:20,723 | driller.Driller | found 4006d8 -> 4006dd transition
    INFO    | 2017-03-08 23:55:20,782 | driller.Driller | found a completely new transition, exploring to some extent
    INFO    | 2017-03-08 23:55:20,785 | driller.Driller | [listing_stdin] dumping input for 4006d8 -> 4006dd
    INFO    | 2017-03-08 23:55:20,785 | driller.Driller | generated: 00bada552100000000000000
    INFO    | 2017-03-08 23:55:21,821 | driller.Driller | [listing_stdin] started symbolic exploration at Wed Mar  8 23:55:21 2017
    INFO    | 2017-03-08 23:55:21,858 | driller.Driller | [listing_stdin] symbolic exploration stopped at Wed Mar  8 23:55:21 2017
    INFO    | 2017-03-08 23:55:21,860 | driller.Driller | [listing_stdin] dumping input for 4000050 -> 4000050
    INFO    | 2017-03-08 23:55:21,860 | driller.Driller | generated: 00bada552100000000000000
    DEBUG   | 2017-03-08 23:55:21,907 | driller.Driller | found 4006fe -> 40071c transition
    INFO    | 2017-03-08 23:55:21,945 | driller.Driller | found a completely new transition, exploring to some extent
    INFO    | 2017-03-08 23:55:21,948 | driller.Driller | [listing_stdin] dumping input for 4006fe -> 40071c
    INFO    | 2017-03-08 23:55:21,948 | driller.Driller | generated: 008c9a89df808f8b96909100
    INFO    | 2017-03-08 23:55:22,978 | driller.Driller | [listing_stdin] started symbolic exploration at Wed Mar  8 23:55:22 2017
    INFO    | 2017-03-08 23:55:23,028 | driller.Driller | [listing_stdin] symbolic exploration stopped at Wed Mar  8 23:55:23 2017
    INFO    | 2017-03-08 23:55:23,030 | driller.Driller | [listing_stdin] dumping input for 4000050 -> 4000050
    INFO    | 2017-03-08 23:55:23,030 | driller.Driller | generated: 008c9a89df808f8b96909100
    WARNING | 2017-03-08 23:55:23,061 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
    DEBUG   | 2017-03-08 23:55:23,094 | driller.Driller | found 400726 -> 40073a transition
    DEBUG   | 2017-03-08 23:55:23,095 | driller.Driller | 400726 -> 40073a has already been encountered
    opened by ekilmer 4
  • Exception: Internal error: cannot translate address

    Exception: Internal error: cannot translate address

    I was using driller to hybrid fuzz sqlite(a database program),but seemly it can not used to database program and raise Exception("Internal error: cannot translate address").The following is the stacktrace: Drilling input: b"CREATE TABLE v0 ( v1 INTEGER ) ; SELECT v1 FROM v0 WHERE v1 = 'v0' AND ( v1 = 8 OR v1 =9223372036854775808 ) ORDER BY v1 ; SELECT v1, sum ( v1 ) OVER( PARTITION BY v1 ORDER BY v1 ) FROM v0 ; " WARNING | 2022-12-19 13:43:46,883 | pyvex.lifting.gym.x86_spotter | The generalized AAM instruction is not supported by VEX, and is handled specially by pyvex. It has no flag handling at present. See pyvex/lifting/gym/x86_spotter.py for details WARNING | 2022-12-19 13:43:47,228 | cle.backends.tls | The provided object has an invalid tls_data_size. Skip TLS loading. WARNING | 2022-12-19 13:43:49,888 | cle.backends.tls | The provided object has an invalid tls_data_size. Skip TLS loading. Traceback (most recent call last): File "run_driller.py", line 70, in main() File "run_driller.py", line 56, in main for _, new_input in Driller(binary, seed, fuzzer_bitmap).drill_generator(): File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/driller/driller_main.py", line 101, in drill_generator for i in self._drill_input(): File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/driller/driller_main.py", line 143, in _drill_input simgr.step() File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/misc/hookset.py", line 90, in call result = current_hook(self.func.self, *args, **kwargs) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/exploration_techniques/driller_core.py", line 39, in step simgr.step(stash=stash, **kwargs) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/misc/hookset.py", line 90, in call result = current_hook(self.func.self, *args, **kwargs) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/exploration_techniques/tracer.py", line 343, in step return simgr.step(stash=stash, syscall_data=self._syscall_data, fd_bytes=self._fd_bytes, **kwargs) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/misc/hookset.py", line 90, in call result = current_hook(self.func.self, *args, **kwargs) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/exploration_techniques/suggestions.py", line 41, in step simgr.step(stash=stash, **kwargs) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/misc/hookset.py", line 95, in call return self.func(*args, **kwargs) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/sim_manager.py", line 407, in step successors = self.step_state(state, successor_func=successor_func, error_list=error_list, **run_args) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/misc/hookset.py", line 90, in call result = current_hook(self.func.self, *args, **kwargs) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/exploration_techniques/tracer.py", line 406, in step_state self._update_state_tracking(succs[0]) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/exploration_techniques/tracer.py", line 574, in _update_state_tracking self._sync_return(state, idx) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/exploration_techniques/tracer.py", line 890, in _sync_return return self._sync(state, idx, ret_addr) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/exploration_techniques/tracer.py", line 893, in _sync addr_translated = self._translate_state_addr(addr) File "/home/linuxbrew/anaconda3/envs/driller/lib/python3.8/site-packages/angr/exploration_techniques/tracer.py", line 640, in _translate_state_addr raise Exception("Internal error: cannot translate address") Exception: Internal error: cannot translate address

    opened by likaiam 6
  • AFL Warning: We probably want the fork() children to run first

    AFL Warning: We probably want the fork() children to run first

    1、Problem description Traceback (most recent call last): File "/home/angr/.virtualenvs/angr/bin/shellphuzz", line 7, in exec(compile(f.read(), file, 'exec')) File "/home/angr/angr-dev/fuzzer/shellphuzz", line 87, in memory=args.memory, seeds=seeds, timeout=args.run_timeout, File "/home/angr/angr-dev/fuzzer/fuzzer/fuzzer.py", line 99, in init Fuzzer._perform_env_checks() File "/home/angr/angr-dev/fuzzer/fuzzer/fuzzer.py", line 599, in _perform_env_checks raise InstallError(err) fuzzer.fuzzer.InstallError: AFL Warning: We probably want the fork() children to run first execute 'echo 1 | sudo tee /proc/sys/kernel/sched_child_runs_first'

    Exception ignored in: <bound method Fuzzer.del of <fuzzer.fuzzer.Fuzzer object at 0x7f188ab629e8>> Traceback (most recent call last): File "/home/angr/angr-dev/fuzzer/fuzzer/fuzzer.py", line 665, in del self.kill() File "/home/angr/angr-dev/fuzzer/fuzzer/fuzzer.py", line 266, in kill for p in self.procs: 2、my unsuccessful solution I run the following cmd in docker environment which gets from shellphish/mechaphish image. It output the above error message.I'm trying to modify the sched_child_runs_first config file. But it's readonly file that cannot be changed. How can i solve this problem? I'm very appreciated for you help. echo 1 | sudo tee /proc/sys/kernel/sched_child_runs_first tee: /proc/sys/kernel/sched_child_runs_first: Read-only file system

    opened by xiaozhouqi 1
  • Could not step to the first address of the trace - state split. Do you want to have a Tracer(fast_forward_to_entry=False)?

    Could not step to the first address of the trace - state split. Do you want to have a Tracer(fast_forward_to_entry=False)?

    I used driller to run a simple program. However i met this problem:

    WARNING | 2022-06-12 21:30:52,066 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000. Traceback (most recent call last): File "/home/nkamg/.virtualenvs/angr/lib/python3.8/site-packages/driller/local_callback.py", line 122, in <module> for new_input in d.drill_generator(): File "/home/nkamg/.virtualenvs/angr/lib/python3.8/site-packages/driller/driller_main.py", line 101, in drill_generator for i in self._drill_input(): File "/home/nkamg/.virtualenvs/angr/lib/python3.8/site-packages/driller/driller_main.py", line 131, in _drill_input simgr.use_technique(t) File "/home/nkamg/.virtualenvs/angr/lib/python3.8/site-packages/angr/sim_manager.py", line 207, in use_technique tech.setup(self) File "/home/nkamg/.virtualenvs/angr/lib/python3.8/site-packages/angr/exploration_techniques/tracer.py", line 293, in setup raise AngrTracerError("Could not step to the first address of the trace - state split. Do you want to have a Tracer(fast_forward_to_entry=False)?") angr.errors.AngrTracerError: Could not step to the first address of the trace - state split. Do you want to have a Tracer(fast_forward_to_entry=False)?

    i wanna know how to solve this problem?

    opened by MaggieCwj 0
  • AngrTracerError: Trace does not seem to contain object initializers for <ELF Object libutil-2.31.so, maps [0x500000:0x50410f]>. Do you want to have a Tracer(aslr=False)?

    AngrTracerError: Trace does not seem to contain object initializers for . Do you want to have a Tracer(aslr=False)?

    I'm trying to improve LiveOverflow's current sudo fuzzing series, by adding driller to the project. Since the Baron SameEdit vulnerability is triggered by using sudoedit, driller shall add 'edit' to the afl queue but sadly i get an error. I created a Dockerfile so you can easily recreate my current state:

    FROM aflplusplus/aflplusplus
    ARG DEBIAN_FRONTEND=noninteractive
    RUN useradd -ms /bin/bash user
    RUN apt-get update && apt-get install -yq build-essential gcc-multilib debootstrap debian-archive-keyring libtool-bin bison python3 python3-pip virtualenv git python3-dev automake lsb-release xxd
    RUN virtualenv -ppython3 /opt/venv
    RUN /opt/venv/bin/pip install git+https://github.com/angr/archinfo
    RUN /opt/venv/bin/pip install cle
    RUN /opt/venv/bin/pip install git+https://github.com/angr/claripy
    RUN /opt/venv/bin/pip install angr
    RUN /opt/venv/bin/pip install git+https://github.com/angr/tracer
    RUN /opt/venv/bin/pip install git+https://github.com/shellphish/driller
    RUN cd / && git clone https://github.com/SpaceMoehre/sudofuzz
    WORKDIR /sudofuzz
    RUN make clean && ./configure --disable-shared && make && make install
    RUN mkdir /tmp/in && mkdir /tmp/out && echo 'init' > /tmp/in/seed
    CMD afl-fuzz -Q -i /tmp/in -o /tmp/out -M fuzzer-master ./src/sudo
    

    For some reason i get errors when trying to install cle, angr via git+https, because of versioning...

    build and run:

    docker build - < Dockerfile
    docker run -it <image id>
    

    This will start the afl-fuzzer in qemu mode. in a second terminal i try to run my driller script:

    source /opt/venv/bin/activate
    python run_driller.py src/sudo /tmp/out/fuzzer-master
    

    This results in the following error:

    Drilling input: b'!!\x05\xff\xff\x05!\x1f!!!!!!!!!!!!\t!!!!#'
    WARNING | 2021-07-13 15:44:22,153 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000.
    WARNING | 2021-07-13 15:44:26,890 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000.
    Traceback (most recent call last):
      File "run_driller.py", line 70, in <module>
        main()
      File "run_driller.py", line 57, in main
        for _, new_input in Driller(binary, seed, fuzzer_bitmap).drill_generator():
      File "/opt/venv/lib/python3.8/site-packages/driller/driller_main.py", line 101, in drill_generator
        for i in self._drill_input():
      File "/opt/venv/lib/python3.8/site-packages/driller/driller_main.py", line 131, in _drill_input
        simgr.use_technique(t)
      File "/opt/venv/lib/python3.8/site-packages/angr/sim_manager.py", line 189, in use_technique
        tech.setup(self)
      File "/opt/venv/lib/python3.8/site-packages/angr/exploration_techniques/tracer.py", line 261, in setup
        self._identify_aslr_slides()
      File "/opt/venv/lib/python3.8/site-packages/angr/exploration_techniques/tracer.py", line 229, in _identify_aslr_slides
        raise AngrTracerError("Trace does not seem to contain object initializers for %s. Do you want to have a Tracer(aslr=False)?" % obj)
    angr.errors.AngrTracerError: Trace does not seem to contain object initializers for <ELF Object libutil-2.31.so, maps [0x500000:0x50410f]>. Do you want to have a Tracer(aslr=False)?
    

    I tested a few things and turns out the libutil used by qemu and driller pointed to the same file and aflplusplus does not appear to be the problem, manually set aslr=False in the tracer.py and disabled aslr but the error persists.

    opened by SpaceMoehre 0
  • Some Problems about TracerDesyncError, mode= 'tracing' and tracer

    Some Problems about TracerDesyncError, mode= 'tracing' and tracer

    There are some progress about #80. I find that when a program need a filepath as argv, and the filepath was used to read the file later, driller will crash with TracerDesyncError. After debugging it, the bug is located in the program argv and tracing mode.

    Here is the sample code

    #include <fcntl.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    int main(int argc, char** argv){
        if(argc==1){
            printf("argv needed\n");
            return 0;
        }
        int fd = open(argv[1],O_RDONLY);
        int input = 0;
        read(fd, &input, sizeof(input));
        if (input == 0xdeadbeef){
            printf("Good\n");
        }else{
            printf("Bad\n");
        }
        close(fd);
        return 0;
    }
    

    Below are some relative codes in driller._drill_input:

    #driller rebuild the trace with all argv
    r = tracer.qemu_runner.QEMURunner(self.binary, self.input, argv=self.argv)
    ...
    # angr init the simstate with mode='tracing' and with no argvs
    s = p.factory.full_init_state(stdin=angr.SimFileStream, mode='tracing')
    ...
    #use Tracer and other techniques
    t = angr.exploration_techniques.Tracer(trace=r.trace, crash_addr=r.crash_addr, copy_states=True)
    self._core=angr.exploration_techniques.DrillerCore(trace=r.trace,fuzz_bitmap=self.fuzz_bitmap)
    simgr.use_technique(t)#
    simgr.use_technique(angr.exploration_techniques.Oppologist())
    simgr.use_technique(self._core)
    

    This is the binary cfg picture in radare2 and the error point in angr

    radare2_point

    error_point

    We can see that 0x40065e(jump to when the argv length >1) wasn't ever in simgr.active which cause a conflict between qemu trace and angr trace history. I think this is because angr didn't initialize simstate with other argv. So when checking the argv length, angr get a concrete length 1(?).FInally, when Tracer._update_state_tracking is called in Tracer.step_state, driller will throw TracerDesyncError.

    I try to add args to full_init_state in Line122 :

    s = p.factory.full_init_state(stdin=angr.SimFileStream,mode='tracing', args=self.argv)
    

    Luckily, driller doesn't throw TracerDesyncError. But when finished no new input is generated. Debugging again,I find the something is still wrong at Line122.I don't know why angr always only have just one active when step() if simstate is initialized with parament mode='tracing', which will cause Tracer can't put any other states in missed stash (code in L365-L367)

    When I modify Line122 with the following code, it's working and can generate testcase driving to another path.

    # just remove parament:mode='tracing'
    s = p.factory.full_init_state(stdin=angr.SimFileStream, args=self.argv)
    

    Below is the complete code named DrillerFile. Mostly copyed from Driller, I just modify the code mentioned above and _writeout to get the target file concretize,.Also for simple, I delete the redis and other codes which is not reletive to this issue.

    Maybe a bit ugly:)

    import os
    import time
    import signal
    import hashlib
    import resource
    import pickle
    import logging
    import binascii
    
    import angr
    import tracer
    from . import config
    
    
    l = logging.getLogger("driller.driller")
    l.setLevel(logging.DEBUG)
    
    class DrillerFile(object):
        """
        DrillerFile is a simple patch to handle a special case that Driller can't handle properly(program with filepath as its argv) 
    
        Ignore the redis and cgc code for simple, just the basic code to handle linux x86 or x86_64 binary :)
        """
        def __init__(self,binary,input_str=None,fuzz_bitmap=None,hooks=None,argv=None):
            """
            :param binary     : The binary to be traced.
            :param input_str  : Input string to feed to the binary.
            :param fuzz_bitmap: AFL's bitmap of state transitions (defaults to empty).
            :param hooks      : Dictionary of addresses to simprocedures.
            :param argv       : Optionally specify argv params (i,e,: ['./calc', 'parm1']),
                                defaults to binary name with no params.
                                Note:if argv is a filepath,prefix it with @,
                                i.e,:['./objdump','-d','@./bin'] 
            """
            self.binary      = binary
            self.input       = input_str
            self.fuzz_bitmap = fuzz_bitmap
            self.fileargv=[]
            
            # parse file argv
            self.argv=list()
            if argv:
                for arg in argv:
                    if arg.startswith('@'):
                        self.argv.append(arg[1:])
                        self.fileargv.append(arg[1:])
                    else:
                        self.argv.append(arg)
            else:
                self.argv = [binary]
            
            # at least one input mode is needed
            if self.input==None:
                if len(self.fileargv)==0:
                    raise Exception("No input")
                else:
                    # input is needed in QEMURunner
                    self.input = b"\x00"
    
            #The following init code same to Driller
    
            self.base = os.path.join(os.path.dirname(__file__), "..")
    
            # The simprocedures.
            self._hooks = {} if hooks is None else hooks
    
            # The driller core, which is now an exploration technique in angr.
            self._core = None
    
            # Start time, set by drill method.
            self.start_time = time.time()
    
            # Set of all the generated inputs.
            # self._generated = set()
            self._generated = list()
    
            # Set the memory limit specified in the config.
            if config.MEM_LIMIT is not None:
                resource.setrlimit(resource.RLIMIT_AS, (config.MEM_LIMIT, config.MEM_LIMIT))
        
        def drill(self):
            """
            perform the drilling
            """
            
            list(self._drill_input())
            return self._generated
    
        def _drill_input(self):
            """
            symbolically step down a path with a tracer, trying to concretize inputs for unencountered
            """
    
            # rebuild the path with qemu
            r = tracer.qemu_runner.QEMURunner(self.binary, self.input, argv=self.argv)
            p = angr.Project(self.binary)
    
            # handle hooks
            for addr, proc in self._hooks.items():
                p.hook(addr, proc)
                l.debug("Hooking %#x -> %s...", addr, proc.display_name)
    
            # try to get an init simstate
            # check the argv 
            s = p.factory.full_init_state(stdin=angr.SimFileStream, args=self.argv)
            
            # preconstrain
            s.preconstrainer.preconstrain_file(self.input, s.posix.stdin, True)
    
            simgr = p.factory.simulation_manager(s, save_unsat=True, hierarchy=False, save_unconstrained=r.crash_mode)
    
            # use_technique
            t = angr.exploration_techniques.Tracer(trace=r.trace, crash_addr=r.crash_addr, copy_states=True)
            self._core = angr.exploration_techniques.DrillerCore(trace=r.trace, fuzz_bitmap=self.fuzz_bitmap)
    
            simgr.use_technique(t)
            simgr.use_technique(angr.exploration_techniques.Oppologist())
            simgr.use_technique(self._core)
    
            self._set_concretizations(simgr.one_active)
    
            while simgr.active and simgr.one_active.globals['trace_idx'] < len(r.trace) - 1:
                simgr.step()
    
                # if something in diverted
                if 'diverted' not in simgr.stashes:
                    continue
                
                while simgr.diverted:
                    state = simgr.diverted.pop(0)
                    l.debug("Found a diverted state, exploring to some extent.")
                    w = self._writeout(state.history.bbl_addrs[-1], state)
                    if w is not None:
                        yield w
                    # symbolic explore
                    for i in self._symbolic_explorer_stub(state):
                        yield i
    
    
        def _writeout(self, prev_addr, state):
            """
    
            writeout all inputs to a dict
            {
                "stdin":xxxxxxx,
                "filename":(length ,content),
                "block":(prev_addr, cur_addr)
            }
    
            """
            
            info = dict()
    
            # first the stdin 
            generated = state.posix.stdin.load(0, state.posix.stdin.pos)
            generated = state.solver.eval(generated, cast_to=bytes)
            info["stdin"] = generated
    
            # file argv
            for fd in self.fileargv:
                try:
                    content = state.fs.get(fd).concretize()
                    info[fd] = (len(content),content)
                #maybe the file is not needed
                except AttributeError:
                    info[fd] = (0,b"\x00")
    
            info["block"] = (prev_addr, state.addr)
    
            # self._generated.add()
            self._generated.append(info)
    
            return info
    
    
        def _symbolic_explorer_stub(self, state):
            
            """
            Create a new simulation manager and step it forward up to 1024
            accumulated active states or steps.
            """
            steps = 0
            accumulated = 1
    
            p = state.project
            state = state.copy()
    
            try:
                state.options.remove(angr.options.LAZY_SOLVES)
            except KeyError:
                pass
            simgr = p.factory.simulation_manager(state, hierarchy=False)
    
            l.debug("[%s] started symbolic exploration at %s.", self.binary, time.ctime())
    
            # try to explore
            while len(simgr.active) and accumulated < 1024:
                simgr.step()
                steps += 1
    
                # Dump all inputs.
                accumulated = steps * (len(simgr.active) + len(simgr.deadended))
    
            l.debug("[%s] stopped symbolic exploration at %s.", self.binary, time.ctime())
    
            # DO NOT think this is the same as using only the deadended stashes. this merges deadended and active
            simgr.stash(from_stash='deadended', to_stash='active')
    
            for dumpable in simgr.active:
                try:
                    if dumpable.satisfiable():
                        w = self._writeout(dumpable.history.bbl_addrs[-1], dumpable)
                        if w is not None:
                            yield w
    
                # If the state we're trying to dump wasn't actually satisfiable.
                except IndexError:
                    pass
    
    
        @staticmethod
        def _set_concretizations(state):
            # Let's put conservative thresholds for now.
            state.unicorn.concretization_threshold_memory = 50000
            state.unicorn.concretization_threshold_registers = 50000
    

    It works well on two simple binary below

    # testcase1 : file with content AAAA
    #include <fcntl.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    int main(int argc, char** argv){
        if(argc==1){
            printf("argv needed\n");
            return 0;
        }
        int fd = open(argv[1],O_RDONLY);
        int input = 0;
        read(fd, &input, sizeof(input));
        if (input == 0xdeadbeef){
            printf("Good\n");
        }else{
            printf("Bad\n");
        }
        close(fd);
        return 0;
    }
    
    # testcase2 stdin with b"11\n8\n"
    #include <stdio.h>
    int main(){
        int a = 0,b=1;
    
        scanf("%d",&a);
        if(a>10){
            scanf("%d",&b);
            if(b<10){
                printf("stage 2\n");
            }else{
                printf("stage 3\n");
            }
        }else{
            printf("stage 1\n");
        }
        return 0;
    }
    

    However when I run some other programs it still crash and I haven't find the reason.So what is the meaning or relationship about parament mode='tracing' in full_init_state and technique Tracer, or anything wrong with my understanding of it?

    (sorry for my poor English)

    opened by Ma5ker 0
  • Running CGC binaries with Driller

    Running CGC binaries with Driller

    Hello, I have been trying to run driller in a docker container and cannot seem to get it to work. The error I obtain -

    shellphuzz -d 2 -w workdir/shellphuzz/ -C --length-extension 4 ./CADET_00001 [*] Drilling... [*] Creating fuzzer... ERROR | 2020-09-03 16:33:21,002 | fuzzer.fuzzer | AFL Warning: We probably want the fork() children to run first execute 'echo 1 | sudo tee /proc/sys/kernel/sched_child_runs_first'

    Traceback (most recent call last): File "/home/angr/.virtualenvs/angr/bin/shellphuzz", line 7, in exec(compile(f.read(), file, 'exec')) File "/home/angr/angr-dev/fuzzer/shellphuzz", line 87, in memory=args.memory, seeds=seeds, timeout=args.run_timeout, File "/home/angr/angr-dev/fuzzer/fuzzer/fuzzer.py", line 99, in init Fuzzer._perform_env_checks() File "/home/angr/angr-dev/fuzzer/fuzzer/fuzzer.py", line 599, in _perform_env_checks raise InstallError(err) fuzzer.fuzzer.InstallError: AFL Warning: We probably want the fork() children to run first execute 'echo 1 | sudo tee /proc/sys/kernel/sched_child_runs_first'

    Exception ignored in: <bound method Fuzzer.del of <fuzzer.fuzzer.Fuzzer object at 0x7f6062895e10>> Traceback (most recent call last): File "/home/angr/angr-dev/fuzzer/fuzzer/fuzzer.py", line 665, in del self.kill() File "/home/angr/angr-dev/fuzzer/fuzzer/fuzzer.py", line 266, in kill for p in self.procs: AttributeError: 'Fuzzer' object has no attribute 'procs'

    Running 'echo 1 | sudo tee /proc/sys/kernel/sched_child_runs_first' tells me the file system is read_only.

    Any advice would be much appreciated.

    opened by tiwns 1
Owner
Shellphish
Shellphish
NEATEST: Evolving Neural Networks Through Augmenting Topologies with Evolution Strategy Training

NEATEST: Evolving Neural Networks Through Augmenting Topologies with Evolution Strategy Training

Göktuğ Karakaşlı 16 Dec 5, 2022
An AFL implementation with UnTracer (our coverage-guided tracer)

UnTracer-AFL This repository contains an implementation of our prototype coverage-guided tracing framework UnTracer in the popular coverage-guided fuz

null 113 Dec 17, 2022
FIRM-AFL is the first high-throughput greybox fuzzer for IoT firmware.

FIRM-AFL FIRM-AFL is the first high-throughput greybox fuzzer for IoT firmware. FIRM-AFL addresses two fundamental problems in IoT fuzzing. First, it

null 356 Dec 23, 2022
Fuzzing the Kernel Using Unicornafl and AFL++

Unicorefuzz Fuzzing the Kernel using UnicornAFL and AFL++. For details, skim through the WOOT paper or watch this talk at CCCamp19. Is it any good? ye

Security in Telecommunications 283 Dec 26, 2022
FairFuzz: AFL extension targeting rare branches

FairFuzz An AFL extension to increase code coverage by targeting rare branches. FairFuzz has a particular advantage on programs with highly nested str

Caroline Lemieux 222 Nov 16, 2022
IJON is an annotation mechanism that analysts can use to guide fuzzers such as AFL.

IJON SPACE EXPLORER IJON is an annotation mechanism that analysts can use to guide fuzzers such as AFL. Using only a small (usually one line) annotati

Chair for Sys­tems Se­cu­ri­ty 146 Dec 16, 2022
Directed Greybox Fuzzing with AFL

AFLGo: Directed Greybox Fuzzing AFLGo is an extension of American Fuzzy Lop (AFL). Given a set of target locations (e.g., folder/file.c:582), AFLGo ge

null 380 Nov 24, 2022
MOpt-AFL provided by the paper "MOPT: Optimized Mutation Scheduling for Fuzzers"

MOpt-AFL 1. Description MOpt-AFL is a AFL-based fuzzer that utilizes a customized Particle Swarm Optimization (PSO) algorithm to find the optimal sele

null 172 Dec 18, 2022
AFLFast (extends AFL with Power Schedules)

AFLFast Power schedules implemented by Marcel Böhme <[email protected]>. AFLFast is an extension of AFL which is written and maintained by Michal

Marcel Böhme 380 Jan 3, 2023
AFL binary instrumentation

E9AFL --- Binary AFL E9AFL inserts American Fuzzy Lop (AFL) instrumentation into x86_64 Linux binaries. This allows binaries to be fuzzed without the

null 242 Dec 12, 2022
Flappy bird automation using Neuroevolution of Augmenting Topologies (NEAT) in Python

FlappyAI Flappy bird automation using Neuroevolution of Augmenting Topologies (NEAT) in Python Everything Used Genetic Algorithm especially NEAT conce

Eryawan Presma Y. 2 Mar 24, 2022
SnapMix: Semantically Proportional Mixing for Augmenting Fine-grained Data (AAAI 2021)

SnapMix: Semantically Proportional Mixing for Augmenting Fine-grained Data (AAAI 2021) PyTorch implementation of SnapMix | paper Method Overview Cite

DavidHuang 126 Dec 30, 2022
Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. It can use GPUs and perform efficient symbolic differentiation.

============================================================================================================ `MILA will stop developing Theano <https:

null 9.6k Dec 31, 2022
Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. It can use GPUs and perform efficient symbolic differentiation.

============================================================================================================ `MILA will stop developing Theano <https:

null 9.6k Jan 6, 2023
Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. It can use GPUs and perform efficient symbolic differentiation.

============================================================================================================ `MILA will stop developing Theano <https:

null 9.3k Feb 12, 2021
ATOMIC 2020: On Symbolic and Neural Commonsense Knowledge Graphs

(Comet-) ATOMIC 2020: On Symbolic and Neural Commonsense Knowledge Graphs Paper Jena D. Hwang, Chandra Bhagavatula, Ronan Le Bras, Jeff Da, Keisuke Sa

AI2 152 Dec 27, 2022
PIGLeT: Language Grounding Through Neuro-Symbolic Interaction in a 3D World [ACL 2021]

piglet PIGLeT: Language Grounding Through Neuro-Symbolic Interaction in a 3D World [ACL 2021] This repo contains code and data for PIGLeT. If you like

Rowan Zellers 51 Oct 8, 2022
Symbolic Parallel Adaptive Importance Sampling for Probabilistic Program Analysis in JAX

SYMPAIS: Symbolic Parallel Adaptive Importance Sampling for Probabilistic Program Analysis Overview | Installation | Documentation | Examples | Notebo

Yicheng Luo 4 Sep 13, 2022
Official repository for the paper, MidiBERT-Piano: Large-scale Pre-training for Symbolic Music Understanding.

MidiBERT-Piano Authors: Yi-Hui (Sophia) Chou, I-Chun (Bronwin) Chen Introduction This is the official repository for the paper, MidiBERT-Piano: Large-

null 137 Dec 15, 2022