def divide_by_signal(self, confirmation_loops=0, function=shutil.copyfile):
     if self.output_dir is not None and not os.path.exists(self.output_dir):
         os.mkdir(self.output_dir)
     ex = Executer(self.config)
     for path, _, files in os.walk(self.search_dir):
         for filename in files:
             if filename.endswith(self.config.run_extension):
                 continue
             filepath = os.path.join( path, filename )
             command = self.config.get_command_line(self.binary_to_use, filepath)
             Logger.debug("Executing:", command, debug_level=4)
             Logger.busy()
             signal = ex.get_signal_for_run(command, env=self.config.env)
             while confirmation_loops > 0:
                 Logger.busy()
                 new_signal = ex.get_signal_for_run(command, env=self.config.env)
                 if new_signal == signal:
                     signal = new_signal
                     confirmation_loops -= 1
                 else:
                     Logger.info("Detected varying return codes for exactly the same run")
                     signal = SignalFinder.VARYING_SIGNAL
                     break
             Logger.debug("We consider signal %i for input file %s" % (signal, filename), debug_level=5)
             destination_dir = self.get_folder_path_for_signal(signal)
             if not os.path.exists(destination_dir):
                 os.mkdir(destination_dir)
             function(filepath, os.path.join(destination_dir, filename))
 def minimize_testcases(self):
     executer = Executer(self.config)
     for path, _, files in os.walk(self.search_dir):
         for filename in files:
             if filename.endswith(self.config.run_extension):
                 continue
             Logger.info("Minimizing", filename)
             filepath = os.path.join(path, filename)
             cmd = self.config.get_afl_tmin_command_line(filepath, os.path.join(self.output_dir, filename))
             Logger.debug("Executing:", cmd)
             signal = executer.get_signal_for_run(cmd, self.config.run_timeout_tmin, env=self.config.env)
             if signal == SignalFinder.TIMEOUT_SIGNAL:
                 Logger.error("Minimizing this file took too long, aborted")
Пример #3
0
 def minimize_testcases(self):
     if self.output_dir is not None and not os.path.exists(self.output_dir):
         os.mkdir(self.output_dir)
     executer = Executer(self.config)
     for path, _, files in os.walk(self.search_dir):
         for filename in files:
             if filename.endswith(self.config.run_extension):
                 continue
             Logger.info("Minimizing", filename)
             filepath = os.path.join(path, filename)
             cmd = self.config.get_afl_tmin_command_line(
                 filepath, os.path.join(self.output_dir, filename))
             Logger.debug("Executing:", cmd)
             Logger.busy()
             signal = executer.run_command(
                 cmd,
                 timeout=self.config.run_timeout_tmin,
                 env=self.config.env)
             if signal == SignalFinder.TIMEOUT_SIGNAL:
                 Logger.error("Minimizing this file took too long, aborted")
 def _combined_stdout_stderr(self, binary, gdb_run, hint):
     executer = Executer(self.config)
     for path, _, files in os.walk(self.search_dir):
         for filename in files:
             if filename.endswith(self.config.run_extension):
                 continue
             filepath = os.path.join(path, filename)
             if gdb_run:
                 command = self.config.get_gdb_command_line(binary, filepath)
                 new_filename = filename+"-"+os.path.basename(binary)+hint+self.config.gdb_prefix
             else:
                 command = self.config.get_command_line(binary, filepath)
                 new_filename = filename+"-"+os.path.basename(binary)+hint
             Logger.debug("Looking for stdout/stderr output:", command, debug_level=4)
             if self.output_dir:
                 output_file_name = get_new_output_file_name(self.output_dir, new_filename, self.config.run_extension, self.config.max_digets)
                 new_filepath = os.path.join(self.output_dir, output_file_name)
             else:
                 output_file_name = get_new_output_file_name(path, new_filename, self.config.run_extension, self.config.max_digets)
                 new_filepath = os.path.join(path, output_file_name)
             fp = file(new_filepath, "w")
             executer.get_output_for_run(command, fp, env=self.config.env)
             fp.close()
Пример #5
0
 def _combined_stdout_stderr(self, binary, gdb_run, hint):
     executer = Executer(self.config)
     for path, _, files in os.walk(self.search_dir):
         for filename in files:
             if filename.endswith(self.config.run_extension):
                 continue
             filepath = os.path.join(path, filename)
             if gdb_run:
                 command = self.config.get_gdb_command_line(
                     binary, filepath)
                 new_filename = filename + "-" + os.path.basename(
                     binary) + hint + self.config.gdb_prefix
             else:
                 command = self.config.get_command_line(binary, filepath)
                 new_filename = filename + "-" + os.path.basename(
                     binary) + hint
             Logger.debug("Looking for stdout/stderr output:",
                          command,
                          debug_level=4)
             if self.output_dir:
                 output_file_name = get_new_output_file_name(
                     self.output_dir, new_filename,
                     self.config.run_extension, self.config.max_digets)
                 new_filepath = os.path.join(self.output_dir,
                                             output_file_name)
             else:
                 output_file_name = get_new_output_file_name(
                     path, new_filename, self.config.run_extension,
                     self.config.max_digets)
                 new_filepath = os.path.join(path, output_file_name)
             fp = file(new_filepath, "w")
             Logger.busy()
             executer.run_command(command,
                                  env=self.config.env,
                                  stdout=fp,
                                  stderr=fp)
             fp.close()
