def testNumMutations0(self): field = Static(value=self.default_value) num_mutations = field.num_mutations() self.assertEqual(num_mutations, 0) self._check_mutation_count(field, num_mutations) field.reset() self._check_mutation_count(field, num_mutations)
def __init__(self, method='GET', uri='/', protocol='HTTP', version=1.0, fuzzable_method=False, fuzzable_uri=False, fuzzable=True): method_value = [method] if isinstance(method, str) else method parsed = urlparse(uri) uri_value = [Path(parsed.path, name='path', fuzz_delims=False)] if parsed.query: uri_value.append( Search(parsed.query, name='search', fuzz_value=True)) fields = [ Group(name='method', values=method_value, fuzzable=fuzzable_method), Static(' '), Container(name='uri', fields=uri_value, fuzzable=fuzzable_uri), Static(' '), String(name='protocol', value=protocol, fuzzable=False), Float(name='version', value=version), Static('\r\n'), ] super(HttpRequestLine, self).__init__(name='http url', fields=fields, fuzzable=fuzzable)
def compile_template(self): _url = Static(name='url', value=self.url.encode()) _method = Static(name='method', value=self.method.encode()) template = Template(name='{}_{}'.format(self.url.replace('/', '_'), self.method), fields=[_url, _method]) self.fuzz_place = get_field_type_by_method(self.method) template.append_fields([Container(name='{}'.format(self.fuzz_place), fields=self.fuzz_params)]) return template
def compile_template(self): _url = Static(name='url', value=self.url) _method = Static(name='method', value=self.method) template = Template(name=self.name, fields=[_url, _method]) for name, field in self.field_to_param.items(): if list(field): template.append_fields([Container(name=name, fields=field)]) return template
def __init__(self, data=b'', boundary=b'', fuzz_delims=False, fuzz_param=False, fuzz_value=True, name=None): self.separator = b'--%s' % boundary self.terminator = b'--%s--' % boundary multipart = self.multipart2json_parse(data) fields = [] for item in multipart: fields += [ Delimiter(self.separator, fuzzable=fuzz_delims), Static(b'\r\n') ] inner_container_header = [] ContentDisposition = item.get(b'header').get( b'Content-Disposition').get(b'params') var_name = ContentDisposition.get(b'name') var_value = item.get(b'value') for header_field in item.get(b'header'): header_value = item.get(b'header')[header_field].get(b'value') header_params = item.get(b'header')[header_field].get( b'params') multipart_header_name = '%s_%s' % (header_field.decode(), var_name.decode()) inner_container_header.append( TextField(key=header_field, value=header_value, params=header_params, name=multipart_header_name, fuzzable_key=fuzz_param, fuzzable_value=fuzz_value)) inner_container_header.append(Static(b'\r\n')) fields.append( Container(fields=inner_container_header, name='%s_header' % var_name)) # Append multipart param value if var_value.isdigit(): fields.append( DecimalNumber(name="multipart_value_%s" % var_name.decode(), num_bits=bit_length(int(var_value)), value=int(var_value), signed=True)) else: fields.append(String(var_value)) fields.append(Static(b'\r\n')) # Append terminator boundary fields += [ Delimiter(self.terminator, fuzzable=fuzz_delims), Static(b'\r\n') ] super(PostMultipartFormData, self).__init__(name=name, fields=fields, fuzzable=fuzz_value)
def __init__(self, key, value, fuzzable=True): fields = [ Static(' '), String(name='attribute key', value=key, fuzzable=False), Static('="'), Container(name='attribute value', fields=value), Static('"'), ] super(xmlAttribute, self).__init__(name=key, fields=fields, fuzzable=fuzzable)
def compile_template(self): _url = Static(name='url', value=self.url) _method = Static(name='method', value=self.method) template = Template(name=self.name, fields=[_url, _method]) for name, field in self.field_to_param.items(): if list(field): try: template.append_fields([Container(name=name, fields=field)]) except KittyException as e: self.logger.warning('Failed to add {} because {}, continue processing...'.format(name, e)) return template
def __init__(self, name, data_reference_index, channelcount, samplesize, pre_defined, samplerate, fields=[], fuzzable=True): super(AudioSampleEntry, self).__init__(name=name, fields=[ Static(name="reserved0", value="\x00"*6), BE16(name="data_reference_index", value=data_reference_index), Static(name="reserved1", value="\x00\x00\x00\x00"*2), BE16(name="channelcount", value=channelcount), BE16(name="samplesize", value=samplesize), BE16(name="pre_defined", value=pre_defined), BE16(name="reserved2", value=0x0000), BE32(name="samplerate", value=samplerate), ] + fields, fuzzable=fuzzable)
def __init__(self, name, value, fuzzable=True): ''' :param name: block name :param value: value to be used :param fuzzable: should we fuzz this field (default: True) ''' if isinstance(value, BaseField): value_field = value else: value_field = String(value, fuzzable=fuzzable, name=_valuename(name)) fields = [Static('"'), value_field, Static('"')] super(JsonString, self).__init__(fields, name=name) self.value = value
def compile_template(self): _url = Static(name='url', value=self.url.encode()) _method = Static(name='method', value=self.method.encode()) template = Template(name='{}_{}'.format(self.url.replace('/', '_'), self.method), fields=[_url, _method]) if self.parameters: template.append_fields([Container(name='parameters', fields=self.parameters)]) if self.headers: template.append_fields([Container(name='headers', fields=self.headers)]) if self.data: template.append_fields([Container(name='data', fields=self.data)]) if self.path_variables: template.append_fields([Container(name='path_variables', fields=self.path_variables)]) return template
def testFieldNotRenderedWithOtherFields(self): expected_index = 3 uut = self.get_default_field() fields = [ Static(name=self.depends_on_name, value=''), Static('field1'), Static('field2'), Static('field3'), ] t = Container(name='level1', fields=[uut, Container(name='level2', fields=fields)]) rendered = uut.render().tobytes() result = unpack('>I', rendered)[0] self.assertEqual(result, expected_index) del t
def __init__(self, name, values): ''' :param name: block name :type values: list of :class:`~kitty.model.low_level.fields.BaseField` :param values: array members ''' self.values = values fields = [] fields.append(Static('[')) for i, value in enumerate(self.values): fields.append(value) if i != (len(self.values) - 1): fields.append(Static(',')) fields.append(Static(']')) super(JsonArray, self).__init__(fields, name=name)
def __init__(self, key, username, password, end=False, delim=':', fuzz_username=True, fuzz_password=True, fuzzable_key=False, fuzzable=True): value_field = [ Static('Basic '), Container(name='base64_auth', fields=[ String(name='username', value=username, fuzzable=fuzz_username), Delimiter(delim, fuzzable=False), String(name='password', value=password, fuzzable=fuzz_password), ], encoder=ENC_BITS_BASE64) ] super(AuthorizationField, self).__init__(key, value_field, end, fuzzable_key, fuzzable)
def testFieldNotRenderedAlone(self): expected_index = 0 uut = self.get_default_field() the_field = Static(name=self.depends_on_name, value='') t = Container(name='level1', fields=[uut, Container(name='level2', fields=the_field)]) rendered = uut.render().tobytes() result = unpack('>I', rendered)[0] self.assertEqual(result, expected_index) del t
def compile_template(self): _url = Static(name='url', value=self.url.encode()) _method = Static(name='method', value=self.method.encode()) template = Template(name=self.name, fields=[_url, _method]) if list(self.params): template.append_fields( [Container(name='params', fields=self.params)]) if list(self.headers): template.append_fields( [Container(name='headers', fields=self.headers)]) if list(self.data): template.append_fields([Container(name='data', fields=self.data)]) if list(self.path_variables): template.append_fields( [Container(name='path_variables', fields=self.path_variables)]) if list(self.cookies): template.append_fields( [Container(name='cookies', fields=self.cookies)]) return template
def __init__(self, key, value, end=False, fuzzable_key=False, fuzzable_value=True): fields = [ String(name=_keyname(key), value=key, fuzzable=fuzzable_key), Static(': '), Container(name=_valuename(key), fields=value, fuzable=fuzzable_value), Static('\r\n') ] if end: fields.append(Static('\r\n')) super(CustomHeaderField, self).__init__(name=key, fields=fields, fuzzable=fuzzable_value)
def __init__(self, name, member_dict, fuzz_keys=False): ''' :param name: block name :type member_dict: dictionary (str, :class:`~kitty.model.low_level.fields.BaseField`) :param member_dict: members of this object :param fuzz_keys: should we fuzz the dictionary keys (default: False) ''' fields = [] self.members = member_dict fields.append(Static('{')) items = self.members.items() for i, (k, v) in enumerate(items): basic_name = name + '_' + k fields.append(JsonString(_keyname(basic_name), k, fuzzable=fuzz_keys)) fields.append(Static(':')) fields.append(v) if i != (len(items) - 1): fields.append(Static(',')) fields.append(Static('}')) super(JsonObject, self).__init__(fields, name=name)
def testStringApplies(self): expected_value = 'Expected' value_field = String(name='comp_field', value='applies') condition = self.cls(field=value_field, comp_value='applies') c = Container(name='container', fields=[ Meta(value_field), If(condition=condition, fields=[Static('Expected')]) ]) rendered = c.render().tobytes() self.assertEqual(rendered, expected_value)
def testApplies(self): expected_value = 'Expected' value_field = self._get_applies_field() condition = self._get_condition(value_field) c = Container(name='container', fields=[ Meta(value_field), If(condition=condition, fields=[Static(expected_value)]) ]) rendered = c.render().tobytes() self.assertEqual(rendered, expected_value.encode())
def testNotApplies(self): expected_value = '' value_field = self._get_not_applies_field() condition = self._get_condition(value_field) c = Container(name='container', fields=[ Meta(value_field), If(condition=condition, fields=[Static('Should not appear')]) ]) rendered = c.render().tobytes() self.assertEqual(rendered, expected_value)
def __init__(self, key, value, flags=0, fuzzable=True): fields = [ SizeInBytes(name="Size of Item Value", sized_field="Item Value", length=32, encoder=ENC_INT_LE), LE32(name="Item Flags", value=flags), String(name="Item Key", value=key, fuzzable=False), Static("\x00"), Container(name="Item Value", fields=[value]) ] super(apev2item, self).__init__(name=key, fields=fields, fuzzable=fuzzable)
def craft_model_by_request(request): # Craft Kitty Model Template value_fields = [] proto = request.request_version.split('/')[0] proto_ver = float(request.request_version.split('/')[1]) # Append Request Line value_fields.append( HttpRequestLine( method=request.requestline.split()[0], uri=request.path, protocol=proto, version=proto_ver, fuzzable_method=True, fuzzable_uri=True, )) # Append headers for k, v in request.headers.items(): if k == 'Content-Length': continue if v.isdigit(): value_fields.append(IntField(key=k, value=int(v))) else: value_fields.append(TextField(key=k, value=v)) # Append data if exists if not request.headers.get('Content-Length'): value_fields.append(Static(b'\r\n')) else: content_length = int(request.headers.get('Content-Length') or 0) value_fields.append( ContentLengthField(sized_field='post_data_params', value=content_length, end=True)) data = request.rfile.read(content_length) if request.headers.get( 'Content-Type') == 'application/x-www-form-urlencoded': value_fields.append( PostFormUrlencoded(data.decode(), name='post_data_params', fuzz_param=True)) elif request.headers.get('Content-Type').startswith( 'multipart/form-data'): boundary = request.headers.get('Content-Type').split( 'boundary=')[1].encode() value_fields.append( PostMultipartFormData(data, boundary, name='post_data_params', fuzz_param=True)) return Template(value_fields, name='Http_Request')
def __init__(self, name=None, fuzzable=True): namer = NameGen() fields = [] r = Random() for tag in opcodes: for i in range(4): opcode = tag | i current = chr(opcode) for j in range(i): current += chr(r.randint(0, 255)) fields.append(Static(name=namer.gen(opcode), value=current)) super(RandomHidReport, self).__init__(fields=fields, min_elements=10, max_elements=40, fuzzable=fuzzable, name=name)
fields=[ UInt8(name='bDesciptorSubType', value=0x06), UInt8(name='bUnitID', value=5), UInt8(name='bSourceID', value=2), SizeInBytes(name='bControlSize', sized_field='bmaControls', length=8), RandomBytes(name='bmaControls', value='\x01', min_length=0, max_length=250), UInt8(name='iFeature', value=1), ]), # .. todo: 4.3.2.6 OneOf(fields=[ Static(''), SubDescriptor(name='junk', descriptor_type=DescriptorType.cs_interface, fields=[ UInt8(name='bDesciptorSubType', value=0x15), ForEach('bDesciptorSubType', fields=[ RandomBytes(name='junk', value='\x01', min_length=0, max_length=250), ]) ]), ]) ]),
from kitty.model import Template, Container, Static, OneOf from id3v23 import id3v23container from apetagv2 import apev2container mp3base = Template( name="mp3base", fields=[ OneOf(name="tag", fields=[id3v23container, apev2container]), Container( name="audio_frame", fields=[ Static( name="default_data", value= "fff310c40002d11aec01401001fffffffffa9c0c0c0c0cf9d5fffff312c40103593f1401803800ffffffd3ff512097c1f37a81aa27fff310c40102f91ee809c08000fffffffff288b841789e3f0008fff310c40202f91b007800143e0403f5fffff0a809cd56000c07fff310c403036916ec7800612003f3ffffea082126016d4d000cfff310c40203291f1c78000e3f0703f5fffff106507aaee2000afff310c40202e1170c7800143f0503f5fffff0606980fa000e07fff310c40302e803307800447203fffffb7fea702755000e0703fff310c40402a123307800872af5fffff8d19ea50281fffffffffff312c40602a11f2819401002fe71a21c85fffffffffff3140dfcfff310c40903493f1401803801207f424a2afffffffc1a51e416fff310c408028006d801c000000e164c414d45332e3937202861fff310c40b00000348000000006c70686129aaaaaaaaaaaaaaaa" .decode("hex")), ]) ])
Static(name="audiodata", value=""" de0400006c69626661616320312e323800000168ac01c820321004424301 0848221208888261813845bffe0aac951bde667e9e9c7e38d5ea2ab35907 4f54ff627f8de79aedac7cf68ecf968786d07f836ff4b84921ff9ff8c039 3abab7ee3b8dc100418872fe7eef1cb06cf1feffaf9672199fe3e27cfee0 7d600661a4102513ee038260172904005088000e002710066000b8009b80 01049ffd51c7364c8e6f37cf8fdbbff6f3c6b57c000c71fafeaf9fc26002 f8fcfdfdbd9be80ff33fedbfe9be861f7e7fdb7fd37d0c3efcffd5f5bfd8 c3efcf7df5bfd8c045fa7bf4aea9981800281403085000160d6797051bc9 8283d77a00720ff028003e39db7db6b7c1d9fb8f9201fd77efdfab57f6f0 0006fdedfbf7ead50feda8001737efbead4d5000005c6fde6ad46a000014 1bf79081000000170dfbc4018e070110d70a821219844461911845ee6b89 db8bf0d77d77ae78ef5dcadfbeb7e3bf5fbfb6b5abb8b975738193266cd9 f3e8d193266ccebad6839fe1b75dcfa0e7f1cc979887c7c180f7279c0cbe 6317f132fd1465938dddbed5fe6bf26fdc7a1e2e38e38997aaf2a3c4a613 2f980cb9022b6408ad900b79806411018404458058440095800058004c00 02a0002a001c0100170ae6211d886054a28958aa2aaaabbfebfbefdfc7f5 ff6fc71c5f0925e359a1e7f4e7e7e7e7e7f3e7f3e7e779e79e79e79e79e7 9e79e792f25e4bcf25e79fbe79b25af5a5af59afe0580c60c6187e48f9fa ec2f6000000018f5d956bd61af5835eb986bd606b9cf5cc35c804b580358 0026982404c00013000b819c000580005400380104170ae615088e44300a 9414a5295555e3f3f7df8f9fcff9fae35c5af5412c71f971e3c7e5978f1c b972c51658a28a28a28a28a28a28a2445122244513c40f50aead4aead4ae ad4964cb47a3f8c7fbcfef1f99ed9029ffb50d5aa0356a806ad40d55d40d 5a8405750082017215aaa154002a41000001500010000170001302c001c0 01165708ca123888842320884826111a06c2306a76d75eaaf8f5aef8e6f7 7bbe69fa79df7f6f1fe3cf5a9a9c22eeb80f6dbd9d9bf7bafedf6dbd926f df81f57f43fc6f39f57f43fc7f81f5125fe37c61e68f96836fee5fe377b0 03c8fbc49c08c1e4a28000027df4fc4dbfd03429fb8ff1a00f8c40f8c40f 8805d4fdc07ee2e0348a00e6002e50002e52c00002a05510051400038001 0a9ffd331928488d66f7cf7eff9ff6f3d6aef435cff59ff92121386b6ff8 dfe9fa4e99f48e24fa36b6ff4fd2427d299276c0df93ed42669833b606e2 7da84cd30676c0df43ed42669925e063de7c8dd1525032b167f44f234f9a f267c87c9e5d57dfa5d1fbfcbc4fc98f4fe15bdd7c81cc6eddc8257d52e6 59e7bd9833bcf3ccd6283506309d508d7ae7af5b61b36361137ef5cd7ada e61b08837dc35eb9b5cc08800de035eb3580000b80d7300002200bdc0380 00fe9ffd749b2a4d0c66677dff6aff3e757163e9fbb3cf3803e7f03dbece 3d55607cfe07b7c3afaaac0edec3c7c3afefab031c0e5e1d7f2ae604c1db f76f55cd61305ff1efb4d64c85079fcb057c048afd592c63111668160596 5016600000000007aba371f1d6f5220004481fec767a1f4300dada3e0ece cf43e87aa001b5b5b4356ad5ac000d9b360d4000003d9b366c0000000d9b 366c000000003fafb2203800c8c0802380""".replace("\n","").decode('hex'))
def get_default_field(self, fuzzable=True): return Static(value=self.default_value, name=self.uut_name)
fuzzable=fuzzable) class apev2textitem(apev2item): def __init__(self, key, value, fuzzable=True): value_field = String(name="key", value=value) super(apev2textitem, self).__init__(key, value_field, flags=0, fuzzable=fuzzable) apev2container = Container( name="apev2container", fields=[ Static("APETAGEX"), LE32(name="version", value=struct.unpack("<I", "2000")[0]), SizeInBytes(name="size", sized_field="items and footer", length=32, encoder=ENC_INT_LE), ElementCount(depends_on="items", length=32, name="item count", encoder=ENC_INT_LE), LE32(name="flags", value=0xa0000000), RandomBytes(name="reserved", value="\x00" * 8, min_length=8, max_length=8), Container(