コード例 #1
0
ファイル: afl.py プロジェクト: ruaronicola/phuzzer
    def choose_afl(self):
        """
        Chooses the right AFL and sets up some environment.
        """

        # set up the AFL path
        p = angr.Project(self.target)
        target_os = p.loader.main_object.os
        afl_dir = shellphish_afl.afl_dir(target_os)

        if target_os == 'cgc':
            afl_path_var = shellphish_afl.afl_path_var('cgc')
        else:
            afl_path_var = shellphish_afl.afl_path_var(p.arch.qemu_name)
            directory = None
            if p.arch.qemu_name == "aarch64":
                directory = "arm64"
            if p.arch.qemu_name == "i386":
                directory = "i386"
            if p.arch.qemu_name == "x86_64":
                directory = "x86_64"
            if p.arch.qemu_name == "mips":
                directory = "mips"
            if p.arch.qemu_name == "mipsel":
                directory = "mipsel"
            if p.arch.qemu_name == "ppc":
                directory = "powerpc"
            if p.arch.qemu_name == "arm":
                # some stuff qira uses to determine the which libs to use for arm
                with open(self.target, "rb") as f:
                    progdata = f.read(0x800)
                if "/lib/ld-linux.so.3" in progdata:
                    directory = "armel"
                elif "/lib/ld-linux-armhf.so.3" in progdata:
                    directory = "armhf"

            if directory is None:
                l.warning("architecture \"%s\" has no installed libraries",
                          p.arch.qemu_name)
            else:
                libpath = os.path.join(afl_dir, "..", "fuzzer-libs", directory)

                l.debug("exporting QEMU_LD_PREFIX of '%s'", libpath)
                os.environ['QEMU_LD_PREFIX'] = libpath

        # set environment variable for the AFL_PATH
        os.environ['AFL_PATH'] = afl_path_var

        # return the AFL path
        return shellphish_afl.afl_bin(target_os)
