コード例 #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
ファイル: qemu_runner.py プロジェクト: yanshu911/long-driller
    def _run_multicb_trace(self, stdout_file=None):
        args = [self._fakeforksrv_path]
        args += self._binaries

        stderr_file = tempfile.mktemp(dir="/dev/shm/",
                                      prefix="tracer-multicb-stderr-")

        saved_afl_path = os.environ.get('AFL_PATH', None)
        with open('/dev/null', 'wb') as devnull:
            os.environ['AFL_PATH'] = shellphish_afl.afl_dir('multi-cgc')

            stdout_f = devnull
            if stdout_file is not None:
                stdout_f = open(stdout_file, 'wb')

            stderr_f = open(stderr_file, 'wb')

            p = None
            try:
                p = subprocess32.Popen(args,
                                       stdin=subprocess32.PIPE,
                                       stdout=stdout_f,
                                       stderr=stderr_f,
                                       close_fds=True,
                                       preexec_fn=self.__get_rlimit_func())

                _, _ = p.communicate(self.input, timeout=self.trace_timeout)

                ret = p.wait(timeout=self.trace_timeout)

            except subprocess32.TimeoutExpired:
                if p != None:
                    p.terminate()
                    self.tmout = True

            self.returncode = p.returncode

            if stdout_file is not None:
                stdout_f.close()

            stderr_f.close()

        if saved_afl_path:
            os.environ['AFL_PATH'] = saved_afl_path

        with open(stderr_file, 'r') as f:
            buf = f.read()
            for line in buf.split("\n"):
                if "signaled" in line:
                    self.crash_mode = bool(int(line.split(":")[-1]))
コード例 #3
0
    def init_afl_config(binary_path, is_multicb=False):
        """
        Returns AFL_PATH and AFL_DIR, if AFL_PATH is set in os.environ it returns that, if not it attempts to auto-detect
        :param binary_path:
        :return: afl_path_var, afl_dir, qemu_arch_name: afl_path_var is location of qemu_trace to use, afl_dir is the location of the afl binaries, qemu_arch_name is the name of the binary's architecture
        """

        if Phuzzer.afl_bin_dir is not None:
            return Phuzzer.afl_bin_dir, Phuzzer.qemu_arch_name

        if "AFL_PATH" in os.environ:
            Phuzzer.afl_bin_dir = os.environ["AFL_PATH"]
        else:

            if not ANGR_INSTALLED:
                raise ModuleNotFoundError(
                    "AFL_PATH was found in enviornment variables and angr is not installed."
                )
            if not SHELLPHISH_AFL_INSTALLED:
                raise ModuleNotFoundError(
                    "AFL_PATH was found in enviornment variables and either shellphish_afl is not installed."
                )
            try:
                p = angr.Project(binary_path)
                Phuzzer.qemu_arch_name = p.arch.qemu_name
                tracer_id = 'cgc' if p.loader.main_object.os == 'cgc' else p.arch.qemu_name
                if is_multicb:
                    tracer_id = 'multi-{}'.format(tracer_id)

                afl_path_var = shellphish_afl.afl_path_var(tracer_id)
                os.environ['AFL_PATH'] = afl_path_var

                Phuzzer.afl_bin_dir = shellphish_afl.afl_dir(tracer_id)
                print(f"afl_dir {Phuzzer.afl_bin_dir}")

            except Exception:

                traceback.format_exc()
                raise ModuleNotFoundError(
                    "AFL_PATH was found in enviornment variables and "
                    "either angr or shellphish_afl is not installed.")

        return Phuzzer.afl_bin_dir, Phuzzer.qemu_arch_name
