def testResolveFieldByAbsoluteName(self): self.target_field = '/B/C/to' uut = self.get_default_field() container = Container( name='A', fields=[ uut, Container(name='B', fields=[ Container(name='C', fields=[ self.to, Container(name='D', fields=[ UInt32(name='E', value=1) ]), ]), ]), ]) container.render() uut_rendered = uut.render() uut_val = unpack('>I', uut_rendered.tobytes())[0] self.assertEqual(len(uut_rendered), uut_val) self.assertEqual(32, uut_val)
def __init__(self, name, fields, fuzzable=True): header = Container(name="header", fields=[ SizeInBytes(name="length", sized_field=self, length=32, encoder=ENC_INT_BE), String(name="name", value=name, fuzzable=False) ]) content = Container(name="content", fields=fields) super(Mp4Box, self).__init__(name=name.replace("\xa9", "\\xa9"), fields=[header, content], fuzzable=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 GenerateHidReport(report_str, name=None): ''' Generate an HID report Container from a HID report string :param report_str: HID report string :param name: name of generated Container (default: None) :raises: KittyException if not enough bytes are left for command :examples: :: Template( name='MyHidReport', fields=GenerateHidReport( '05010906A101050719E029E7150025017501950881029501750881011900296515002565750895018100C0', ) ) ''' fields = [] index = 0 namer = NameGen() while index < len(report_str): opcode = report_str[index] num_args = opcode & 3 if index + num_args >= len(report_str): raise KittyException('Not enough bytes in hid report for last opcode') index += 1 cur_name = namer.gen(opcode) if num_args == 0: fields.append(UInt8(opcode, name=cur_name)) else: args = report_str[index:index + num_args] value = sum(args[i] << (i * 8) for i in range(len(args))) # little endian... fields.append(Container( name=cur_name, fields=[ UInt8(opcode, name='opcode'), BitField(value, 8 * len(args), encoder=ENC_INT_LE, name='value') ] )) index += num_args return OneOf( name=name, fields=[ Container( name='generation', fields=fields ), MutableField( name='mutation', value=report_str ), RandomHidReport( name='random_sequences' ), ])
def _testCorrectIndex(self, expected_index): field_list = [String('%d' % i) for i in range(20)] field_list[expected_index] = self.get_original_field() uut = self.get_default_field() t = Container(name='level1', fields=[uut, Container(name='level2', fields=field_list)]) 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='{}_{}'.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 testAbsoluteNameDoesNotExist(self): original_field = self.get_original_field() absolute_name = '/A/B/' + original_field.get_name() self.depends_on_name = absolute_name calculated_field = self.get_default_field() container = Container(name='A', fields=[ Container(name='B', fields=[ Container(name='C', fields=[ original_field ]), calculated_field ]) ]) with self.assertRaises(KittyException): container.render()
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 testSizeInclusiveAlone(self): self.length = 32 container = Container(name=self.depends_on_name, fields=[self.get_default_field()]) rendered = container.render() self.assertEqual(len(rendered), self.length) self.assertEquals(unpack('>I', rendered.tobytes())[0], self.length / 8)
def testContainerWithInternalContainer(self): container = Container(name=self.depends_on_name, fields=[ String('abc'), String('def'), Container(name='counts_as_one', fields=[ String('ghi'), String('jkl'), ]) ]) uut = self.get_default_field() full = Container([container, uut]) full.render() self.assertEqual(uut.render(), self.calculate(container)) del full
def __init__(self, name, status, error, chain_param, ab_data, fuzzable=True): fields = [ UInt8(name='bMessageType', value=0x80), SizeInBytes(name='dwLength', sized_field=ab_data, length=32, fuzzable=True, encoder=ENC_INT_LE), DynamicInt(name='bSlot', key='bSlot', bitfield=UInt8(name='bSlotInt', value=0)), DynamicInt(name='bSeq', key='bSeq', bitfield=UInt8(name='bSeqInt', value=0)), UInt8(name='bStatus', value=status), UInt8(name='bError', value=error), UInt8(name='bChainParameter', value=chain_param), Container(name='abData', fields=ab_data), ] super(R2PDataBlock, self).__init__(name=name, fields=fields, fuzzable=fuzzable)
def __init__(self, fields={}, fuzz_keys=True, fuzz_delims=True, name=None): ''' :param fields: dictionary of strings and torrent fields :fuzz_delims: bool (default: True) :param name: name of container (default: None) ''' name = name if name is not None else _unique_name(type(self).__name__) dictionary_fields = [] for k, v in fields.items(): dictionary_fields.append( Container(name=_merge(name, 'container', k), fields=[ TString(value=k, fuzz_value=fuzz_keys, fuzz_length=fuzz_keys, fuzz_delim=fuzz_delims, name=_merge(name, 'key', k)), v ])) super(TDict, self).__init__( name=name, fields=[ String(value='d', max_size=1, fuzzable=fuzz_delims, name=_merge(name, 'start')), TakeFrom(name=_merge(name, 'fields'), fields=dictionary_fields, min_elements=len(dictionary_fields) / 2), String(value='e', max_size=1, fuzzable=fuzz_delims, name=_merge(name, 'end')) ])
def __init__(self, data='', fuzz_delims=False, fuzz_param=False, fuzz_value=True, fuzzable=True, name=None): ''' :param data: data string (default: '') :param fuzz_delims: should fuzz the delimiters (default: False) :param name: name of container (default: None) :param fuzzable: should fuzz the container (default: True) ''' fields = [] for i, part in enumerate(data.split('&')): part = part.split('=') if len(fields) >= 1: fields.append( Delimiter(name='search_delim_%d' % i, value='&', fuzzable=fuzz_delims)) fields.append( Container(name='param_%s' % part[0], fields=[ String(name='search_%d_key' % i, value=part[0], fuzzable=fuzz_param), Delimiter(value='=', fuzzable=fuzz_delims), String(name='search_%d_value' % i, value=part[1], fuzzable=fuzz_value) ])) super(PostFormUrlencoded, self).__init__(name=name, fields=fields, fuzzable=fuzzable)
def __init__(self, search='', fuzz_delims=False, fuzz_param=False, fuzz_value=True, fuzzable=True, name=None): ''' :param search: search string (default: '') :param fuzz_delims: should fuzz the delimiters (default: False) :param name: name of container (default: None) :param fuzzable: should fuzz the container (default: True) ''' fields = [ Delimiter(name='search main delim', value='?', fuzzable=fuzz_delims), ] for i, part in enumerate(search.split('&')): part = part.split('=') fields.append( Container(name='param_%s' % part[0], fields=[ String(name='search_%d_key' % i, value=part[0], fuzzable=fuzz_param), Delimiter(value='=', fuzzable=fuzz_delims), String(name='search_%d_value' % i, value=part[1], fuzzable=fuzz_value) ])) super(Search, self).__init__(name=name, fields=fields, fuzzable=fuzzable)
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 __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 testAbsoluteOffsetOfPreFieldAtTheBeginning(self): uut = self.get_default_field() container = Container(name='container', fields=[self.to, uut]) container.render() uut_rendered = uut.render() uut_val = unpack('>I', uut_rendered.tobytes())[0] self.assertEqual(0, uut_val)
def testNameDoesNotExist(self): original_field = self.get_original_field() self.depends_on_name = 'not really' calculated_field = self.get_default_field() container = Container([original_field, calculated_field]) with self.assertRaises(KittyException): container.render()
def testAbsoluteOffsetOfPostFieldFixed(self): uut = self.get_default_field() container = Container(name='container', fields=[uut, self.to]) container.render() uut_rendered = uut.render() uut_val = unpack('>I', uut_rendered.tobytes())[0] self.assertEqual(32, uut_val)
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 testInternalContainer(self): internal_container = Container(name=self.depends_on_name, fields=[ String('ghi', name='field3'), String('jkl', name='field4'), ]) container = Container(name='this_doesnt_count', fields=[ String('abc', name='field1'), String('def', name='field2'), internal_container ]) uut = self.get_default_field() full = Container([container, uut]) full.render() self.assertEqual(uut.render(), self.calculate(internal_container)) del full
def testAbsoluteOffsetOfPreFieldNotAtTheBeginning(self): uut = self.get_default_field() pre_field = String(name='first', value='first') container = Container(name='container', fields=[pre_field, self.to, uut]) while container.mutate(): container.render() uut_rendered = uut.render() uut_val = unpack('>I', uut_rendered.tobytes())[0] self.assertEqual(len(pre_field.render()), uut_val)
def testResolveTargetFieldByName(self): self.target_field = 'to' uut = self.get_default_field() container = Container(name='container', fields=[uut, self.to]) container.render() uut_rendered = uut.render() uut_val = unpack('>I', uut_rendered.tobytes())[0] self.assertEqual(len(uut_rendered), uut_val) self.assertEqual(32, uut_val)
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 testCorrectionInt(self): self.correction = 5 uut = self.get_default_field() pre_field = String(name='first', value='first') container = Container(name='container', fields=[pre_field, self.to, uut]) while container.mutate(): container.render() uut_rendered = uut.render() uut_val = unpack('>I', uut_rendered.tobytes())[0] self.assertEqual(len(pre_field.render()) + 5, uut_val)
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, name, type_code=0, fields=None, fuzzable=True): super(Mp4MetadataBox, self).__init__(name, fields=[ Mp4Box("data", fuzzable=fuzzable, fields=[ BE16(name="typeReserved", value=0), BE8(name="typeSetIdentifier", value=0), BE8(name="typeCode", value=type_code), BE32(name="locale", value=0), Container(name="metadata", fields=fields) ]) ])
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 testAbsoluteNameExists(self): original_field = self.get_original_field() absolute_name = '/A/B/C/' + original_field.get_name() self.depends_on_name = absolute_name calculated_field = self.get_default_field() container = Container(name='A', fields=[ Container(name='B', fields=[ Container(name='C', fields=[ original_field ]), calculated_field ]) ]) expected = self.calculate(original_field) actual = calculated_field.render() self.assertEqual(expected, actual) while container.mutate(): expected = self.calculate(original_field) actual = calculated_field.render() self.assertEqual(expected, actual)