#!/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( "ffffzzzzzzzzzzzz" ) in_2 = bytearray("") out = fuzz(in_1, in_2) print(out)