コード例 #4
0
    def __init__(self, binary_path, testcase):
        """
        :param binary_path: path to the binary which the testcase applies to
        :param testcase: string representing the contents of the testcase
        """

        self.binary_path = binary_path
        self.testcase = testcase

        Fuzzer._perform_env_checks()

        self.base = Fuzzer._get_base()
        l.debug("got base dir %s", self.base)

        # unfortunately here is some code reuse between Fuzzer and Minimizer
        p = angr.Project(self.binary_path)
        tracer_id = 'cgc' if p.loader.main_object.os == 'cgc' else p.arch.qemu_name
        self.tmin_path = os.path.join(shellphish_afl.afl_dir(tracer_id),
                                      "afl-tmin")
        self.afl_path_var = shellphish_afl.afl_path_var(tracer_id)

        l.debug("tmin_path: %s", self.tmin_path)
        l.debug("afl_path_var: %s", self.afl_path_var)

        os.environ['AFL_PATH'] = self.afl_path_var

        # create temp
        self.work_dir = tempfile.mkdtemp(prefix='tmin-', dir='/tmp/')

        # flag for work directory removal
        self._removed = False

        self.input_testcase = os.path.join(self.work_dir, 'testcase')
        self.output_testcase = os.path.join(self.work_dir, 'minimized_result')

        l.debug("input_testcase: %s", self.input_testcase)
        l.debug("output_testcase: %s", self.output_testcase)

        # populate contents of input testcase
        with open(self.input_testcase, 'wb') as f:
            f.write(testcase)
コード例 #5
0
ファイル: afl_plusplus.py プロジェクト: ruaronicola/phuzzer
    def cmin(self, fuzzer_prefix="fuzzer-"):
        afl_dir = shellphish_afl.afl_dir(self.target_os)
        afl_path_var = shellphish_afl.afl_path_var(self.target_arch)
        os.environ['AFL_PATH'] = afl_path_var

        # create queue.all dir
        if os.path.exists(self.queue_all_dir):
            shutil.rmtree(self.queue_all_dir)
        os.makedirs(self.queue_all_dir)

        # copy all seeds
        for seed in glob(f"{self.work_dir}/{fuzzer_prefix}*/queue/id:*"):
            id = seed.split("/")[-1]
            fuzzer = seed.split("/queue")[0].split("/")[-1]
            shutil.copy(seed, f"{self.queue_all_dir}/{{{fuzzer}}}{id}")

        # create queue.cmin
        if os.path.exists(self.queue_min_dir):
            shutil.rmtree(self.queue_min_dir)
        os.makedirs(self.queue_min_dir)

        # create cmd args
        cmin_path = os.path.join(afl_dir, "afl-cmin")
        args = [cmin_path]

        args += ["-i", self.queue_all_dir]
        args += ["-o", self.queue_min_dir]
        args += ["-m", self.memory]
        args += ["-Q"]
        args += ["--"]
        args += [self.target]
        args += self.target_opts

        #l.debug(f"execing: AFL_PATH={afl_path_var} {' '.join(args)}")
        return subprocess.Popen(args,
                                env=os.environ,
                                stdout=subprocess.DEVNULL,
                                stderr=subprocess.DEVNULL,
                                close_fds=True)
