Example #1
0
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
Example #2
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)
Example #3
0
File: core.py Project: vient/kAFL
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
Example #4
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
Example #5
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()
Example #6
0
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)
Example #7
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
Example #8
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)
Example #9
0
File: core.py Project: kirasys/kAFL
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)
Example #10
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')
Example #11
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
Example #12
0
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