Пример #6
0
 def divide_by_signal(self, confirmation_loops, function=shutil.copyfile):
     ex = Executer(self.config)
     for path, _, files in os.walk(self.search_dir):
         for filename in files:
             if filename.endswith(self.config.run_extension):
                 continue
             filepath = os.path.join( path, filename )
             command = self.config.get_command_line(self.binary_to_use, filepath)
             Logger.debug("Executing:", command, debug_level=4)
             signal = ex.get_signal_for_run(command, env=self.config.env)
             while confirmation_loops > 0:
                 new_signal = ex.get_signal_for_run(command, env=self.config.env)
                 if new_signal == signal:
                     signal = new_signal
                     confirmation_loops -= 1
                 else:
                     Logger.info("Detected varying return codes for exactly the same run")
                     signal = SignalFinder.VARYING_SIGNAL
                     break
             Logger.debug("We consider signal %i for input file %s" % (signal, filename))
             destination_dir = self.get_folder_path_for_signal(signal)
             if not os.path.exists(destination_dir):
                 os.mkdir(destination_dir)
             function(filepath, os.path.join(destination_dir, filename))
 def __init__(self, config, search_dir=None, output_dir=None):
     self.config = config
     self.search_dir = search_dir
     if self.search_dir is None:
         self.search_dir = self.config.original_crashes_directory
     self.output_dir = output_dir
     if self.output_dir is None:
         self.output_dir = os.path.join(self.config.output_dir, "byte-changing-offsets")
     self.lucky_hex_values = "EEDDCCBB".decode("hex")
     #self.lucky_hex_values_upper_bound = hex(int(self.lucky_hex_values.encode("hex"),16)+0xFF)[2:].decode("hex")
     self.lucky_hex_values_upper_bound = "EEDDCDBB".decode("hex")
     self.gdb_script = """info registers eip"""
     self.gdb_script_path = self.config.prepare_gdb_script(self.gdb_script)
     self.regular_expr = re.compile("eip +(0x[0-9a-fA-F]{8})")
     self.executer = Executer(self.config)
class FeelingLuckyExploiter:
    """
    Simple idea:
    We replace a couple of bytes in the input file with something else
    and check if the crashing eip is changing.
    """
    def __init__(self, config, search_dir=None, output_dir=None):
        self.config = config
        self.search_dir = search_dir
        if self.search_dir is None:
            self.search_dir = self.config.original_crashes_directory
        self.output_dir = output_dir
        if self.output_dir is None:
            self.output_dir = os.path.join(self.config.output_dir, "byte-changing-offsets")
        self.lucky_hex_values = "EEDDCCBB".decode("hex")
        #self.lucky_hex_values_upper_bound = hex(int(self.lucky_hex_values.encode("hex"),16)+0xFF)[2:].decode("hex")
        self.lucky_hex_values_upper_bound = "EEDDCDBB".decode("hex")
        self.gdb_script = """info registers eip"""
        self.gdb_script_path = self.config.prepare_gdb_script(self.gdb_script)
        self.regular_expr = re.compile("eip +(0x[0-9a-fA-F]{8})")
        self.executer = Executer(self.config)
    
    def run_forest_run(self):
        if self.output_dir is not None and not os.path.exists(self.output_dir):
            os.mkdir(self.output_dir)
        new_file_path = os.path.join(self.config.tmp_dir, "feelingLucky.txt")
        cmd = self.config.get_gdb_command_line(self.config.get_most_standard_binary(), new_file_path, self.gdb_script_path)
        for path, _, files in os.walk(self.search_dir):
            for filename in files:
                eips = []
                indexes = []
                if filename.endswith(self.config.run_extension):
                    continue
                Logger.info("Trying my luck with", filename)
                filepath = os.path.join(path, filename)
                orig_file = file(filepath, "rb").read()
                Logger.debug(filepath, debug_level=4)
                for index in xrange(0,len(orig_file)-len(self.lucky_hex_values)):
                    new_file = orig_file[:index] + self.lucky_hex_values + orig_file[index+len(self.lucky_hex_values):]
                    #Logger.debug(new_file[:100])
                    file(new_file_path, "w").write(new_file)
                    crash_eip = self.get_crash_eip(cmd)
                    if crash_eip:
                        if not crash_eip in eips:
                            eips.append(crash_eip)
                            indexes.append(index)
                        if self.lucky_hex_values <= crash_eip and crash_eip <= self.lucky_hex_values_upper_bound:
                            o = os.path.join(self.output_dir, filename)
                            Logger.info("WTF, we actually were able to control EIP! See file ", o)
                            file(o, "w").write(new_file)