コード例 #6
0
ファイル: afl_plusplus.py プロジェクト: ruaronicola/phuzzer
    def _check_environment():
        err = ""
        # check for afl sensitive settings
        with open("/proc/sys/kernel/core_pattern") as f:
            if not "core" in f.read():
                err += "!!!! AFL ERROR: Pipe at the beginning of core_pattern\n"
                err += "++++ TO FIX THIS, LITERALLY JUST EXECUTE THIS COMMAND:\n"
                err += "     echo core | sudo tee /proc/sys/kernel/core_pattern\n"

        # This file is based on a driver not all systems use
        # http://unix.stackexchange.com/questions/153693/cant-use-userspace-cpufreq-governor-and-set-cpu-frequency
        # TODO: Perform similar performance check for other default drivers.
        if os.path.exists(
                "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"):
            with open("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
                      ) as f:
                if not "performance" in f.read():
                    err += "!!!! AFL ERROR: Suboptimal CPU scaling governor\n"
                    err += "++++ TO FIX THIS, LITERALLY JUST EXECUTE THIS COMMAND:\n"
                    err += "    echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor\n"

        # TODO: test, to be sure it doesn't mess things up
        with open("/proc/sys/kernel/sched_child_runs_first") as f:
            if not "1" in f.read():
                err += "!!!! AFL WARNING: We probably want the fork() children to run first\n"
                err += "++++ TO FIX THIS, LITERALLY JUST EXECUTE THIS COMMAND:\n"
                err += "     echo 1 | sudo tee /proc/sys/kernel/sched_child_runs_first\n"

        if err:
            afl_dir = shellphish_afl.afl_dir('linux')
            configpath = os.path.join(afl_dir, "afl-system-config")
            err += "!!!! AFL WARNING: The environment was not properly configured\n"
            err += "++++ TO FIX THIS, LITERALLY JUST EXECUTE THIS COMMAND:\n"
            err += "     sudo sh " + configpath + "\n"
            err += "++++ YOU MAY ALSO ADD TO /etc/default/grub:\n"
            err += "     GRUB_CMDLINE_LINUX_DEFAULT='ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off'"
            raise InstallError(err)
コード例 #7
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
コード例 #8
0
    def __init__(self,
                 binary,
                 input=None,
                 pov_file=None,
                 record_trace=False,
                 record_stdout=False,
                 record_magic=False,
                 seed=None,
                 memory_limit="8G",
                 bitflip=False,
                 report_bad_args=False,
                 use_tiny_core=False,
                 qemu=None):
        """
        :param binary: path to the binary to be traced
        :param input: concrete input string to feed to binary
        :param pov_file: CGC PoV describing the input to trace
        :param record_trace: whether or not to record the basic block trace
        :param report_bad_arg: enable CGC QEMU's report bad args option
        :param use_tiny_core: Use minimal core loading
        """

        if isinstance(binary, basestring):
            self.is_multicb = False
            self.binaries = [binary]
        elif isinstance(binary, (list, tuple)):
            if not multicb_available:
                raise ValueError("Multicb tracing is disabled")
            self.is_multicb = True
            self.binaries = binary

        else:
            raise ValueError(
                "Expected list or string for binary, got {} instead".format(
                    type(binary)))

        self.input = input
        self.pov_file = pov_file
        self._record_magic = record_magic
        self._record_trace = record_trace

        if record_trace and self.is_multicb:
            l.warning(
                "record_trace specified with multicb, no trace will be recorded"
            )

        self.trace = []
        self.crashed_binary = 0
        self.reg_vals = None
        self._state = None
        self.memory = None
        self.seed = seed
        self.memory_limit = memory_limit
        self.bitflip = bitflip

        if self.bitflip and self.is_multicb:
            raise ValueError("Cannot perform bitflip with MultiCB")

        self.report_bad_args = report_bad_args
        self.use_tiny_core = use_tiny_core

        if self.pov_file is None and self.input is None:
            raise ValueError("must specify input or pov_file")

        if self.pov_file is not None and self.input is not None:
            raise ValueError("cannot specify both a pov_file and an input")

        # a PoV was provided
        if self.pov_file is not None:
            self.pov_file = TracerPoV(self.pov_file)
            self.pov = True
        else:
            self.pov = False

        self.base = os.path.join(os.path.dirname(__file__), "..", "..")

        self.tracer_qemu = None
        self.tracer_qemu_path = None
        self.forced_qemu = qemu

        self.fakeforksrv_path = os.path.join(
            shellphish_afl.afl_dir('multi-cgc'), "run_via_fakeforksrv")

        self._setup()

        l.debug("accumulating basic block trace...")
        l.debug("self.tracer_qemu_path: %s", self.tracer_qemu_path)

        # does the input cause a crash?
        self.crash_mode = False
        # if the input causes a crash, what address does it crash at?
        self.crash_addr = None

        self.stdout = None
        self.magic = None

        if record_stdout:
            tmp = tempfile.mktemp(prefix="stdout_" + os.path.basename(binary))
            # will set crash_mode correctly
            self.dynamic_trace(stdout_file=tmp)
            with open(tmp, "rb") as f:
                self.stdout = f.read()
            os.remove(tmp)
        else:
            # will set crash_mode correctly
            self.dynamic_trace()
