예제 #1
0
def main(argv):
    show_info()

    parser = argparse.ArgumentParser(description="afl-vcrash verifies that afl-fuzz crash samples lead to crashes in \
the target binary.", usage="afl-vcrash [-f LIST_FILENAME] [-h] [-j THREADS] [-q] [-r] [-t TIMEOUT] collection_dir -- target_command")

    parser.add_argument("collection_dir",
                        help="Directory holding all crash samples that will be verified.")
    parser.add_argument("target_cmd", nargs="+", help="Target binary including command line \
options. Use '@@' to specify crash sample input file position (see afl-fuzz usage).")
    parser.add_argument("-f", "--filelist", dest="list_filename", default=None,
                        help="Writes all crash sample file names that do not lead to crashes into a file.")
    parser.add_argument("-j", "--threads", dest="num_threads", default=1,
                        help="Enable parallel verification by specifying the number of threads afl-vcrash \
will utilize.")
    parser.add_argument("-q", "--quiet", dest="quiet", action="store_const", const=True, default=False,
                        help="Suppress output of crash sample file names that do not lead to crashes. This is \
particularly useful when combined with '-r' or '-f'.")
    parser.add_argument("-r", "--remove", dest="remove", action="store_const", const=True, default=False,
                        help="Remove crash samples that do not lead to crashes.")
    parser.add_argument("-t", "--timeout", dest="timeout_secs", default=60,
                        help="Define the timeout in seconds before killing the verification of a crash sample")

    args = parser.parse_args(argv[1:])

    input_dir = os.path.abspath(os.path.expanduser(args.collection_dir))
    if not os.path.exists(input_dir):
        print_err("No valid directory provided for <collection_dir>!")
        return

    num_crashes, crash_samples = afl_collect.get_samples_from_dir(input_dir, True)

    print_ok("Verifying %d crash samples..." % num_crashes)

    args.target_cmd = " ".join(args.target_cmd).split()
    args.target_cmd[0] = os.path.abspath(os.path.expanduser(args.target_cmd[0]))
    if not os.path.exists(args.target_cmd[0]):
        print_err("Target binary not found!")
        return
    args.target_cmd = " ".join(args.target_cmd)

    invalid_samples, timeout_samples = verify_samples(int(args.num_threads), crash_samples, args.target_cmd, int(args.timeout_secs))

    print_warn("Found %d invalid crash samples." % len(invalid_samples))
    print_warn("%d samples caused a timeout." % len(timeout_samples))

    if args.remove:
        print_ok("Removing invalid crash samples.")
        remove_samples(invalid_samples, args.quiet)
        print_ok("Removing timeouts.")
        remove_samples(timeout_samples, args.quiet)
    elif not args.quiet:
        for ci in invalid_samples:
            print(ci)

    # generate filelist of collected crash samples
    if args.list_filename:
        afl_collect.generate_sample_list(args.list_filename, invalid_samples + timeout_samples)
        print_ok("Generated invalid crash sample list '%s'." % args.list_filename)
예제 #2
0
def main(argv):
    show_info()

    parser = argparse.ArgumentParser(description="afl-vcrash verifies that afl-fuzz crash samples lead to crashes in \
the target binary.", usage="afl-vcrash [-f LIST_FILENAME] [-h] [-j THREADS] [-q] [-r] [-t TIMEOUT] collection_dir -- target_command")

    parser.add_argument("collection_dir",
                        help="Directory holding all crash samples that will be verified.")
    parser.add_argument("target_cmd", nargs="+", help="Target binary including command line \
options. Use '@@' to specify crash sample input file position (see afl-fuzz usage).")
    parser.add_argument("-f", "--filelist", dest="list_filename", default=None,
                        help="Writes all crash sample file names that do not lead to crashes into a file.")
    parser.add_argument("-j", "--threads", dest="num_threads", default=1,
                        help="Enable parallel verification by specifying the number of threads afl-vcrash \
will utilize.")
    parser.add_argument("-q", "--quiet", dest="quiet", action="store_const", const=True, default=False,
                        help="Suppress output of crash sample file names that do not lead to crashes. This is \
particularly useful when combined with '-r' or '-f'.")
    parser.add_argument("-r", "--remove", dest="remove", action="store_const", const=True, default=False,
                        help="Remove crash samples that do not lead to crashes.")
    parser.add_argument("-t", "--timeout", dest="timeout_secs", default=60,
                        help="Define the timeout in seconds before killing the verification of a crash sample")

    args = parser.parse_args(argv[1:])

    input_dir = os.path.abspath(os.path.expanduser(args.collection_dir))
    if not os.path.exists(input_dir):
        print_err("No valid directory provided for <collection_dir>!")
        sys.exit(1)

    num_crashes, crash_samples = afl_collect.get_samples_from_dir(input_dir, True)

    print_ok("Verifying %d crash samples..." % num_crashes)

    args.target_cmd = build_target_cmd(args.target_cmd)

    os.environ["ASAN_OPTIONS"] = "abort_on_error=1:detect_leaks=0:symbolize=1:allocator_may_return_null=1"
    os.environ["ASAN_SYMBOLIZER_PATH"] = "/usr/lib/llvm-3.8/bin/llvm-symbolizer"

    invalid_samples, timeout_samples = verify_samples(int(args.num_threads), crash_samples, args.target_cmd, int(args.timeout_secs))

    print_warn("Found %d invalid crash samples." % len(invalid_samples))
    print_warn("%d samples caused a timeout." % len(timeout_samples))

    if args.remove:
        print_ok("Removing invalid crash samples.")
        remove_samples(invalid_samples, args.quiet)
        print_ok("Removing timeouts.")
        remove_samples(timeout_samples, args.quiet)
    elif not args.quiet:
        for ci in invalid_samples:
            print(ci)

    # generate filelist of collected crash samples
    if args.list_filename:
        afl_collect.generate_sample_list(args.list_filename, invalid_samples + timeout_samples)
        print_ok("Generated invalid crash sample list '%s'." % args.list_filename)
