def redqueen_dbg(config, qemu_verbose=False): global thread_done log_info("Starting...") q = qemu(1337, config, debug_mode=True) q.start(verbose=qemu_verbose) payload = open(config.argument_values["payload"][0]).read() q.set_payload(payload) if os.path.exists("patches"): shutil.copyfile("patches", "/tmp/redqueen_workdir_1337/redqueen_patches.txt") start = time.time() thread = Thread(target=lambda: redqueen_dbg_thread(q)) thread.start() result = q.execute_in_redqueen_mode(debug_mode=True) thread_done = True thread.join() requeen_print_state(q) end = time.time() if result: print(common.color.OKGREEN + "Execution succeded!" + common.color.ENDC) else: print(common.color.FLUSH_LINE + common.color.FAIL + "Execution failed!" + common.color.ENDC) print("Time: " + str(end - start) + "t/s") q.__del__() os.system("stty sane") return 0
def benchmark(config): log_debug("Starting benchmark...") payload_file = config.argument_values["input"] q = qemu(1337, config, debug_mode=False) q.start() q.set_payload(read_binary_file(payload_file)) log_debug("Hash: " + str(q.send_payload().hash())) try: while True: start = time.time() execs = 0 # for i in range(execs): while (time.time() - start < REFRESH): q.set_payload(read_binary_file(payload_file)) q.send_payload() execs += 1 end = time.time() # print("Performance: " + str(execs/(end - start)) + "t/s") stdout.write(common.color.FLUSH_LINE + "Performance: " + str(execs / (end - start)) + "t/s") stdout.flush() except KeyboardInterrupt: stdout.write("\n") q.shutdown() return 0
def __restart_vm(self): if self.comm.slave_termination.value: return False self.comm.reload_semaphore.acquire() try: #raise Exception("!") # QEMU is full of memory leaks...fixing it that way... if self.soft_reload_counter >= 32: self.soft_reload_counter = 0 raise Exception("Overstrop soft reload counter") self.q.soft_reload() self.soft_reload_counter += 1 except Exception as e: log_slave("Fail soft reload", self.slave_id) log_slave(str(e), self.slave_id) while True: self.q.__del__() self.q = qemu(self.slave_id, self.config) if self.q.start(): break else: time.sleep(0.5) log_slave("Fail Reload", self.slave_id) self.comm.reload_semaphore.release() self.q.set_tick_timeout_treshold(self.stage_tick_treshold * self.timeout_tick_factor) if self.comm.slave_termination.value: return False return True
def start(): config = InfoConfiguration() if not post_self_check(config): return -1 config.argument_values["work_dir"] = DEFAULT_INFO_WORKDIR if config.argument_values['v']: enable_logging(config.argument_values["work_dir"]) prepare_working_dir(config.argument_values['work_dir']) log_info("Dumping target addresses...") if os.path.exists("/tmp/kAFL_info.txt"): os.remove("/tmp/kAFL_info.txt") q = qemu(0, config) q.start() q.__del__() try: for line in open("/tmp/kAFL_info.txt"): print line, os.remove("/tmp/kAFL_info.txt") except: pass shutil.rmtree(DEFAULT_INFO_WORKDIR) return 0
def debug_execution(config, execs, qemu_verbose=False, notifiers=True): log_debug("Starting debug execution...(%d rounds)" % execs) payload_file = config.argument_values["input"] zero_hash = mmh3.hash(("\x00" * config.config_values['BITMAP_SHM_SIZE']), signed=False) q = qemu(1337, config, debug_mode=True, notifiers=notifiers) assert q.start(), "Failed to start Qemu?" start = time.time() for i in range(execs): log_debug("Launching payload %d/%d.." % (i + 1, execs)) if i % 3 == 0: q.set_payload(read_binary_file(payload_file)) # time.sleep(0.01 * rand.int(0, 9)) # a = str(q.send_payload()) # hexdump(a) result = q.send_payload() current_hash = result.hash() if zero_hash == current_hash: log_debug("Feedback Hash: " + str(current_hash) + common.color.WARNING + " (WARNING: Zero hash found!)" + common.color.ENDC) else: log_debug("Feedback Hash: " + str(current_hash)) #log_debug("Full hexdump:\n" + hexdump(result.copy_to_array())) if result.is_crash(): q.restart() q.shutdown() end = time.time() print("Performance: " + str(execs / (end - start)) + "t/s") return 0
def main(): cfg = FuzzerConfiguration(IRPT_CONFIG) payload = read_binary_file(cfg.argument_values['payload']) q = qemu(0, cfg, debug_mode=0) if not q.start(): return i = 0 while i < len(payload): iocode = u32(payload[i:i + 4]) inlength = u32(payload[i + 4:i + 8]) outlength = u32(payload[i + 8:i + 12]) inbuffer = str(payload[i + 12:i + 12 + (inlength & 0xFFFFFF)]) log("[+] IoControlCode(%x) InBufferLength(%d)" % (iocode, inlength)) exec_res = q.send_irp(IRP(iocode, inlength, outlength, inbuffer)) if exec_res.is_crash(): if not exec_res.is_timeout(): log("Crashed!!") else: log("Timeout!!") q.shutdown() return i = i + 12 + inlength q.shutdown()
def benchmark(config): log_info("Starting...") q = qemu(1337, config, debug_mode=False) q.start(verbose=False) q.set_payload(open(config.argument_values["payload"][0]).read()) print(q.send_payload().hash()) try: while True: start = time.time() execs = 0 # for i in range(execs): while (time.time() - start < REFRESH): q.set_payload( open(config.argument_values["payload"][0]).read()) q.send_payload() execs += 1 end = time.time() # print("Performance: " + str(execs/(end - start)) + "t/s") stdout.write(common.color.FLUSH_LINE + "Performance: " + str(execs / (end - start)) + "t/s") stdout.flush() except: print("\nExit") q.__del__() try: for i in range(512): if os.path.exists("/tmp/kAFL_printf.txt." + str(i)): os.remove("/tmp/kAFL_printf.txt." + str(i)) else: break except: pass return 0
def start(config): if not post_self_check(config): return -1 if config.argument_values['v']: enable_logging(config.argument_values["work_dir"]) log_info("Dumping target addresses...") # TODO: use proper temp file or store to $work_dir if os.path.exists("/tmp/kAFL_info.txt"): os.remove("/tmp/kAFL_info.txt") q = qemu(0, config) q.start() q.shutdown() try: with open("/tmp/kAFL_info.txt", 'r') as f: print(f.read()) os.remove("/tmp/kAFL_info.txt") except: pass return 0
def debug_execution(config, execs, qemu_verbose=False, notifiers=True): log_info("Starting...") zero_hash = mmh3.hash64(("\xFF" * config.config_values['BITMAP_SHM_SIZE'])) q = qemu(1337, config, debug_mode=True, notifiers=notifiers) q.start(verbose=qemu_verbose) q.set_payload(open(config.argument_values["payload"][0]).read()) start = time.time() for i in range(execs): print("+----------------------------------------------+") current_hash = mmh3.hash64(q.send_payload()) if zero_hash == current_hash: print("Hash: " + str(current_hash) + common.color.WARNING + " (WARNING: Zero hash found!)" + common.color.ENDC) else: print("Hash: " + str(current_hash)) end = time.time() print("Performance: " + str(execs / (end - start)) + "t/s") q.__del__() try: for i in range(512): if os.path.exists("/tmp/kAFL_printf.txt." + str(i)): os.remove("/tmp/kAFL_printf.txt." + str(i)) else: break except: pass os.system("stty sane") return 0
def __restart_vm(self): return True if self.comm.slave_termination.value: return False self.comm.reload_semaphore.acquire() try: if self.soft_reload_counter >= 32: self.soft_reload_counter = 0 raise Exception("...") self.q.soft_reload() self.soft_reload_counter += 1 except: log_slave("restart failed %s"%traceback.format_exc(), self.slave_id) while True: self.q.__del__() self.q = qemu(self.slave_id, self.config) if self.q.start(): break else: time.sleep(0.5) log_slave("Fail Reload", self.slave_id) self.comm.reload_semaphore.release() self.q.set_tick_timeout_treshold(self.stage_tick_treshold * self.timeout_tick_factor) if self.comm.slave_termination.value: return False return True
def __init__(self, slave_id, config, connection, auto_reload=False): self.config = config self.slave_id = slave_id self.q = qemu(self.slave_id, self.config) self.statistics = SlaveStatistics(self.slave_id, self.config) self.logic = FuzzingStateLogic(self, self.config) self.conn = connection self.bitmap_storage = BitmapStorage(self.config, self.config.config_values['BITMAP_SHM_SIZE'], "master")
def __restart_vm(self): while True: self.q.__del__() self.q = qemu(1337, self.config) if self.q.start(): break else: time.sleep(0.5) self.__log("Fail Reload")
def __init__(self, comm, slave_id, auto_reload=False): self.config = FuzzerConfiguration() self.comm = comm self.slave_id = slave_id self.counter = 0 self.q = qemu(self.slave_id, self.config) self.false_positiv_map = set() self.stage_tick_treshold = 0 self.timeout_tick_factor = self.config.config_values[ "TIMEOUT_TICK_FACTOR"] self.auto_reload = auto_reload self.soft_reload_counter = 0
def generate_traces_worker(config, pid, input_list): def sigterm_handler(signal, frame): if q: q.async_exit() sys.exit(0) # override config - workdir root should be tempdir! pname = mp.current_process().name config.argument_values['work_dir'] += "_%s" % pname config.argument_values['purge'] = True prepare_working_dir(config) work_dir = config.argument_values['work_dir'] trace_dir = config.argument_values["input"] + "/traces/" signal.signal(signal.SIGTERM, sigterm_handler) os.setpgrp() q = qemu(1337, config, debug_mode=False) if not q.start(): print_fail("%s: Could not start Qemu. Exit." % pname) return None pbar = tqdm(total=len(input_list), desc=pname, dynamic_ncols=True, smoothing=0.1, position=pid + 1) try: for input_path in input_list: trace_file = trace_dir + os.path.basename(input_path) + ".lz4" if os.path.exists(trace_file): #printf("Skipping %s.." % os.path.basename(input_path)) pbar.update() continue #print("Processing %s.." % os.path.basename(input_path)) if funky_trace_run(q, input_path): with open( work_dir + "/redqueen_workdir_1337/pt_trace_results.txt", 'rb') as f_in: with lz4.LZ4FrameFile(trace_file, 'wb', compression_level=lz4. COMPRESSIONLEVEL_MINHC) as f_out: shutil.copyfileobj(f_in, f_out) pbar.update() except: q.async_exit() raise q.shutdown()
def __init__(self, comm, slave_id, auto_reload=False): self.config = FuzzerConfiguration() self.redqueen_state = RedqueenState() #globally shared redqueen state self.comm = comm self.slave_id = slave_id self.counter = 0 self.q = qemu(self.slave_id, self.config) self.false_positiv_map = set() self.stage_tick_treshold = 0 self.timeout_tick_factor = self.config.config_values["TIMEOUT_TICK_FACTOR"] self.auto_reload = auto_reload self.soft_reload_counter = 0 configure_log_prefix("%.2d"%slave_id)
def gdb_session(config, qemu_verbose=True, notifiers=True): import common.qemu_protocol as qemu_protocol payload_file = config.argument_values["input"] config.argument_values["gdbserver"] = True q = qemu(1337, config, notifiers=notifiers) print("Starting Qemu + GDB with payload %s" % payload_file) print("Connect with gdb to release guest from reset (localhost:1234)") if q.start(): q.set_payload(read_binary_file(payload_file)) result = q.debug_payload(apply_patches=False) print("Payload result: %s. Thank you for playing.." % qemu_protocol.CMDS[result]) q.shutdown()
def __init__(self, slave_id, config, connection, auto_reload=False): self.config = config self.slave_id = slave_id self.q = qemu(self.slave_id, self.config) self.q.start(verbose=False) print "started qemu" self.statistics = SlaveStatistics(self.slave_id, self.config) self.logic = FuzzingStateLogic(self, self.config) self.conn = connection self.bitmap_storage = BitmapStorage( self.config, self.config.config_values['BITMAP_SHM_SIZE'], "master") configure_log_prefix("%.2d" % slave_id)
def __init__(self, config, pid=0): self.config = config self.debug_mode = config.argument_values['debug'] self.statistics = ProcessStatistics(self.config) self.bitmap_storage = BitmapStorage(config, config.config_values['BITMAP_SHM_SIZE'], "process", read_only=False) log_process("Starting (pid: %d)" % os.getpid()) log_process("Configuration dump:\n%s" % pformat(config.argument_values, indent=4, compact=True)) self.q = qemu(pid, self.config, debug_mode=self.debug_mode) self.optimizer = Optimizer(self.q, self.statistics) self.reproducer = Reproducer(self.q, self.statistics) self.database = Database(self.statistics) # load interface
def redqueen_cov(config, qemu_verbose=False): import json global thread_done log_info("Starting...") q = qemu(1337, config, debug_mode=True) q.start(verbose=qemu_verbose) known_lines = set() for input in config.argument_values["payload"]: name = os.path.basename(input) output = "trace_" + name + ".rqse" print((input, "=>", output)) with open(output, "w") as f: print(common.color.OKGREEN + "Running: %s" % input + common.color.ENDC) q.set_payload(open(input).read()) start = time.time() result = q.execute_in_redqueen_mode(se_mode=False, debug_mode=True, trace_only=True) end = time.time() if result: print(common.color.OKGREEN + "Execution succeded!" + common.color.ENDC) else: print(common.color.FLUSH_LINE + common.color.FAIL + "Execution failed!" + common.color.ENDC) print("Time: " + str(end - start) + "t/s") requeen_print_state(q) f.write(json.dumps({"input_path": input}) + "\n") with open(q.redqueen_workdir.pt_trace(), "r") as trace: for line in trace.readlines(): if not line in known_lines: print line known_lines.add(line) f.write(line) os.system("killall -9 qemu-system-x86_64") os.system("killall -9 python") print("kill qemu") q.__del__() print("fix tty") os.system("stty sane") return 0
def redqueen_dbg(config, qemu_verbose=False): global thread_done log_debug("Starting Redqueen debug...") q = qemu(1337, config, debug_mode=True) q.start() payload = read_binary_file(config.argument_values["input"]) # q.set_payload(payload) if os.path.exists("patches"): shutil.copyfile("patches", "/tmp/redqueen_workdir_1337/redqueen_patches.txt") start = time.time() thread = Thread(target=lambda: redqueen_dbg_thread(q)) thread.start() result = q.execute_in_redqueen_mode(payload, debug_mode=True) thread_done = True thread.join() requeen_print_state(q) end = time.time() if result: print(common.color.OKGREEN + "Execution succeded!" + common.color.ENDC) else: print(common.color.FLUSH_LINE + common.color.FAIL + "Execution failed!" + common.color.ENDC) print("Time: " + str(end - start) + "t/s") num_muts, muts = parser.parse_rq_data( open( "/tmp/kafl_debug_workdir/redqueen_workdir_1337/redqueen_results.txt" ).read(), payload) count = 0 for offset in muts: for lhs in muts[offset]: for rhs in muts[offset][lhs]: count += 1 print(offset, lhs, rhs) print(count) return 0
def start(): config = DebugConfiguration() prepare_working_dir(config.argument_values['work_dir']) if not post_self_check(config): return -1 if config.argument_values['v']: enable_logging(config.argument_values["work_dir"]) if not config.argument_values['ip0']: print(common.color.WARNING + "[WARNING]\tNo trace region configured!" + common.color.ENDC) if (config.argument_values['debug_mode'] == "noise"): debug_non_det(config, open(config.argument_values["payload"][0]).read()) if (config.argument_values['debug_mode'] == "noise-multiple"): q = qemu(1337, config, debug_mode=False) q.start(verbose=False) for e in config.argument_values["payload"]: print("FILE: " + e) debug_non_det(config, open(e).read(), max_iterations=20, q=q) elif (config.argument_values['debug_mode'] == "benchmark"): benchmark(config) elif (config.argument_values['debug_mode'] == "trace"): debug_execution(config, config.argument_values['i']) elif (config.argument_values['debug_mode'] == "trace-qemu"): debug_execution(config, config.argument_values['i'], qemu_verbose=True) elif (config.argument_values['debug_mode'] == "printk"): debug_execution(config, 1, qemu_verbose=True, notifiers=False) elif (config.argument_values['debug_mode'] == "redqueen"): redqueen_dbg(config, qemu_verbose=False) elif (config.argument_values['debug_mode'] == "redqueen-qemu"): redqueen_dbg(config, qemu_verbose=True) elif (config.argument_values['debug_mode'] == "cov"): redqueen_cov(config, qemu_verbose=True) elif (config.argument_values['debug_mode'] == "verify"): verify_dbg(config, qemu_verbose=True) return 0
def main(): cfg = FuzzerConfiguration(IRPT_CONFIG) q = qemu(0, cfg, debug_mode=0) if not q.start(): return interface_manager.load(cfg.argument_values['interface']) iocode_list = list(interface_manager.get_all_codes()) exec_res = q.send_irp(IRP(iocode_list[0], 0, 0)) for iocode in iocode_list[1:]: q.reload_driver() exec_res2 = q.send_irp(IRP(iocode, 0, 0)) if exec_res.copy_to_array() != exec_res2.copy_to_array(): print("IoControlCode(%x) == IoControlCode(%x)" % (iocode_list[0], iocode)) else: print("IoControlCode(%x) != IoControlCode(%x)" % (iocode_list[0], iocode)) q.shutdown()
def start(): config = InfoConfiguration() if not post_self_check(config): return -1 if config.argument_values['v']: enable_logging() log_info("Dumping target addresses...") if os.path.exists("/tmp/kAFL_info.txt"): os.remove("/tmp/kAFL_info.txt") q = qemu(0, config) q.start() q.__del__() try: for line in open("/tmp/kAFL_info.txt"): print line, os.remove("/tmp/kAFL_info.txt") except: pass return 0
def execute_once(config, qemu_verbose=False, notifiers=True): payload_file = config.argument_values["input"] log_debug("Execute payload %s.. " % payload_file) zero_hash = mmh3.hash(("\x00" * config.config_values['BITMAP_SHM_SIZE']), signed=False) q = qemu(1337, config, debug_mode=False, notifiers=notifiers) assert q.start(), "Failed to start Qemu?" q.set_payload(read_binary_file(payload_file)) result = q.send_payload() current_hash = result.hash() if zero_hash == current_hash: log_debug("Feedback Hash: " + str(current_hash) + common.color.WARNING + " (WARNING: Zero hash found!)" + common.color.ENDC) else: log_debug("Feedback Hash: " + str(current_hash)) q.shutdown() return 0
def debug_non_det(config, payload, max_iterations=0, q=None): log_info("Starting...") # Define IP Range!! if q is None: q = qemu(1337, config, debug_mode=False) q.start(verbose=False) hash_value = None default_hash = None hash_list = [] try: q.set_payload(payload) bitmap = q.send_payload() # bitmap = q.send_payload() default_hash = bitmap.hash() hash_list.append(default_hash) # q.set_payload(open(config.argument_values["payload"]).read()) # bitmap = q.send_payload() print("Default Hash: " + str(default_hash)) total = 1 hash_mismatch = 0 count = 0 while True: mismatch_r = 0 start = time.time() # for i in range(execs): execs = 0 while (time.time() - start < REFRESH): # time.sleep(0.00001 * randint(0, 9)) # q.set_payload(open(config.argument_values["payload"]).read()) q.set_payload(payload) bitmap = q.send_payload() hash_value = bitmap.hash() if hash_value != default_hash: mismatch_r += 1 if hash_value not in hash_list: hash_list.append(hash_value) # print(common.color.FAIL + "[WARNING]: hash mismatch" + common.color.ENDC) execs += 1 end = time.time() total += execs hash_mismatch += mismatch_r # print("Performance: " + str(format(((execs*0.1)/(end - start)), '.4f')) + " t/s\tTotal: " + str(total) + "\tMismatch: " + common.color.FAIL + str(hash_mismatch) + common.color.ENDC + " (+" + str(mismatch_r) + ")\tRatio: " + str(format(((hash_mismatch*1.0)/total)*100.00, '.4f')) + "%") stdout.write(common.color.FLUSH_LINE + "Performance: " + str(format(((execs * 1.0) / (end - start)), '.4f')) + " t/s\tTotal: " + str(total) + "\tMismatch: ") if (len(hash_list) != 1): stdout.write( common.color.FAIL + str(hash_mismatch) + common.color.ENDC + " (+" + str(mismatch_r) + ")\tRatio: " + str(format(( (hash_mismatch * 1.0) / total) * 100.00, '.4f')) + "%") stdout.write("\t\tHashes:\t" + str(len(hash_list)) + " (" + str( format(((len(hash_list) * 1.0) / total) * 100.00, '.4f')) + "%)") else: stdout.write( common.color.OKGREEN + str(hash_mismatch) + common.color.ENDC + " (+" + str(mismatch_r) + ")\tRatio: " + str(format(( (hash_mismatch * 1.0) / total) * 100.00, '.4f')) + "%") stdout.flush() if max_iterations != 0 and total >= count: break count += 1 except Exception as e: pass # if max_iterations == 0: # print("\nExit + (" + str(e) + ")") # print('Error on line {}'.format(sys.exc_info()[-1].tb_lineno), type(e).__name__, e) if max_iterations != 0: print("") for e in hash_list: print(e) if max_iterations != 0: print("") # q.__del__() try: for i in range(512): if os.path.exists("/tmp/kAFL_printf.txt." + str(i)): os.remove("/tmp/kAFL_printf.txt." + str(i)) else: break except: pass return 0
def redqueen_cov(config, qemu_verbose=False): global thread_done log_info("Starting...") q = qemu(1337, config, debug_mode=True) q.start(verbose=qemu_verbose) known_lines = set() trace_parser = TraceParser(config) inputs, input_to_timestamp = parse_input_cov_list( config.argument_values["payload"]) for input_path in inputs: name = os.path.basename(input_path) print(common.color.OKGREEN + "Running: %s" % input_path + common.color.ENDC) q.set_payload(open(input_path).read()) start = time.time() result = q.execute_in_trace_mode(debug_mode=True, timeout_detection=False) end = time.time() if result: print(common.color.OKGREEN + "Execution succeded!" + common.color.ENDC) else: print(common.color.FLUSH_LINE + common.color.FAIL + "Execution failed!" + common.color.ENDC) print("Time: " + str(end - start) + "t/s") trace_parser.parse_and_add_trace( input_path, "/tmp/kafl_debug_workdir/redqueen_workdir_1337/pt_trace_results.txt" ) input_to_new_bbs = trace_parser.input_to_new_targets if all([ input_to_timestamp.get(input_path) is not None for input_path in inputs ]): plot_bb(inputs, input_to_timestamp, input_to_new_bbs) else: for input in sorted(list(input_to_new_bbs)): safe_print("%s: %s" % (input, repr(map(hex, input_to_new_bbs[input])))) count = 0 for _, bbs in input_to_new_bbs.items(): count += len(bbs) print("total: %d" % count) print("kill qemu") os.system("killall -9 qemu-system-x86_64") q.__del__() print("fix tty") os.system("stty sane") print("kill python") os.system("killall -9 python") return 0
def debug_non_det(config, payload, max_iterations=0): log_debug("Starting non-deterministic...") # Define IP Range!! q = qemu(1337, config, debug_mode=False) q.start() hash_value = None default_hash = None hash_list = [] try: q.set_payload(payload) time.sleep(0.2) bitmap = q.send_payload() default_hash = bitmap.hash() hash_list.append(default_hash) log_debug("Default Hash: " + str(default_hash)) total = 1 hash_mismatch = 0 count = 0 while True: mismatch_r = 0 start = time.time() execs = 0 while (time.time() - start < REFRESH): #time.sleep(0.0002 * rand.int(10)) q.set_payload(payload) #time.sleep(0.3) bitmap = q.send_payload() if execution_exited_abnormally(q): print("Crashed - restarting...") q.restart() hash_value = bitmap.hash() if hash_value != default_hash: mismatch_r += 1 if hash_value not in hash_list: hash_list.append(hash_value) log_debug( "Full hexdump for %x:\n%s\n" % (hash_value, hexdump(bitmap.copy_to_array()))) execs += 1 end = time.time() total += execs hash_mismatch += mismatch_r stdout.write(common.color.FLUSH_LINE + "Performance: " + str(format(((execs * 1.0) / (end - start)), '.0f')) + " t/s\tTotal: " + str(total) + "\tMismatch: ") if (len(hash_list) != 1): stdout.write( common.color.FAIL + str(hash_mismatch) + common.color.ENDC + " (+" + str(mismatch_r) + ")\tRatio: " + str(format(( (hash_mismatch * 1.0) / total) * 100.00, '.2f')) + "%") stdout.write("\t\tHashes:\t" + str(len(hash_list)) + " (" + str( format(((len(hash_list) * 1.0) / total) * 100.00, '.2f')) + "%)") else: stdout.write( common.color.OKGREEN + str(hash_mismatch) + common.color.ENDC + " (+" + str(mismatch_r) + ")\tRatio: " + str(format(( (hash_mismatch * 1.0) / total) * 100.00, '.2f')) + "%") stdout.flush() if max_iterations != 0 and total >= count: break count += 1 except Exception as e: raise except KeyboardInterrupt: stdout.write("\n") finally: q.shutdown() for h in hash_list: print("%x" % h) return 0
def verify_dbg(config, qemu_verbose=False): global thread_done print("Starting...") rq_state = RedqueenState() workdir = RedqueenWorkdir(1337) if os.path.exists("patches"): with open("patches", "r") as f: for x in f.readlines(): rq_state.add_candidate_hash_addr(int(x, 16)) if not rq_state.get_candidate_hash_addrs(): print("WARNING: no patches configured\n") print("Maybe add ./patches with addresses to patch\n") else: print("OK: got patches %s\n", rq_state.get_candidate_hash_addrs()) q = qemu(1337, config, debug_mode=True) print("using qemu command:\n%s\n" % q.cmd) q.start() orig_input = read_binary_file(config.argument_values["input"]) q.set_payload(orig_input) # result = q.send_payload() with open(q.redqueen_workdir.whitelist(), "w") as w: with open(q.redqueen_workdir.patches(), "w") as p: for addr in rq_state.get_candidate_hash_addrs(): addr = hex(addr).rstrip("L").lstrip("0x") + "\n" w.write(addr) p.write(addr) print("RUN WITH PATCHING:") bmp1 = q.send_payload(apply_patches=True) print("\nNOT PATCHING:") bmp2 = q.send_payload(apply_patches=False) if bmp1 == bmp2: print( "WARNING: patches don't seem to change anything, are checksums present?" ) else: print("OK: bitmaps are distinct") q.soft_reload() hash = HashFixer(q, rq_state) print("fixing hashes\n") fixed_payload = hash.try_fix_data(orig_input) if fixed_payload: print("%s\n", repr("".join(map(chr, fixed_payload)))) q.set_payload(fixed_payload) bmp3 = q.send_payload(apply_patches=False) if bmp1 == bmp3: print("CONGRATZ, BITMAPS ARE THE SAME, all cmps fixed\n") else: print("Warning, after fixing cmps, bitmaps differ\n") else: print("couldn't fix payload\n") start = time.time() return 0
def debug_non_det(config, max_execs=0): log_debug("Starting non-deterministic...") delay = 0 payload_file = config.argument_values["input"] assert os.path.isfile( payload_file), "Provided -input argument must be a file." assert "ip0" in config.argument_values, "Must set -ip0 range in order to obtain PT traces." payload = read_binary_file(payload_file) q = qemu(1337, config, debug_mode=False) assert q.start(), "Failed to launch Qemu." store_traces = config.argument_values["trace"] if store_traces: trace_out = config.argument_values[ "work_dir"] + "/redqueen_workdir_1337/pt_trace_results.txt" trace_dir = config.argument_values["work_dir"] + "/noise/" os.makedirs(trace_dir) hash_value = None default_hash = None hashes = dict() try: q.set_payload(payload) time.sleep(delay) if store_traces: q.send_enable_trace() exec_res = q.send_payload() if store_traces: q.send_disable_trace() default_hash = exec_res.hash() hashes[default_hash] = 1 log_debug("Default Hash: " + str(default_hash)) if store_traces: shutil.copyfile(trace_out, trace_dir + "/trace_%08x.txt" % default_hash) total = 1 hash_mismatch = 0 time.sleep(delay) while max_execs == 0 or total <= max_execs: mismatch_r = 0 start = time.time() execs = 0 while (time.time() - start < REFRESH): #time.sleep(0.0002 * rand.int(10)) q.set_payload(payload) time.sleep(delay) if store_traces: q.send_enable_trace() exec_res = q.send_payload() if store_traces: q.send_disable_trace() if exec_res.is_crash(): print("Crashed - restarting...") q.restart() time.sleep(delay) hash_value = exec_res.hash() if hash_value != default_hash: mismatch_r += 1 if hash_value in hashes: hashes[hash_value] = hashes[hash_value] + 1 else: hashes[hash_value] = 1 if store_traces: shutil.copyfile( trace_out, trace_dir + "/trace_%08x.txt" % hash_value) execs += 1 end = time.time() total += execs hash_mismatch += mismatch_r stdout.write(common.color.FLUSH_LINE + "Performance: " + str(format(((execs * 1.0) / (end - start)), '.0f')) + " t/s\tTotal: " + str(total) + "\tMismatch: ") if (len(hashes) != 1): stdout.write( common.color.FAIL + str(hash_mismatch) + common.color.ENDC + " (+" + str(mismatch_r) + ")\tRatio: " + str(format(( (hash_mismatch * 1.0) / total) * 100.00, '.2f')) + "%") stdout.write("\t\tHashes:\t" + str(len(hashes.keys())) + " (" + str( format(((len(hashes.keys()) * 1.0) / total) * 100.00, '.2f')) + "%)") else: stdout.write( common.color.OKGREEN + str(hash_mismatch) + common.color.ENDC + " (+" + str(mismatch_r) + ")\tRatio: " + str(format(( (hash_mismatch * 1.0) / total) * 100.00, '.2f')) + "%") stdout.flush() except Exception as e: raise except KeyboardInterrupt: pass finally: q.shutdown() stdout.write("\n") for h in hashes.keys(): if h == default_hash: print("* %08x: %03d" % (h, hashes[h])) else: print(" %08x: %03d" % (h, hashes[h])) return 0
def generate_traces(config, input_list): work_dir = config.argument_values['work_dir'] data_dir = config.argument_values["input"] trace_dir = data_dir + "/traces/" if data_dir == work_dir: print_note("Workdir must be separate from input/data dir. Aborting.") return None prepare_working_dir(config) if os.path.exists(trace_dir): print_note( "Input data_dir already has a traces/ subdir. Skipping trace generation..\n" ) return trace_dir # real deal. delete trace dir if it exists and (re-)create traces shutil.rmtree(trace_dir, ignore_errors=True) os.makedirs(trace_dir) # TODO What is the effect of not defining a trace region? will it trace? if not config.argument_values['ip0']: print_warning("No trace region configured!") if os.path.exists(work_dir + "redqueen_workdir_1337"): print_fail( "Leftover files from 1337 instance. This should not happen.") return None q = qemu(1337, config, debug_mode=False) if not q.start(): print_fail("Could not start Qemu. Exit.") return None start = time.time() try: for input_path, nid, timestamp in input_list: print("Processing: %s" % input_path) q.set_payload(read_binary_file(input_path)) exec_res = q.execute_in_trace_mode(timeout_detection=False) if not exec_res: print_note("Failed to execute input %s. Continuing anyway..." % input_path) assert (q.restart()) continue # TODO: reboot by default, persistent by option if exec_res.is_crash(): q.reload() with open(work_dir + "/redqueen_workdir_1337/pt_trace_results.txt", 'rb') as f_in: with lz4.LZ4FrameFile( trace_dir + os.path.basename(input_path) + ".lz4", 'wb', compression_level=lz4.COMPRESSIONLEVEL_MINHC) as f_out: shutil.copyfileobj(f_in, f_out) except: raise finally: q.async_exit() end = time.time() print("Time taken: %.2fs" % (end - start)) return trace_dir