1#!/usr/bin/env python 2 3from XmlMutatorMin import XmlMutatorMin 4 5# Default settings (production mode) 6 7__mutator__ = None 8__seed__ = "RANDOM" 9__log__ = False 10__log_file__ = "wrapper.log" 11 12 13# AFL functions 14def log(text): 15 """ 16 Logger 17 """ 18 19 global __seed__ 20 global __log__ 21 global __log_file__ 22 23 if __log__: 24 with open(__log_file__, "a") as logf: 25 logf.write("[%s] %s\n" % (__seed__, text)) 26 27 28def init(seed): 29 """ 30 Called once when AFL starts up. Seed is used to identify the AFL instance in log files 31 """ 32 33 global __mutator__ 34 global __seed__ 35 36 # Get the seed 37 __seed__ = seed 38 39 # Create a global mutation class 40 try: 41 __mutator__ = XmlMutatorMin(__seed__, verbose=__log__) 42 log("init(): Mutator created") 43 except RuntimeError as e: 44 log("init(): Can't create mutator: %s" % e.message) 45 46 47def fuzz(buf, add_buf, max_size): 48 """ 49 Called for each fuzzing iteration. 50 """ 51 52 global __mutator__ 53 54 # Do we have a working mutator object? 55 if __mutator__ is None: 56 log("fuzz(): Can't fuzz, no mutator available") 57 return buf 58 59 # Try to use the AFL buffer 60 via_buffer = True 61 62 # Interpret the AFL buffer (an array of bytes) as a string 63 if via_buffer: 64 try: 65 buf_str = str(buf) 66 log("fuzz(): AFL buffer converted to a string") 67 except Exception: 68 via_buffer = False 69 log("fuzz(): Can't convert AFL buffer to a string") 70 71 # Load XML from the AFL string 72 if via_buffer: 73 try: 74 __mutator__.init_from_string(buf_str) 75 log( 76 "fuzz(): Mutator successfully initialized with AFL buffer (%d bytes)" 77 % len(buf_str) 78 ) 79 except Exception: 80 via_buffer = False 81 log("fuzz(): Can't initialize mutator with AFL buffer") 82 83 # If init from AFL buffer wasn't succesful 84 if not via_buffer: 85 log("fuzz(): Returning unmodified AFL buffer") 86 return buf 87 88 # Sucessful initialization -> mutate 89 try: 90 __mutator__.mutate(max=5) 91 log("fuzz(): Input mutated") 92 except Exception: 93 log("fuzz(): Can't mutate input => returning buf") 94 return buf 95 96 # Convert mutated data to a array of bytes 97 try: 98 data = bytearray(__mutator__.save_to_string()) 99 log("fuzz(): Mutated data converted as bytes") 100 except Exception: 101 log("fuzz(): Can't convert mutated data to bytes => returning buf") 102 return buf 103 104 # Everything went fine, returning mutated content 105 log("fuzz(): Returning %d bytes" % len(data)) 106 return data 107 108 109# Main (for debug) 110if __name__ == "__main__": 111 112 __log__ = True 113 __log_file__ = "/dev/stdout" 114 __seed__ = "RANDOM" 115 116 init(__seed__) 117 118 in_1 = bytearray( 119 "<foo ddd='eeee'>ffff<a b='c' d='456' eee='ffffff'>zzzzzzzzzzzz</a><b yyy='YYY' zzz='ZZZ'></b></foo>" 120 ) 121 in_2 = bytearray("<abc abc123='456' abcCBA='ppppppppppppppppppppppppppppp'/>") 122 out = fuzz(in_1, in_2) 123 print(out) 124