about summary refs log tree commit diff
path: root/utils/custom_mutators/wrapper_afl_min.py
blob: 5cd6003188e714f864629bf64060aed0b16eb369 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env python

from XmlMutatorMin import XmlMutatorMin

# Default settings (production mode)

__mutator__ = None
__seed__ = "RANDOM"
__log__ = False
__log_file__ = "wrapper.log"


# AFL functions
def log(text):
    """
    Logger
    """

    global __seed__
    global __log__
    global __log_file__

    if __log__:
        with open(__log_file__, "a") as logf:
            logf.write("[%s] %s\n" % (__seed__, text))


def init(seed):
    """
    Called once when AFL starts up. Seed is used to identify the AFL instance in log files
    """

    global __mutator__
    global __seed__

    # Get the seed
    __seed__ = seed

    # Create a global mutation class
    try:
        __mutator__ = XmlMutatorMin(__seed__, verbose=__log__)
        log("init(): Mutator created")
    except RuntimeError as e:
        log("init(): Can't create mutator: %s" % e.message)


def fuzz(buf, add_buf, max_size):
    """
    Called for each fuzzing iteration.
    """

    global __mutator__

    # Do we have a working mutator object?
    if __mutator__ is None:
        log("fuzz(): Can't fuzz, no mutator available")
        return buf

    # Try to use the AFL buffer
    via_buffer = True

    # Interpret the AFL buffer (an array of bytes) as a string
    if via_buffer:
        try:
            buf_str = str(buf)
            log("fuzz(): AFL buffer converted to a string")
        except Exception:
            via_buffer = False
            log("fuzz(): Can't convert AFL buffer to a string")

    # Load XML from the AFL string
    if via_buffer:
        try:
            __mutator__.init_from_string(buf_str)
            log(
                "fuzz(): Mutator successfully initialized with AFL buffer (%d bytes)"
                % len(buf_str)
            )
        except Exception:
            via_buffer = False
            log("fuzz(): Can't initialize mutator with AFL buffer")

    # If init from AFL buffer wasn't succesful
    if not via_buffer:
        log("fuzz(): Returning unmodified AFL buffer")
        return buf

    # Sucessful initialization -> mutate
    try:
        __mutator__.mutate(max=5)
        log("fuzz(): Input mutated")
    except Exception:
        log("fuzz(): Can't mutate input => returning buf")
        return buf

    # Convert mutated data to a array of bytes
    try:
        data = bytearray(__mutator__.save_to_string())
        log("fuzz(): Mutated data converted as bytes")
    except Exception:
        log("fuzz(): Can't convert mutated data to bytes => returning buf")
        return buf

    # Everything went fine, returning mutated content
    log("fuzz(): Returning %d bytes" % len(data))
    return data


# Main (for debug)
if __name__ == "__main__":

    __log__ = True
    __log_file__ = "/dev/stdout"
    __seed__ = "RANDOM"

    init(__seed__)

    in_1 = bytearray(
        "<foo ddd='eeee'>ffff<a b='c' d='456' eee='ffffff'>zzzzzzzzzzzz</a><b yyy='YYY' zzz='ZZZ'></b></foo>"
    )
    in_2 = bytearray("<abc abc123='456' abcCBA='ppppppppppppppppppppppppppppp'/>")
    out = fuzz(in_1, in_2)
    print(out)