def test_dictionary_options_file_with_nonexistent_dict(fs): """Test that ValueError is returned when options file's dict attribute contains a dict that is invalid / does not exist.""" fs.create_file('/fuzz-target.options', contents='[test]\ndict = not_exist.dict') with pytest.raises(ValueError): utils.get_dictionary_path('/fuzz-target')
def fuzz(input_corpus, output_corpus, target_binary): """Run fuzzer.""" # Seperate out corpus and crash directories as sub-directories of # |output_corpus| to avoid conflicts when corpus directory is reloaded. crashes_dir = os.path.join(output_corpus, 'crashes') output_corpus = os.path.join(output_corpus, 'corpus') os.makedirs(crashes_dir) os.makedirs(output_corpus) print('[fuzz] Running target with river') command = [ 'python3.6', '/river/repo/River3/concolic_GenerationalSearch2.py', '--binaryPath', target_binary, '--architecture', 'x64', '--maxLen', '10', '--logLevel', 'CRITICAL', '--secondsBetweenStats', '10', '--outputType', 'textual', '--input', input_corpus, '--output', output_corpus, '--crashdir', crashes_dir, ] dictionary_path = utils.get_dictionary_path(target_binary) if dictionary_path: command.extend(['--dict', dictionary_path]) print('[fuzz] Running command: ' + ' '.join(command))
def fuzz(input_corpus, output_corpus, target_binary): """Run fuzzer.""" # Seperate out corpus and crash directories as sub-directories of # |output_corpus| to avoid conflicts when corpus directory is reloaded. crashes_dir = os.path.join(output_corpus, 'crashes') output_corpus = os.path.join(output_corpus, 'corpus') os.makedirs(crashes_dir) os.makedirs(output_corpus) print('[fuzz] Running target with honggfuzz') command = [ './honggfuzz', '--persistent', '--rlimit_rss', '2048', '--sanitizers_del_report=true', '--input', input_corpus, '--output', output_corpus, # Store crashes along with corpus for bug based benchmarking. '--crashdir', crashes_dir, ] dictionary_path = utils.get_dictionary_path(target_binary) if dictionary_path: command.extend(['--dict', dictionary_path]) command.extend(['--', target_binary]) print('[fuzz] Running command: ' + ' '.join(command)) subprocess.check_call(command)
def fuzz(input_corpus, output_corpus, target_binary): """Run fuzzer.""" # Honggfuzz needs the output directory to exist. if not os.path.exists(output_corpus): os.makedirs(output_corpus) print('[run_fuzzer] Running target with honggfuzz') command = [ './honggfuzz', '--persistent', '--rlimit_rss', '2048', '--sanitizers_del_report=true', '--input', input_corpus, '--output', output_corpus, ] dictionary_path = utils.get_dictionary_path(target_binary) if dictionary_path: command.extend(['--dict', dictionary_path]) command.extend(['--', target_binary]) print('[run_fuzzer] Running command: ' + ' '.join(command)) subprocess.check_call(command)
def fuzz(input_corpus, output_corpus, target_binary): """Run fuzzer.""" os.environ['WEIZZ_NO_UI'] = '1' os.environ['WEIZZ_SKIP_CPUFREQ'] = '1' os.environ['WEIZZ_NO_AFFINITY'] = '1' os.environ['WEIZZ_I_DONT_CARE_ABOUT_MISSING_CRASHES'] = '1' os.environ['WEIZZ_CTX_SENSITIVE'] = '1' # Weizz needs at least one non-empty seed to start. utils.create_seed_file_for_empty_corpus(input_corpus) command = [ './weizz', '-d', # No deterministic mutation. '-w', # Enable smart mode, high-order mutate tagged inputs. '-h', # Stacking mode, alternate smart and AFL mutations. '-Q', # Qemu mode. '-L', # Size bounds to disable getdeps for a testcase. '8k', # Size bounds set to 8kb. '-m', # No memory limits 'none', '-i', input_corpus, '-o', output_corpus, ] dictionary_path = utils.get_dictionary_path(target_binary) if dictionary_path: command.extend(['-x', dictionary_path]) command.extend(['--', target_binary]) os.system('ulimit -s 16384') print('[weizz] Running command: ' + ' '.join(command)) subprocess.check_call(command)
def run_fuzzer(input_corpus, output_corpus, target_binary, extra_flags=None): """Run fuzzer.""" if extra_flags is None: extra_flags = [] flags = [ '-print_final_stats=1', # `close_fd_mask` to prevent too much logging output from the target. '-close_fd_mask=3', # Run in fork mode to allow ignoring ooms, timeouts, crashes and # continue fuzzing indefinitely. '-fork=1', '-ignore_ooms=1', '-ignore_timeouts=1', '-ignore_crashes=1', # Don't use LSAN's leak detection. Other fuzzers won't be using it and # using it will cause libFuzzer to find "crashes" no one cares about. '-detect_leaks=0', ] flags += extra_flags if 'ADDITIONAL_ARGS' in os.environ: flags += os.environ['ADDITIONAL_ARGS'].split(' ') dictionary_path = utils.get_dictionary_path(target_binary) if dictionary_path: flags.append('-dict=' + dictionary_path) command = [target_binary, output_corpus, input_corpus] + flags print('[run_fuzzer] Running command: ' + ' '.join(command)) subprocess.call(command)
def fuzz(input_corpus, output_corpus, target_binary): """Run fuzzer.""" prepare_fuzz_environment(input_corpus) dictionary_path = utils.get_dictionary_path(target_binary) command = [target_binary] if dictionary_path: command += (['-x', dictionary_path]) command += (['-o', output_corpus, '-i', input_corpus]) print(command) subprocess.check_call(command, cwd=os.environ['OUT'])
def run_afl_fuzz(input_corpus, output_corpus, target_binary, additional_flags=None, hide_output=False): """Run afl-fuzz.""" # Spawn the afl fuzzing process. print('[run_afl_fuzz] Running target with afl-fuzz') command = [ './afl-fuzz', '-r', '30', '-p', '1', '-u', '1', '-i', input_corpus, '-o', output_corpus, # Use no memory limit as ASAN doesn't play nicely with one. '-m', 'none', '-t', '1000+', # Use same default 1 sec timeout, but add '+' to skip hangs. ] # Use '-d' to skip deterministic mode, as long as it it compatible with # additional flags. if not additional_flags or check_skip_det_compatible(additional_flags): command.append('-d') if additional_flags: command.extend(additional_flags) dictionary_path = utils.get_dictionary_path(target_binary) if dictionary_path: command.extend(['-x', dictionary_path]) command += [ '--', target_binary, # Pass INT_MAX to afl the maximize the number of persistent loops it # performs. '2147483647' ] print('[run_afl_fuzz] Running command: ' + ' '.join(command)) output_stream = subprocess.DEVNULL if hide_output else None subprocess.check_call(command, stdout=output_stream, stderr=output_stream)
def run_fuzzer(input_corpus, output_corpus, target_binary, extra_flags=None): """Run fuzzer.""" if extra_flags is None: extra_flags = [] # Seperate out corpus and crash directories as sub-directories of # |output_corpus| to avoid conflicts when corpus directory is reloaded. crashes_dir = os.path.join(output_corpus, 'crashes') output_corpus = os.path.join(output_corpus, 'corpus') os.makedirs(crashes_dir) os.makedirs(output_corpus) flags = [ '-print_final_stats=1', # `close_fd_mask` to prevent too much logging output from the target. '-close_fd_mask=3', # Run in fork mode to allow ignoring ooms, timeouts, crashes and # continue fuzzing indefinitely. '-fork=4', '-NumCorpuses=8', '-ignore_ooms=1', '-ignore_timeouts=1', '-ignore_crashes=1', '-entropic=1', '-adaptive=6', # Don't use LSAN's leak detection. Other fuzzers won't be using it and # using it will cause libFuzzer to find "crashes" no one cares about. '-detect_leaks=0', # Store crashes along with corpus for bug based benchmarking. f'-artifact_prefix={crashes_dir}/', ] flags += extra_flags if 'ADDITIONAL_ARGS' in os.environ: flags += os.environ['ADDITIONAL_ARGS'].split(' ') dictionary_path = utils.get_dictionary_path(target_binary) if dictionary_path: flags.append('-dict=' + dictionary_path) command = [target_binary] + flags + [output_corpus, input_corpus] print('[run_fuzzer] Running command: ' + ' '.join(command)) subprocess.check_call(command)
def run_afl_fuzz(input_corpus, output_corpus, target_binary, additional_flags=None, hide_output=False): """Run afl-fuzz.""" # Spawn the afl fuzzing process. # FIXME: Currently AFL will exit if it encounters a crashing input in seed # corpus (usually timeouts). Add a way to skip/delete such inputs and # re-run AFL. print('[run_afl_fuzz] Running target with afl-fuzz') command = [ './afl-fuzz', '-i', input_corpus, '-o', output_corpus, # Use deterministic mode as it does best when we don't have # seeds which is often the case. '-d', # Use no memory limit as ASAN doesn't play nicely with one. '-m', 'none', '-t', '1000+', # Use same default 1 sec timeout, but add '+' to skip hangs. ] if additional_flags: command.extend(additional_flags) dictionary_path = utils.get_dictionary_path(target_binary) if dictionary_path: command.extend(['-x', dictionary_path]) command += [ '--', target_binary, # Pass INT_MAX to afl the maximize the number of persistent loops it # performs. '2147483647' ] print('[run_afl_fuzz] Running command: ' + ' '.join(command)) output_stream = subprocess.DEVNULL if hide_output else None subprocess.check_call(command, stdout=output_stream, stderr=output_stream)
def fuzz(input_corpus, output_corpus, target_binary): """Run fuzzer.""" # Seperate out corpus and crash directories as sub-directories of # |output_corpus| to avoid conflicts when corpus directory is reloaded. crashes_dir = os.path.join(output_corpus, 'crashes') output_corpus = os.path.join(output_corpus, 'corpus') os.makedirs(crashes_dir) os.makedirs(output_corpus) flags = [ '-print_final_stats=1', # `close_fd_mask` to prevent too much logging output from the target. '-close_fd_mask=3', # Run in fork mode to allow ignoring ooms, timeouts, crashes and # continue fuzzing indefinitely. '-fork=1', '-ignore_ooms=1', '-ignore_timeouts=1', '-ignore_crashes=1', # Don't use LSAN's leak detection. Other fuzzers won't be using it and # using it will cause libFuzzer to find "crashes" no one cares about. '-detect_leaks=0', # Store crashes along with corpus for bug based benchmarking. f'-artifact_prefix={crashes_dir}/', '-oracle=1' ] if 'ADDITIONAL_ARGS' in os.environ: flags += os.environ['ADDITIONAL_ARGS'].split(' ') dictionary_path = utils.get_dictionary_path(target_binary) if dictionary_path: flags.append('-dict=' + dictionary_path) command = [target_binary] + flags runner = __import__('pylibfuzzer.exec.runner', fromlist=['main']) runner.main('fuzzer.yml', command, seed_path=input_corpus)
def test_dictionary_options_file_with_no_dict(fs): """Test that None is returned when options file has not dict attribute.""" fs.create_file('/fuzz-target.options', contents='[test]') assert utils.get_dictionary_path('/fuzz-target') is None
def test_dictionary_bad_options_file(fs): """Test that Exception is returned when options file cannot be parsed.""" fs.create_file('/fuzz-target.options', contents=']') with pytest.raises(Exception): utils.get_dictionary_path('/fuzz-target')
def test_dictionary_dict_file(fs): """Test that target.dict file is returned when it exists.""" fs.create_file('/fuzz-target.dict', contents='A') assert utils.get_dictionary_path('/fuzz-target') == '/fuzz-target.dict'
def test_no_dictionary(fs): """Test that None is returned when no dictionary is found.""" assert utils.get_dictionary_path('/fuzz-target') is None
def test_dictionary_no_dictionaries(fs, environ): """Test that None is return when NO_DICTIONARIES is set.""" os.environ['NO_DICTIONARIES'] = 'True' fs.create_file('/fuzz-target.dict', contents='A') assert utils.get_dictionary_path('/fuzz-target') is None
def test_dictionary_options_file_with_dict(fs): """Test that dictionary path is returned when options file has a valid dict attribute.""" fs.create_file('/fuzz.dict', contents='A') fs.create_file('/fuzz-target.options', contents='[test]\ndict = fuzz.dict') assert utils.get_dictionary_path('/fuzz-target') == '/fuzz.dict'
def test_dictionary_skip(fs, environ): """Test that None is return when SKIP_DICT is set.""" os.environ['SKIP_DICT'] = '1' fs.create_file('/fuzz-target.dict', contents='A') assert utils.get_dictionary_path('/fuzz-target') is None
def test_dictionary_dict_file_with_env_var(fs): """Test that target.dict file is returned when it exists and |NO_DICTIONARIES| environment variable is set to False.""" os.environ['NO_DICTIONARIES'] = 'False' fs.create_file('/fuzz-target.dict', contents='A') assert utils.get_dictionary_path('/fuzz-target') == '/fuzz-target.dict'