Beispiel #1
0
def controlled_gen(processes, php, only_str_repeat=False):
    """Generate a controlled set of sequences based on imagecreatetruecolor and
    str_repeat.
    """

    sequences = {}
    total_execs = total_errors = total_duplicates = 0
    for fragment in _gen_str_repeat_fragments():
        fragment, interactions, err = _analyse_fragment(fragment, php)
        total_execs += 1
        if err or not interactions:
            total_errors += 1
            continue

        sequence = InteractionSequence(interactions)
        if sequence.summary in sequences:
            total_duplicates += 1
            continue

        logger.debug("{} => {}".format(fragment, sequence))
        sequences[fragment] = sequence.summary

    logger.info("{} execs, {} errors, {} duplicates from str_repeat".format(
        total_execs, total_errors, total_duplicates))

    if only_str_repeat:
        return sequences

    total_execs = total_errors = total_duplicates = 0
    for fragment in _gen_imagecreatetruecolor_fragments():
        fragment, interactions, err = _analyse_fragment(fragment, php)
        total_execs += 1
        if err or not interactions:
            total_errors += 1
            continue

        sequence = InteractionSequence(interactions)
        if sequence.summary in sequences:
            total_duplicates += 1
            continue

        logger.debug("{} => {}".format(fragment, sequence))
        sequences[fragment] = sequence.summary

    logger.info(("{} execs, {} errors, {} duplicates from "
                 "imagecreatetruecolor").format(total_execs, total_errors,
                                                total_duplicates))
    return sequences
Beispiel #2
0
def _fuzz_process(fragment_store, php, time_limit):
    new_sequences = {}
    existing_summaries = fragment_store.get_summaries()
    existing_fragments = fragment_store.get_fragments()

    total_execs = total_duplicates = total_errors = 0
    start_time = time.time()
    while time.time() - start_time < time_limit:
        fragment = random.sample(existing_fragments, 1)[0]
        new_fragments = _fuzz_fragment(fragment)

        if not new_fragments:
            continue

        for new_fragment in new_fragments:
            fragment, interactions, err = _analyse_fragment(new_fragment, php)
            total_execs += 1
            if err or not interactions:
                total_errors += 1
                continue

            sequence = InteractionSequence(interactions)
            if sequence.summary in existing_summaries:
                total_duplicates += 1
                continue

            logger.debug("{} => {}".format(new_fragment, sequence))
            new_sequences[new_fragment] = sequence.summary
            existing_summaries.add(sequence.summary)

    return new_sequences, total_execs, total_duplicates, total_errors
Beispiel #3
0
def get_interaction_sequences(fragments, processes, php):
    """Execute each of the `fragments` provided using the PHP interpreter at
    `php` and record the resulting allocator interaction sequences.

    Args:
        fragments (list of str): The code fragments to execute
        processes (int): The number of concurrent processes to use
        php (str): The path to the PHP binary to use

    Returns:
        A dict (str to SequenceSummary)) mapping from the fragments to
        summaries of the resulting allocator interaction sequences.
    """

    results = []
    with multiprocessing.Pool(processes=processes) as pool:
        for t in fragments:
            results.append(pool.apply_async(_analyse_fragment, (t, php)))
        pool.close()
        pool.join()

    sequences = {}
    err_fatal = err_os = err_sec = err_no_interaction = 0
    for result_obj in results:
        fragment, interactions, err = result_obj.get(timeout=1)
        if err:
            if err == ERR_FATAL:
                # Some sort of fatal error was reported by the interpreter.
                # Probably an attempt to use an undefined function.
                err_fatal += 1
            elif err == ERR_SECURITY:
                # Used a disabled function
                err_sec += 1
            elif err == ERR_OS:
                err_os += 1
            continue

        if not interactions:
            # No allocator interactions
            err_no_interaction += 1
            continue

        sequences[fragment] = InteractionSequence(interactions).summary

    return sequences, err_fatal, err_os, err_sec, err_no_interaction