def __call__(self, context): client = ImposterClient(context) mh = MessageHelper(context) fuzzer = Fuzzer(context) handshake_request = client.handshake() print mh.unpack_request(handshake_request) # Fuzz a read request for m in fuzzer.fuzz(handshake_request): print mh.unpack_request(m)[0] client.send(m) response_raw = client.receive() response = client.unpack(response_raw, m) print response
class Fuzzer(object): """Take a valid network packet and fuzz the crap out of it Fuzzing strategies: - Random bytes - Exhaustive (recursive) - Fuzz vectors (known "dangerous" values" """ def __init__(self, context): self.mh = MessageHelper(context) def fuzz(self, valid_packet): """Generate fuzzed packets""" i = 0 self.valid_packet = self.mh.unpack_request(valid_packet)[0] # Just do a static number of permutations for now. while i < 1000: print '[i]', i yield self.permute(self.valid_packet) i += 1 def permute(self, packet): """Return a fuzzed packet""" if packet.type == 'handshake': packet_struct = get_struct('ClientInitHandShake') else: packet_struct = get_struct('ClientRequestHdr') packet_struct += get_struct('Client' + packet.type[4:].title() + 'Request') if packet.type == 'kXR_read': packet_struct += get_struct('read_args') # Remove 'type' field that we inserted for convenience vars = packet._asdict() del vars['type'] for field in packet_struct: if field['fuzzable']: vars[field['name']] = self.mutate(vars[field['name']], field['type']) return self.mh.build_message(packet_struct, vars) def mutate(self, field, type): if type == 'H': return random.randint(0, 65535) elif type == 'l': return random.randint(-2147483648 + 1, 2147483647) elif type == 'q': return random.randint(-sys.maxint + 1, sys.maxint) elif type in ('s', 'c'): return os.urandom(len(field))