コード例 #2
0
    def __init__(self, binary_path, work_dir, afl_count=1, library_path=None, time_limit=None,
            target_opts=None, extra_opts=None, create_dictionary=False,
            seeds=None, crash_mode=False, never_resume=False):
        '''
        :param binary_path: path to the binary to fuzz. List or tuple for multi-CB.
        :param work_dir: the work directory which contains fuzzing jobs, our job directory will go here
        :param afl_count: number of AFL jobs total to spin up for the binary
        :param library_path: library path to use, if none is specified a default is chosen
        :param timelimit: amount of time to fuzz for, has no effect besides returning True when calling timed_out
        :param seeds: list of inputs to seed fuzzing with
        :param target_opts: extra options to pass to the target
        :param extra_opts: extra options to pass to AFL when starting up
        :param crash_mode: if set to True AFL is set to crash explorer mode, and seed will be expected to be a crashing input
        :param never_resume: never resume an old fuzzing run, even if it's possible
        '''

        self.binary_path    = binary_path
        self.work_dir       = work_dir
        self.afl_count      = afl_count
        self.time_limit     = time_limit
        self.library_path   = library_path
        self.target_opts    = [ ] if target_opts is None else target_opts
        self.crash_mode     = crash_mode

        Fuzzer._perform_env_checks()

        if isinstance(binary_path,basestring):
            self.is_multicb = False
            self.binary_id = os.path.basename(binary_path)
        elif isinstance(binary_path,(list,tuple)):
            self.is_multicb = True
            self.binary_id = os.path.basename(binary_path[0])
        else:
            raise ValueError("Was expecting either a string or a list/tuple for binary_path! It's {} instead.".format(type(binary_path)))

        # sanity check crash mode
        if self.crash_mode:
            if seeds is None:
                raise ValueError("Seeds must be specified if using the fuzzer in crash mode")
            l.info("AFL will be started in crash mode")

        self.seeds          = ["fuzz"] if seeds is None or len(seeds) == 0 else seeds

        self.job_dir  = os.path.join(self.work_dir, self.binary_id)
        self.in_dir   = os.path.join(self.job_dir, "input")
        self.out_dir  = os.path.join(self.job_dir, "sync")

        # sanity check extra opts
        self.extra_opts = extra_opts
        if self.extra_opts is not None:
            if not isinstance(self.extra_opts, list):
                raise ValueError("extra_opts must be a list of command line arguments")

        # base of the fuzzer package
        self.base = Fuzzer._get_base()

        self.start_time       = int(time.time())
        # create_dict script
        self.create_dict_path = os.path.join(self.base, "bin", "create_dict.py")
        # afl dictionary
        self.dictionary       = None
        # processes spun up
        self.procs            = [ ]
        # start the fuzzer ids at 0
        self.fuzz_id          = 0
        # test if we're resuming an old run
        self.resuming         = bool(os.listdir(self.out_dir)) if os.path.isdir(self.out_dir) else False
        # has the fuzzer been turned on?
        self._on = False

        if never_resume and self.resuming:
            l.info("could resume, but starting over upon request")
            shutil.rmtree(self.job_dir)
            self.resuming = False

        if self.is_multicb:
            # Where cgc/setup's Dockerfile checks it out
            # NOTE: 'afl/fakeforksrv' serves as 'qemu', as far as AFL is concerned
            #       Will actually invoke 'fakeforksrv/multicb-qemu'
            #       This QEMU cannot run standalone (always speaks the forkserver "protocol"),
            #       but 'fakeforksrv/run_via_fakeforksrv' allows it.
            # XXX: There is no driller/angr support, and probably will never be.
            self.afl_path = shellphish_afl.afl_bin('multi-cgc')
            self.afl_path_var = shellphish_afl.afl_path_var('multi-cgc')
        else:

            p = angr.Project(binary_path)

            self.os = p.loader.main_bin.os

            afl_dir               = shellphish_afl.afl_dir(self.os)

            # the path to AFL capable of calling driller
            self.afl_path         = shellphish_afl.afl_bin(self.os)

            self.afl_path_var     = shellphish_afl.afl_path_var(p.arch.qemu_name)

            # set up libraries
            self._export_library_path(p)

        self.qemu_dir         = self.afl_path_var

        l.debug("self.start_time: %r", self.start_time)
        l.debug("self.afl_path: %s", self.afl_path)
        l.debug("self.afl_path_var: %s", self.afl_path_var)
        l.debug("self.qemu_dir: %s", self.qemu_dir)
        l.debug("self.binary_id: %s", self.binary_id)
        l.debug("self.work_dir: %s", self.work_dir)
        l.debug("self.resuming: %s", self.resuming)

        # if we're resuming an old run set the input_directory to a '-'
        if self.resuming:
            l.info("[%s] resuming old fuzzing run", self.binary_id)
            self.in_dir = "-"

        else:
            # create the work directory and input directory
            try:
                os.makedirs(self.in_dir)
            except OSError:
                l.warning("unable to create in_dir \"%s\"", self.in_dir)

            # populate the input directory
            self._initialize_seeds()

        # look for a dictionary
        dictionary_file = os.path.join(self.job_dir, "%s.dict" % self.binary_id)
        if os.path.isfile(dictionary_file):
            self.dictionary = dictionary_file

        # if a dictionary doesn't exist and we aren't resuming a run, create a dict
        elif not self.resuming:
            # call out to another process to create the dictionary so we can
            # limit it's memory
            if create_dictionary:
                if self._create_dict(dictionary_file):
                    self.dictionary = dictionary_file
                else:
                    # no luck creating a dictionary
                    l.warning("[%s] unable to create dictionary", self.binary_id)

        # set environment variable for the AFL_PATH
        os.environ['AFL_PATH'] = self.afl_path_var
コード例 #3
0
import shutil
import hashlib
#import tarfile
import subprocess
import shellphish_afl

