kitty.model.low_level.container module¶
Containers are fields that group multiple fields into a single logical unit,
they all inherit from Container
, which inherits from
BaseField
.
-
class
kitty.model.low_level.container.
Conditional
(condition, fields=[], encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.container.Container
Container that its rendering is dependant on a condition
-
__init__
(condition, fields=[], encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Parameters: - condition (an object that has a function applies(self, Container) -> Boolean) – condition to evaluate
- fields – enclosed field(s) (default: [])
- encoder (BitsEncoder) – encoder for the container (default: ENC_BITS_DEFAULT)
- fuzzable – is container fuzzable (default: True)
- name – (unique) name of the container (default: None)
Example: Template([ Group(['a', 'b', 'c'], name='letters'), If(ConditionCompare('letters', '==', 'a'), [ Static('dvil') ]) ]) # results in the mutations: advil, b, c
-
get_rendered_fields
(ctx=None)[source]¶ Parameters: ctx – rendering context in which the method was called Returns: ordered list of the fields that will be rendered
-
-
class
kitty.model.low_level.container.
Container
(fields=[], encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.field.BaseField
A logical unit to group multiple fields together
-
__init__
(fields=[], encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Parameters: - fields (field or iterable of fields) – enclosed field(s) (default: [])
- encoder (BitsEncoder) – encoder for the container (default: ENC_BITS_DEFAULT)
- fuzzable – is container fuzzable (default: True)
- name – (unique) name of the container (default: None)
Example: Container([ String('header_name'), Delimiter('='), String('header_value') ])
-
append_fields
(new_fields)[source]¶ Add fields to the container
Parameters: new_fields – fields to append
-
get_field_by_name
(name)[source]¶ Parameters: name – name of field to get Returns: direct sub-field with the given name Raises: KittyException
if no direct subfield with this name
-
get_rendered_fields
(ctx=None)[source]¶ Parameters: ctx – rendering context in which the method was called Returns: ordered list of the fields that will be rendered
-
is_default
()[source]¶ Checks if the field is in its default form
Returns: True if field is in default form
-
push
(field)[source]¶ Add a field to the container, if the field is a Container itself, it should be poped() when done pushing into it
Parameters: field – BaseField to push
-
render
(ctx=None)[source]¶ Parameters: ctx – rendering context in which the method was called Return type: Bits Returns: rendered value of the container
-
replace_fields
(new_fields)[source]¶ Remove all fields from the container and add new fields
Parameters: new_fields – fields to add to the container
-
scan_for_field
(field_key)[source]¶ Scan for a field in the container and its enclosed fields
Parameters: field_key – name of field to look for Returns: field with name that matches field_key, None if not found
-
-
class
kitty.model.low_level.container.
ForEach
(mutated_field, fields=[], encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.container.Container
Perform all mutations of enclosed fields for each mutation of mutated_field
-
__init__
(mutated_field, fields=[], encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Parameters: - mutated_field – (name of) field to perform mutations for each of its mutations
- fields – enclosed field(s) (default: [])
- encoder (BitsEncoder) – encoder for the container (default: ENC_BITS_DEFAULT)
- fuzzable – is container fuzzable (default: True)
- name – (unique) name of the container (default: None)
Example: Template([ Group(['a', 'b', 'c'], name='letters'), ForEach('letters', [ Group(['1', '2', '3']) ]) ]) # results in the mutations: a1, a2, a3, b1, b2, b3, c1, c2, c3
-
-
class
kitty.model.low_level.container.
If
(condition, fields=[], encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.container.Conditional
Render only if condition evalutes to True
-
class
kitty.model.low_level.container.
IfNot
(condition, fields=[], encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.container.Conditional
Render only if condition evalutes to False
-
class
kitty.model.low_level.container.
Meta
(fields=[], encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.container.Container
Don’t render enclosed fields
Example: Container([ Static('no sp'), Meta([Static(' ')]), Static('ace') ]) # will render to: 'no space'
-
class
kitty.model.low_level.container.
OneOf
(fields=[], encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.container.Container
Render a single field from the fields (also mutates only one field each time)
Example: OneOf(fields=[ String('A'), String('B'), String('C'), String('D'), ]) # 'A', 'AAAA', '%s' ... 'B', 'BBBB' ... 'C' .. 'D'
-
class
kitty.model.low_level.container.
Pad
(pad_length, pad_data='x00', fields=[], fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.container.Container
Pad the rendered value of the enclosed fields
-
__init__
(pad_length, pad_data='\x00', fields=[], fuzzable=True, name=None)[source]¶ Parameters: - pad_length – length to pad up to (in bits)
- pad_data – data to pad with (default: ‘’)
- fields – enclosed field(s) (default: [])
- fuzzable – is fuzzable (default: True)
- name – (unique) name of the template (default: None)
Example: Pad a string with ‘ ‘s so it is at least 20 bytes
Pad(fields=String('padded'), pad_data=' ', pad_length=20) # default result will be: 'padded '
-
-
class
kitty.model.low_level.container.
PseudoTemplate
(name)[source]¶ Bases:
kitty.model.low_level.container.Template
A pseudo template is an empty, immutable template, that can be created with any name. Pseudo templates are useful when fuzzing clients and we want to fuzz a template at differemt stages.
Example: Let’s say you have a protocol in which a given request is performed twice and you don’t only want to check the handling of the response for each request, but what happens when those responses are different.
This use case happens in various protocols. For example, some USB hosts may ask the same descriptor twice. In the first time, they will only read its length and allocate enough memory for it, and in the second time it will copy the descriptor to the allocated buffer. Providing different descriptors in each response may expose bugs that are similar to time-of-check time-of-use.
When working with a graph model, this can be a problem, as you need to connect the same template to itself to match the stages of the stack, but you cannot do that, as it creates a cycle inside the GraphModel.
The solution is to create
PseudoTemplates
s with the same name.Example: g = GraphModel() stage1 = PseudoTemplate(original.get_name()) stage2 = PseudoTemplate(original.get_name()) g.connect(original) g.connect(stage1) g.connect(stage1, original) g.connect(stage1, stage2) g.connect(stage2, original)
This will result in the following (interesting) sequences:
original
,stage1 -> original
andstage1 -> stage2 -> original
-
class
kitty.model.low_level.container.
Repeat
(fields=[], min_times=1, max_times=1, step=1, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.container.Container
Repeat the enclosed fields. When not mutated, the repeat count is min_times
-
__init__
(fields=[], min_times=1, max_times=1, step=1, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Parameters: - fields – enclosed field(s) (default: [])
- min_times – minimum number of repetitions (default: 1)
- max_times – maximum number of repetitions (default: 1)
- step – how many repetitions to add each mutation (default: 1)
- encoder (BitsEncoder) – encoder for the container (default: ENC_BITS_DEFAULT)
- fuzzable – is container fuzzable (default: True)
- name – (unique) name of the container (default: None)
Examples: Repeat([Static('a')], min_times=5, fuzzable=False) # will render to: 'aaaaa' Repeat([Static('a')], min_times=5, max_times=10, step=5) # will render to: 'aaaaa', 'aaaaaaaaaa'
-
-
class
kitty.model.low_level.container.
Switch
(field_dict, key_field, default_key, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.container.OneOf
When switch is not mutating, it will render one of the fields, choosing the one with a key that matchs the value of key_field. When switch is mutating, it will mutate and render one of its fields each time, setting the value of the key_field field to the mutated field key.
-
__init__
(field_dict, key_field, default_key, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Parameters: - field_dict – dictionary of key:field
- key_field – (name of) field that switch takes the key from
- default_key – key to use if the key_field’s value doesn’t match any key
- encoder (BitsEncoder) – encoder for the container (default: ENC_BITS_DEFAULT)
- fuzzable – is container fuzzable (default: True)
- name – (unique) name of the container (default: None)
Example: Container(fields=[ BE16(name='opcode', value=1), Switch(name='opcode_params', key_field='opcode', default_key=1, field_dict={ 1: Container(name='opcode_1_params', fields=[ BE32(name='param1', value=3), ]), 2: Container(name='opcode_2_params', fields=[ BE32(name='param1', value=4), BE32(name='param2', value=5), ]), }) ])
-
-
class
kitty.model.low_level.container.
TakeFrom
(fields=[], min_elements=1, max_elements=None, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.container.OneOf
Render to only part of the enclosed fields, performing all mutations on them
-
__init__
(fields=[], min_elements=1, max_elements=None, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]¶ Parameters: - fields (field or iterable of fields) – enclosed field(s) (default: [])
- min_elements – minimum number of elements in the sub set
- max_elements – maximum number of elements in the sub set
- encoder (BitsEncoder) – encoder for the container (default: ENC_BITS_DEFAULT)
- fuzzable – is container fuzzable (default: True)
- name – (unique) name of the container (default: None)
Example: TakeFrom(fields=[ Static('A'), Static('B'), Static('C'), Static('D'), Static('E'), Static('F'), ]) # 'E', 'B', 'D', 'F', 'C', 'A', 'CE', 'FC', 'CF', 'BD', 'AF', 'BED', # 'EBC', 'CDB', 'DCA', 'BFAD', 'FCBD', 'DBCF', 'BFACD' ...
-
-
class
kitty.model.low_level.container.
Template
(fields=[], encoder=<kitty.model.low_level.encoder.ByteAlignedBitsEncoder object>, fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.container.Container
Top most container of a message, serves a the only interface to the high level model
-
__init__
(fields=[], encoder=<kitty.model.low_level.encoder.ByteAlignedBitsEncoder object>, fuzzable=True, name=None)[source]¶ Parameters: - fields – enclosed field(s) (default: [])
- encoder (BitsEncoder) – encoder for the container (default: ENC_BITS_BYTE_ALIGNED)
- fuzzable – is fuzzable (default: True)
- name – (unique) name of the template (default: None)
Example: Template([ Group(['a', 'b', 'c']), Group(['1', '2', '3']) ]) # the mutations are: a1, b1, c1, a1, a2, a3
-
copy
()[source]¶ We might want to change it in the future, but for now...
Raises: KittyException
, as it should not be copied
-
-
class
kitty.model.low_level.container.
Trunc
(max_size, fields=[], fuzzable=True, name=None)[source]¶ Bases:
kitty.model.low_level.container.Container
Truncate the size of the enclosed fields