コード例 #9
0
ファイル: showmap.py プロジェクト: ruaronicola/phuzzer
    def __init__(self, binary_path, testcase, timeout=None):
        """
        :param binary_path: path to the binary which the testcase applies to
        :param testcase: string representing the contents of the testcase
        :param timeout: millisecond timeout
        """

        self.binary_path = binary_path
        self.testcase = testcase
        self.timeout = None

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

        if timeout is not None:
            if isinstance(timeout, int):
                self.timeout = str(timeout)
            elif isinstance(timeout, (str)):
                self.timeout = timeout
            elif isinstance(timeout, (bytes)):
                self.timeout = timeout.decode('utf-8')
            else:
                raise ValueError("timeout param must be of type int or str")

        # will be set by showmap's return code
        self.causes_crash = False

        AFL.check_environment()

        # unfortunately here is some code reuse between Phuzzer and Minimizer (and Showmap!)
        p = angr.Project(self.binaries[0])
        tracer_id = 'cgc' if p.loader.main_object.os == 'cgc' else p.arch.qemu_name
        if self.is_multicb:
            tracer_id = 'multi-{}'.format(tracer_id)

        self.showmap_path = os.path.join(shellphish_afl.afl_dir(tracer_id),
                                         "afl-showmap")
        self.afl_path_var = shellphish_afl.afl_path_var(tracer_id)

        l.debug("showmap_path: %s", self.showmap_path)
        l.debug("afl_path_var: %s", self.afl_path_var)

        os.environ['AFL_PATH'] = self.afl_path_var

        # create temp
        self.work_dir = tempfile.mkdtemp(prefix='showmap-', dir='/tmp/')

        # flag for work directory removal
        self._removed = False

        self.input_testcase = os.path.join(self.work_dir, 'testcase')
        self.output = os.path.join(self.work_dir, 'out')

        l.debug("input_testcase: %s", self.input_testcase)
        l.debug("output: %s", self.output)

        # populate contents of input testcase
        with open(self.input_testcase, 'wb') as f:
            f.write(testcase)