if __name__ == "__main__":
    # minimizing code
    p = os.path.join("/tmp/", "afl_seeds")
    try:
        os.mkdir(p)
    except OSError:
        pass

    afl_path_var = shellphish_afl.afl_path_var('cgc')
    afl_path = shellphish_afl.afl_bin('cgc')
    BIN = sys.argv[1]
    IN_DIR = sys.argv[2]
    OUT_DIR = sys.argv[3]
    os.environ['AFL_PATH'] = afl_path_var

    # set afl-showmap (super hacky)
    shutil.copy2(os.path.join(afl_path_var, "../../afl-showmap"), afl_path_var)

    # run afl-cmin
    print "### cmin time (binary %s)" % BIN

    args = [os.path.join(os.path.dirname(__file__), "../afl-cmin")]

    print "collecting seeds"
    if os.path.exists("/home/angr/cmin-input"):
コード例 #4
0
ファイル: afl_plusplus.py プロジェクト: ruaronicola/phuzzer
    def choose_afl(self):
        """
        Chooses the right AFL and sets up some environment.
        """

        # set up the AFL path
        self.proj = self.proj or angr.Project(self.target,
                                              auto_load_libs=False)
        self.target_os = self.proj.loader.main_object.os
        self.target_arch = self.proj.arch.qemu_name

        afl_dir = shellphish_afl.afl_dir(self.target_os)
        afl_path_var = shellphish_afl.afl_path_var(self.target_arch)

        directory = None
        if self.target_arch == "i386":
            directory = "i386"
            qemu_base = 0x40000000
        if self.target_arch == "x86_64":
            directory = "x86_64"
            qemu_base = 0x4000000000

        if directory is None:
            l.warning("architecture \"%s\" has no installed libraries",
                      self.target_arch)
        elif False:  # for now, avoid mixing up libs
            libpath = os.path.join(afl_dir, "..", "fuzzer-libs", directory)

            l.debug("exporting QEMU_LD_PREFIX=%s", libpath)
            os.environ['QEMU_LD_PREFIX'] = libpath

        l.debug("exporting AFL_PATH=%s", afl_path_var)
        os.environ['AFL_PATH'] = afl_path_var

        libcompcovpath = os.path.join(afl_dir, "libcompcov.so")
        libdislocatorpath = os.path.join(afl_dir, "libdislocator.so")
        afl_preload = " ".join([libcompcovpath, libdislocatorpath])
        afl_preload = f"'{afl_preload}'"
        l.debug("exporting AFL_PRELOAD=%s", afl_preload)
        os.environ['AFL_PRELOAD'] = afl_preload

        l.debug("exporting AFL_COMPCOV_LEVEL=2")
        os.environ[
            'AFL_COMPCOV_LEVEL'] = "2"  # CompareCoverage instrumentation

        # set entrypoint
        main = self.proj.loader.find_symbol('main')
        entrypoint = main.rebased_addr if main else self.proj.entry

        if self.proj.loader.main_object.pic:
            entrypoint = self.proj.loader.main_object.addr_to_offset(
                entrypoint)
            entrypoint += qemu_base

        #l.debug("exporting QEMU_SET_ENV=%s", f"QEMU_GUEST_BASE={hex(qemu_base)}")
        os.environ['QEMU_SET_ENV'] = f"QEMU_GUEST_BASE={hex(qemu_base)}"

        l.debug("exporting AFL_ENTRYPOINT=%s", hex(entrypoint))
        os.environ['AFL_ENTRYPOINT'] = hex(entrypoint)

        #if not self.proj.loader.main_object.pic:
        #l.debug("exporting AFL_QEMU_PERSISTENT_ADDR=%s", hex(entrypoint))
        #os.environ['AFL_QEMU_PERSISTENT_ADDR'] = hex(entrypoint)
        #os.environ['AFL_QEMU_PERSISTENT_GPR'] = "1"

        # return the AFL path
        return shellphish_afl.afl_bin(self.target_os)
コード例 #5
0
 def choose_afl(self):
     os.environ['AFL_PATH'] = shellphish_afl.afl_path_var('multi-cgc')
     return shellphish_afl.afl_bin('multi-cgc')
コード例 #6
0
 def __init__(self, targets, **kwargs):
     super().__init__(targets[0], **kwargs)
     self.afl_path = shellphish_afl.afl_bin('multi-cgc')
     self.afl_path_var = shellphish_afl.afl_path_var('multi-cgc')
     self.timeout = 1000 * len(targets)
     self.target_opts = targets[1:]