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 test_simple(self): args = dict() args['ram_file'] = "/tmp/kafl_unittest_ram_file" args['overlay_dir'] = "/tmp/kafl_unittest_overlay_dir/" args['executable'] = "/tmp/kafl_unittest_exec_file" args['work_dir'] = "/tmp/kafl_unittest_work_dir/" args['mem'] = 300 args['ip_filter'] = (0x0000, 0xffff) FuzzerConfiguration(emulated_arguments=args) if not os.path.isdir(args['work_dir']): os.makedirs(args['work_dir']) prepare_working_dir(args['work_dir'], purge=True) seed = \ [ \ ["ABC", [chr(0), chr(1), chr(1)]], \ ["DEF", [chr(0), chr(1), chr(0)]] \ ] kt = KaflTree(seed, enable_graphviz=True) kt.draw() p = Popen("xdot /tmp/kafl_unittest_work_dir/graph.dot".split(" ")) time.sleep(2) for i in range(10): print(kt.get_next(100)) kt.draw() time.sleep(1) p.terminate() self.assertTrue(True)
def start(config): prepare_working_dir(config) if not post_self_check(config): return -1 # kAFL debug output is redirected to logs as part of -v mode. stdout will only print test/debug results. if config.argument_values['v']: enable_logging(config.argument_values["work_dir"]) # Without -ip0, Qemu will not active PT tracing and Redqueen will not # attempt to handle debug traps. This is a requirement for modes like gdb. if not config.argument_values['ip0']: print_warning("No trace region configured! Intel PT disabled!") max_execs = config.argument_values['n'] try: # TODO: noise, benchmark, trace are working, others untested mode = config.argument_values['action'] if (mode == "noise"): debug_non_det(config, max_execs) elif (mode == "benchmark"): benchmark(config) elif (mode == "gdb"): gdb_session(config, qemu_verbose=True) elif (mode == "single"): execute_once(config, max_execs) elif (mode == "trace"): debug_execution(config, max_execs) elif (mode == "trace-qemu"): debug_execution(config, max_execs, qemu_verbose=True) elif (mode == "printk"): debug_execution(config, 1, qemu_verbose=True, notifiers=False) elif (mode == "redqueen"): redqueen_dbg(config, qemu_verbose=False) elif (mode == "redqueen-qemu"): redqueen_dbg(config, qemu_verbose=True) elif (mode == "verify"): verify_dbg(config, qemu_verbose=True) else: print("Unknown debug mode. Exit") except Exception as e: raise finally: # cleanup #os.system("stty sane") 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 print( "\nDone. Check logs for details.\nAny remaining qemu instances should be GC'ed on exit:" ) os.system("pgrep qemu-system") return 0
def start(): config = FuzzerConfiguration() if not post_self_check(config): return -1 if config.argument_values['v']: enable_logging(config.argument_values["work_dir"]) num_processes = config.argument_values['p'] if not config.argument_values['Purge']: if ask_for_permission("PURGE", " to wipe old workspace:"): print_warning("Wiping old workspace...") time.sleep(2) else: print_fail("Aborting...") return 0 prepare_working_dir(config.argument_values['work_dir']) if not copy_seed_files(config.argument_values['work_dir'], config.argument_values['seed_dir']): print_fail("Seed directory is empty...") return 1 master = MasterProcess(config) slaves = [] for i in range(num_processes): print "fuzzing process {}".format(i) slaves.append( multiprocessing.Process(name='SLAVE' + str(i), target=slave_loader, args=(i, ))) slaves[i].start() try: master.loop() except KeyboardInterrupt: pass signal.signal(signal.SIGINT, signal.SIG_IGN) counter = 0 # print_pre_exit_msg(counter, clrscr=True) for slave in slaves: while True: counter += 1 # print_pre_exit_msg(counter) slave.join(timeout=0.25) if not slave.is_alive(): break # print_exit_msg() return 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 start(config): if not post_self_check(config): return -1 work_dir = config.argument_values["work_dir"] if config.argument_values['v'] or config.argument_values['debug']: enable_logging(work_dir) if not prepare_working_dir(config): print_fail("Refuse to operate on existing work directory. Use --purge to override.") return 1 # Load an interface json file. interface_manager.load(config.argument_values['interface']) # Start IRPT! qemu_sweep() proc = Process(config) try: proc.loop() except KeyboardInterrupt: print_note("Received Ctrl-C") finally: proc.database.save() proc.shutdown() os._exit(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 start(config): if not post_self_check(config): return -1 work_dir = config.argument_values["work_dir"] seed_dir = config.argument_values["seed_dir"] num_slaves = config.argument_values['p'] if config.argument_values['v']: enable_logging(work_dir) if not prepare_working_dir(config): print_fail( "Refuse to operate on existing work directory. Use --purge to override." ) return 1 if seed_dir and not copy_seed_files(work_dir, seed_dir): print_fail("Error when importing seeds. Exit.") return 1 # Without -ip0, Qemu will not active PT tracing and we turn into a blind fuzzer if not config.argument_values['ip0']: print_warning("No trace region configured! PT feedback disabled!") master = MasterProcess(config) slaves = [] for i in range(num_slaves): slaves.append( multiprocessing.Process(name="Slave " + str(i), target=slave_loader, args=(i, ))) slaves[i].start() try: master.loop() except KeyboardInterrupt: print_note("Received Ctrl-C, killing slaves...") except: print_fail("Exception in Master. Exiting..") print(traceback.format_exc()) finally: graceful_exit(slaves) time.sleep(0.2) qemu_sweep() sys.exit(0)
def start(config): if not post_self_check(config): return -1 work_dir = config.argument_values["work_dir"] seed_dir = config.argument_values["seed_dir"] num_slaves = config.argument_values['p'] if config.argument_values['v'] or config.argument_values['debug']: enable_logging(work_dir) if not prepare_working_dir(config): print_fail("Refuse to operate on existing work directory. Use --purge to override.") return 1 if seed_dir and not copy_seed_files(work_dir, seed_dir): print_fail("Error when importing seeds. Exit.") return 1 if config.argument_values['wdm']: interface_manager.load(config.argument_values['wdm']) master = MasterProcess(config) slaves = [] for i in range(num_slaves): slaves.append(multiprocessing.Process(name="Slave " + str(i), target=slave_loader, args=(i,))) slaves[i].start() try: master.loop() except KeyboardInterrupt: print_note("Received Ctrl-C, killing slaves...") except SystemExit as e: print_fail("Master exit: " + str(e)) finally: graceful_exit(slaves) time.sleep(0.2) qemu_sweep() sys.exit(0)
def main(): signal.signal(signal.SIGUSR1, handle_pdb) print(os.getpid()) time.sleep(1) config = FuzzerConfiguration() num_processes = config.argument_values['p'] num_concolic = config.argument_values['concolic'] reload = False if config.argument_values['Purge'] and check_if_old_state_exits( config.argument_values['work_dir']): print_warning("Old workspace found!") print_warning("Wiping old workspace...") prepare_working_dir(config.argument_values['work_dir'], purge=config.argument_values['Purge']) time.sleep(2) if not check_if_old_state_exits(config.argument_values['work_dir']): if not prepare_working_dir(config.argument_values['work_dir'], purge=config.argument_values['Purge']): print_fail("Working directory is weired or corrupted...") return 1 if not copy_seed_files(config.argument_values['work_dir'], config.argument_values['seed_dir']): print_fail("Seed directory is empty...") return 1 config.save_data() else: log_core("Old state exist -> loading...") config.load_data() reload = True DO_USE_UI = (USE_UI and not config.argument_values['verbose'] and config.argument_values['f']) comm = Communicator(num_processes=num_processes, concolic_thread=num_concolic) master = MasterProcess(comm, reload=reload) mapserver_process = multiprocessing.Process(name='MAPSERVER', target=mapserver_loader, args=(comm, reload)) modelserver_process = multiprocessing.Process(name='MODELSERVER', target=modelserver_loader, args=(comm, )) update_process = multiprocessing.Process(name='UPDATE', target=update_loader, args=(comm, DO_USE_UI)) slaves = [] for i in range(num_processes): slave = SlaveThread(comm, i, reload=reload) slaves.append(slave) concolic_models = [] for i in range(num_concolic): controller = ConcolicController(comm, num_processes, i) slaves.append(controller) concolic_models.append(controller.model) concserv = ConcolicServerThread(comm, num_processes, num_concolic, concolic_models) comm.start() comm.create_shm() update_process.start() time.sleep(.1) mapserver_process.start() modelserver_process.start() concserv.start() for slave in slaves: slave.start() # print('Starting master loop') try: master.loop() except KeyboardInterrupt: master.stop() print('Saving data') # Wait for child processes to properly exit mapserver_process.join() update_process.join() concserv.stop() # Properly stop threads for slave in slaves: slave.stop() time.sleep(1) # Stop communicator last because Queues may be in used comm.stop() master.save_data() print('Data saved')
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
def start(): config = FuzzerConfiguration() if not post_self_check(config): return -1 if config.argument_values['v']: enable_logging() num_processes = config.argument_values['p'] if config.argument_values['Purge'] and check_if_old_state_exits( config.argument_values['work_dir']): print_warning("Old workspace found!") if ask_for_permission("PURGE", " to wipe old workspace:"): print_warning("Wiping old workspace...") prepare_working_dir(config.argument_values['work_dir'], purge=True) time.sleep(2) else: print_fail("Aborting...") return 0 if not check_if_old_state_exits(config.argument_values['work_dir']): if not prepare_working_dir(config.argument_values['work_dir'], purge=True): print_fail("Working directory is weired or corrupted...") return 1 if not copy_seed_files(config.argument_values['work_dir'], config.argument_values['seed_dir']): print_fail("Seed directory is empty...") return 1 config.save_data() else: log_core("Old state exist -> loading...") config.load_data() comm = Communicator(num_processes=num_processes, tasks_per_requests=config.argument_values['t'], bitmap_size=config.config_values["BITMAP_SHM_SIZE"]) comm.create_shm() qlookup = QemuLookupSet() master = MasterProcess(comm) update_process = multiprocessing.Process(name='UPDATE', target=update_loader, args=(comm, )) mapserver_process = multiprocessing.Process(name='MAPSERVER', target=mapserver_loader, args=(comm, )) slaves = [] for i in range(num_processes): slaves.append( multiprocessing.Process(name='SLAVE' + str(i), target=slave_loader, args=(comm, i))) slaves[i].start() update_process.start() mapserver_process.start() try: master.loop() except KeyboardInterrupt: master.save_data() log_core("Date saved!") signal.signal(signal.SIGINT, signal.SIG_IGN) counter = 0 print_pre_exit_msg(counter, clrscr=True) for slave in slaves: while True: counter += 1 print_pre_exit_msg(counter) slave.join(timeout=0.25) if not slave.is_alive(): break print_exit_msg() return 0