#                        else:
#                            Logger.debug("Binary crashed, but at eip:", hex(crash_eip), "index to put lucky hex value in file:", index, debug_level=7)
                Logger.info("Seen the following crashing eips for this file:", list_as_intervals(eips, as_hex=True))
                Logger.info("File indexes that lead to different crashes for this file:", list_as_intervals(indexes))
                
    
    def get_crash_eip(self, cmd):
        eip = None
        Logger.busy()
        gdb_output = self.executer.get_output_for_run(cmd, self.executer.pipe, self.config.run_timeout_tmin, env=self.config.env, stderr=self.executer.pipe)
        #Logger.debug("GDB output:", gdb_output)
        m = self.regular_expr.search(gdb_output)
        if m:
            eip = m.group(1)
            eip = int(eip, 16)
        #if not signal == SignalFinder.TIMEOUT_SIGNAL:
        #    Logger.error("Minimizing this file took too long, aborted")
        return eip
class FeelingLuckyExploiter:
    """
    Simple idea:
    We replace a couple of bytes in the input file with something else
    and check if the crashing eip is changing.
    """
    def __init__(self, config, search_dir=None, output_dir=None):
        self.config = config
        self.search_dir = search_dir
        if self.search_dir is None:
            self.search_dir = self.config.original_crashes_directory
        self.output_dir = output_dir
        if self.output_dir is None:
            self.output_dir = os.path.join(self.config.output_dir, "byte-changing-offsets")
        self.lucky_hex_values = "EEDDCCBB".decode("hex")
        #self.lucky_hex_values_upper_bound = hex(int(self.lucky_hex_values.encode("hex"),16)+0xFF)[2:].decode("hex")
        self.lucky_hex_values_upper_bound = "EEDDCDBB".decode("hex")
        self.gdb_script = """info registers eip"""
        self.gdb_script_path = self.config.prepare_gdb_script(self.gdb_script)
        self.regular_expr = re.compile("eip +(0x[0-9a-fA-F]{8})")
        self.executer = Executer(self.config)
    
    def run_forest_run(self):
        if self.output_dir is not None and not os.path.exists(self.output_dir):
            os.mkdir(self.output_dir)
        new_file_path = os.path.join(self.config.tmp_dir, "feelingLucky.txt")
        cmd = self.config.get_gdb_command_line(self.config.get_most_standard_binary(), new_file_path, self.gdb_script_path)
        for path, _, files in os.walk(self.search_dir):
            for filename in files:
                eips = []
                indexes = []
                if filename.endswith(self.config.run_extension):
                    continue
                Logger.info("Trying my luck with", filename)
                filepath = os.path.join(path, filename)
                orig_file = file(filepath, "rb").read()
                Logger.debug(filepath, debug_level=4)
                for index in xrange(0,len(orig_file)-len(self.lucky_hex_values)):
                    new_file = orig_file[:index] + self.lucky_hex_values + orig_file[index+len(self.lucky_hex_values):]
                    #Logger.debug(new_file[:100])
                    file(new_file_path, "w").write(new_file)
                    crash_eip = self.get_crash_eip(cmd)
                    if crash_eip:
                        if not crash_eip in eips:
                            eips.append(crash_eip)
                            indexes.append(index)
                        if self.lucky_hex_values <= crash_eip and crash_eip <= self.lucky_hex_values_upper_bound:
                            o = os.path.join(self.output_dir, filename)
                            Logger.info("WTF, we actually were able to control EIP! See file ", o)
                            file(o, "w").write(new_file)
#                        else:
#                            Logger.debug("Binary crashed, but at eip:", hex(crash_eip), "index to put lucky hex value in file:", index, debug_level=7)
                Logger.info("Seen the following crashing eips for this file:", list_as_intervals(eips, as_hex=True))
                Logger.info("File indexes that lead to different crashes for this file:", list_as_intervals(indexes))
                
    
    def get_crash_eip(self, cmd):
        eip = None
        Logger.busy()
        gdb_output = self.executer.run_command(cmd, env=self.config.env, stdout=self.executer.pipe, stderr=self.executer.pipe)
        #Logger.debug("GDB output:", gdb_output)
        m = self.regular_expr.search(gdb_output)
        if m:
            eip = m.group(1)
            eip = int(eip, 16)
        #if not signal == SignalFinder.TIMEOUT_SIGNAL:
        #    Logger.error("Minimizing this file took too long, aborted")
        return eip