예제 #3
0
    def test_generate_sample_list(self):
        list_name = 'testdata/read_only'
        files_collected = ['dummy0', 'dummy1', 'dummy2']
        self.assertFalse(os.path.exists('testdata/read_only'))
        self.assertIsNone(
            afl_collect.generate_sample_list(list_name, files_collected))
        self.assertTrue(os.path.exists('testdata/read_only'))

        self.assertIsNone(
            afl_collect.generate_sample_list('/invalid', files_collected))
예제 #4
0
def main(argv):
    show_info()

    parser = argparse.ArgumentParser(description="afl-vcrash verifies that afl-fuzz crash samples lead to crashes in \
the target binary.", usage="afl-vcrash [-f LIST_FILENAME] [-h] [-j THREADS] [-q] [-r] collection_dir -- target_command")

    parser.add_argument("collection_dir",
                        help="Directory holding all crash samples that will be verified.")
    parser.add_argument("target_cmd", nargs="+", help="Target binary including command line \
options. Use '@@' to specify crash sample input file position (see afl-fuzz usage).")
    parser.add_argument("-f", "--filelist", dest="list_filename", default=None,
                        help="Writes all crash sample file names that do not lead to crashes into a file.")
    parser.add_argument("-j", "--threads", dest="num_threads", default=1,
                        help="Enable parallel verification by specifying the number of threads afl-vcrash \
will utilize.")
    parser.add_argument("-q", "--quiet", dest="quiet", action="store_const", const=True, default=False,
                        help="Suppress output of crash sample file names that do not lead to crashes. This is \
particularly useful when combined with '-r' or '-f'.")
    parser.add_argument("-r", "--remove", dest="remove", action="store_const", const=True, default=False,
                        help="Remove crash samples that do not lead to crashes.")

    args = parser.parse_args(argv[1:])

    if args.collection_dir:
        input_dir = args.collection_dir
    else:
        print("No valid directory provided for <collection_dir>!")
        return

    num_crashes, crash_samples = afl_collect.get_samples_from_dir(input_dir, True)

    print("Verifying %d crash samples..." % num_crashes)

    args.target_cmd = " ".join(args.target_cmd).split()
    args.target_cmd[0] = os.path.abspath(os.path.expanduser(args.target_cmd[0]))
    if not os.path.exists(args.target_cmd[0]):
        print("Target binary not found!")
        return
    args.target_cmd = " ".join(args.target_cmd)

    invalid_samples = verify_samples(int(args.num_threads), crash_samples, args.target_cmd)

    print("Found %d invalid crash samples." % len(invalid_samples))

    if args.remove:
        print("Removing invalid crash samples.")
        remove_samples(invalid_samples, args.quiet)
    elif not args.quiet:
        for ci in invalid_samples:
            print(ci)

    # generate filelist of collected crash samples
    if args.list_filename:
        afl_collect.generate_sample_list(args.list_filename, invalid_samples)
        print("Generated invalid crash sample list '%s'." % args.list_filename)
예제 #5
0
    def test_generate_sample_list(self):
        list_name = 'testdata/read_only'
        files_collected = [
            'dummy0',
            'dummy1',
            'dummy2'
        ]
        self.assertFalse(os.path.exists('testdata/read_only'))
        self.assertIsNone(afl_collect.generate_sample_list(list_name, files_collected))
        self.assertTrue(os.path.exists('testdata/read_only'))

        self.assertIsNone(afl_collect.generate_sample_list('/invalid', files_collected))