コード例 #10
0
    def __init__(self, binary=None, input=None, project=None, record_trace=True, record_stdout=False,
                 record_magic=True, record_core=False, seed=None, memory_limit="8G", bitflip=False, report_bad_args=False,
                 use_tiny_core=False, max_size=None, qemu=None, argv=None,
                 trace_log_limit=2**30, trace_timeout=10):
        """
        :param binary        : Path to the binary to be traced.
        :param input         : Concrete input to feed to binary (string or CGC TracerPoV).
        :param project       : The original project.
        :param record_trace  : Whether or not to record the basic block trace.
        :param record_stdout : Whether ot not to record the output of tracing process.
        :param record_magic  : Whether ot not to record the magic flag page as reported by QEMU.
        :param record_core   : Whether or not to record the core file in case of crash.
        :param report_bad_arg: Enable CGC QEMU's report bad args option.
        :param use_tiny_core : Use minimal core loading.
        :param max_size      : Optionally set max size of input. Defaults to size
                               of preconstrained input.
        :param qemu          : Path to QEMU to be forced used.
        :param argv          : Optionally specify argv params (i,e,: ['./calc', 'parm1']).
                               Defaults to binary name with no params.
        :param trace_log_limit: Optionally specify the dynamic trace log file
            size limit in bytes, defaults to 1G.
        :param trace_timeout  : Optionally specify the dymamic time limit in seconds
            defaults to 10 seconds.
        """
        if type(input) not in (str, TracerPoV):
            raise RunnerEnvironmentError("Input for tracing should be either a string or a TracerPoV for CGC PoV file.")

        Runner.__init__(self, binary=binary, input=input, project=project, record_trace=record_trace,
                        record_core=record_core, use_tiny_core=use_tiny_core, trace_source_path=qemu, argv=argv)

        self.tmout = False
        self._record_magic = record_magic and self.os == 'cgc'

        if record_trace and self.is_multicb:
            l.warning("record_trace specified with multicb, no trace will be recorded")

        if isinstance(seed, (int, long)):
            seed = str(seed)
        self._seed = seed
        self._memory_limit = memory_limit
        self._bitflip = bitflip

        if self._bitflip and self.is_multicb:
            raise ValueError("Cannot perform bitflip with MultiCB")

        self._report_bad_args = report_bad_args

        if self.input is None:
            raise ValueError("Must specify input.")

        # validate seed
        if self._seed is not None:
            try:
                iseed = int(self._seed)
                if iseed > 4294967295 or iseed < 0:
                    raise ValueError
            except ValueError:
                raise ValueError("The passed seed is either not an integer or is not between 0 and UINT_MAX")

        self.input_max_size = max_size or len(input) if input is not None else None

        self.trace_log_limit = trace_log_limit
        self.trace_timeout = trace_timeout
        if self.is_multicb:
            self._fakeforksrv_path = os.path.join(shellphish_afl.afl_dir('multi-cgc'), "run_via_fakeforksrv")

        self._setup()

        l.debug("Accumulating basic block trace...")
        l.debug("tracer qemu path: %s", self._trace_source_path)

        self.stdout = None

        # We need this to keep symbolic traces following the same path
        # as their dynamic counterpart
        self.magic = None

        if record_stdout:
            tmp = tempfile.mktemp(prefix="stdout_" + os.path.basename(binary))
            # will set crash_mode correctly
            self._run(stdout_file=tmp)
            with open(tmp, "rb") as f:
                self.stdout = f.read()
            os.remove(tmp)
        else:
            # will set crash_mode correctly
            self._run()
コード例 #11
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)
コード例 #12
0
try:
    import tracer, angr, fuzzer, shellphish_afl
except:
    logger.error(
        "Unable to find required angr/mechaphish libraries. Make sure mechaphish is installed."
    )
    exit(1)

# Just to be sure...
try:
    input = raw_input
except:
    pass

AFL_ROOT = shellphish_afl.afl_dir('unix')


class AFL(Fuzzer):
    def __init__(self, bininfo):

        self.fuzzer = None
        self.target = GlobalConfig.target
        self.target_args = GlobalConfig.arguments
        self.work_dir = GlobalConfig.work_dir
        self.threads = GlobalConfig.threads
        self.seeds = GlobalConfig.seeds

        # Use QEMU or not?
        self.qemu = not bininfo.afl
        self.dictionary = None
コード例 #13
0
ファイル: AFL.py プロジェクト: Owlz/autoPwn
from . import *
from ..Config import global_config as GlobalConfig

try:
    import tracer, angr, fuzzer, shellphish_afl
except:
    logger.error("Unable to find required angr/mechaphish libraries. Make sure mechaphish is installed.")
    exit(1)

# Just to be sure...
try:
    input = raw_input
except:
    pass

AFL_ROOT = shellphish_afl.afl_dir('unix')

class AFL(Fuzzer):

    def __init__(self, bininfo):
        
        self.fuzzer = None
        self.target = GlobalConfig.target
        self.target_args = GlobalConfig.arguments
        self.work_dir = GlobalConfig.work_dir
        self.threads = GlobalConfig.threads
        self.seeds = GlobalConfig.seeds

        # Use QEMU or not?
        self.qemu = not bininfo.afl
        self.dictionary = None