Fuzzing Message Format#

The Preset class can be used to apply format message fuzzing. Fuzzing configuration is provided by the fuzz() method.

Preset.fuzz(key, mode=None, generator=None, seed=None, counterMax=None, kwargs=None)[source]#

The fuzz method specifies the fuzzing strategy for a symbol, a field, a variable or a type.

Applying a fuzzing strategy on a object has the effect to propagate the fuzzing strategy to the object descendants (i.e. fuzzing a symbol will activate fuzzing on its fields, which then triggers the fuzzing of the associated field variables). It is possible to control the fuzzing propagation on node variables (Agg, Alt, Repeat and Opt) with the mutateChild parameter. Besides, it is possible to specifically deactivate fuzzing on a object with the unset method.

The fuzz method expects some parameters:

Parameters
  • key (Field, or Symbol, or Variable, or AbstractType, required) – The targeted object (either a symbol, a field, a variable or a type).

  • mode (Enum, optional) –

    The fuzzing strategy, which can be either:

    • FuzzingMode.MUTATE: in this mode, the specialization process generates a legitimate message from a symbol, then some mutations are applied to it.

    • FuzzingMode.GENERATE: in this mode, the fuzzing component directly produces a random message.

    Default value is FuzzingMode.GENERATE.

  • generator (iter, optional) –

    The underlying generator used to produce pseudo-random or deterministic values.

    Default generator is 'xorshift', which is efficient to produce unique pseudo-random numbers.

    A deterministic is also available (generator='determinist'), and may be used in case where a domain has an interval (see below).

  • seed (int, optional) –

    An integer used to initialize the underlying generator.

    If None, the default value will be set to Mutator.SEED_DEFAULT. The Mutator.SEED_DEFAULT constant is initialized from the configuration variable Conf.seed from the Netzob API Conf class.

  • counterMax (int, optional) –

    An integer used to limit the number of mutations.

    If None, the default value will be set to COUNTER_MAX_DEFAULT = 2**32.

  • kwargs (dict, optional) – Some context dependent parameters (see below) (optional).

The kwargs parameter is used to provide specific options depending on the targeted object type. Available options are described in the following tables:

Integer options:

Option

Description

interval

The scope of values to generate.

  • If set to FuzzingInterval.DEFAULT_INTERVAL, the values will be generated between the min and max values of the domain.

  • If set to FuzzingInterval.FULL_INTERVAL, the values will be generated in [0, 2^N-1], where N is the bitsize (storage) of the field.

  • If it is a tuple of integers (min, max), the values will be generated between min and max.

Default value is dependant on the chosen generator:

  • If the generator is determinist, default interval will be FuzzingInterval.DEFAULT_INTERVAL.

  • Else, default interval will be FuzzingInterval.FULL_INTERVAL.

lengthBitSize

The size in bits of the memory on which the generated values have to be encoded.

The following sizes are available:

  • None (default value), which indicates to use the unit size set in the field domain.

  • UnitSize.SIZE_8

  • UnitSize.SIZE_16

  • UnitSize.SIZE_24

  • UnitSize.SIZE_32

  • UnitSize.SIZE_64

String options:

Option

Description

endChar

The str character(s) which will end the string. This terminal symbol will be mutated by truncating its value if defined on several bytes.

Default value is DEFAULT_END_CHAR. It is used to set the eos parameter of String.

interval

The scope of values to generate.

  • If set to FuzzingInterval.DEFAULT_INTERVAL, the values will be randomly generated with a size between the min and max values of the domain.

  • If set to FuzzingInterval.FULL_INTERVAL, the values will be randomly generated with a size of [0, 2^N-1], where N is the length in bits of the integer used to represent the String length.

  • If it is a tuple of integers (min, max), the values will be randomly generated with a size between min and max.

Default value is FuzzingInterval.FULL_INTERVAL.

lengthBitSize

The size in bits of the memory on which the generated length will be encoded. This parameter should be used in conjunction with FuzzingInterval.FULL_INTERVAL or with a tuple interval, in order to generate String with a length bigger than the original full interval. This parameter will not have any effect when used with FuzzingInterval.DEFAULT_INTERVAL.

The following sizes are available:

  • None (default value), which indicates to use the unit size set in the field domain.

  • UnitSize.SIZE_1

  • UnitSize.SIZE_4

  • UnitSize.SIZE_8

  • UnitSize.SIZE_16

  • UnitSize.SIZE_24

  • UnitSize.SIZE_32

  • UnitSize.SIZE_64

naughtyStrings

The list of potentially dangerous str elements.

Default value is StringMutator.DEFAULT_NAUGHTY_STRINGS.

The StringMutator.DEFAULT_NAUGHTY_STRINGS default value is the following:

DEFAULT_NAUGHTY_STRINGS = [
      'System("ls -al /")',
      '`ls -al /`',
      'Kernel.exec("ls -al /")',
      'Kernel.exit(1)',
      '%x("ls -al /")',
      '<img \\x00src=x onerror="alert(1)">',
      '$ENV{"HOME"}',
      '%d',
      '%s']

Raw options:

Option

Description

interval

The scope of values to generate.

  • If set to FuzzingInterval.DEFAULT_INTERVAL, the values will be randomly generated with a size between the min and max values of the domain.

  • If set to FuzzingInterval.FULL_INTERVAL, the values will be randomly generated with a size of [0, 2^N-1], where N is the length in bits of the integer used to represent the Raw data length.

  • If it is a tuple of integers (min, max), the values will be randomly generated with a size between min and max.

Default value is FuzzingInterval.FULL_INTERVAL.

lengthBitSize

The size in bits of the memory on which the generated length will be encoded. This parameter should be used in conjunction with FuzzingInterval.FULL_INTERVAL or with a tuple interval, in order to generate Raw data with a length bigger than the original full interval. This parameter will not have any effect when used with FuzzingInterval.DEFAULT_INTERVAL.

The following sizes are available:

  • None (default value), which indicates to use the unit size set in the field domain.

  • UnitSize.SIZE_1

  • UnitSize.SIZE_4

  • UnitSize.SIZE_8

  • UnitSize.SIZE_16

  • UnitSize.SIZE_24

  • UnitSize.SIZE_32

  • UnitSize.SIZE_64

HexaString options:

Option

Description

interval

The scope of values to generate.

  • If set to FuzzingInterval.DEFAULT_INTERVAL, the values will be randomly generated with a size between the min and max values of the domain.

  • If set to FuzzingInterval.FULL_INTERVAL, the values will be randomly generated with a size of [0, 2^N-1], where N is the length in bits of the integer used to represent the HexaString length.

  • If it is a tuple of integers (min, max), the values will be randomly generated with a size between min and max.

Default value is FuzzingInterval.FULL_INTERVAL.

lengthBitSize

The size in bits of the memory on which the generated length will be encoded. This parameter should be used in conjunction with FuzzingInterval.FULL_INTERVAL or with a tuple interval, in order to generate HexaStrings with a length bigger than the original full interval. This parameter will not have any effect when used with FuzzingInterval.DEFAULT_INTERVAL.

The following sizes are available:

  • None (default value), which indicates to use the unit size set in the field domain.

  • UnitSize.SIZE_1

  • UnitSize.SIZE_4

  • UnitSize.SIZE_8

  • UnitSize.SIZE_16

  • UnitSize.SIZE_24

  • UnitSize.SIZE_32

  • UnitSize.SIZE_64

BitArray options:

Option

Description

interval

The scope of values to generate.

  • If set to FuzzingInterval.DEFAULT_INTERVAL, the values will be randomly generated with a size between the min and max values of the domain.

  • If set to FuzzingInterval.FULL_INTERVAL, the values will be randomly generated with a size of [0, 2^N-1], where N is the length in bits of the integer used to represent the BitArray length.

  • If it is a tuple of integers (min, max), the values will be randomly generated with a size between min and max.

Default value is FuzzingInterval.FULL_INTERVAL.

lengthBitSize

The size in bits of the memory on which the generated length will be encoded. This parameter should be used in conjunction with FuzzingInterval.FULL_INTERVAL or with a tuple interval, in order to generate BitArrays with a length bigger than the original full interval. This parameter will not have any effect when used with FuzzingInterval.DEFAULT_INTERVAL.

The following sizes are available:

  • None (default value), which indicates to use the unit size set in the field domain.

  • UnitSize.SIZE_1

  • UnitSize.SIZE_4

  • UnitSize.SIZE_8

  • UnitSize.SIZE_16

  • UnitSize.SIZE_24

  • UnitSize.SIZE_32

  • UnitSize.SIZE_64

Timestamp options:

Option

Description

No option

IPv4 options:

Option

Description

No option

Alt options:

Option

Description

mutateChild

If True, the children variables will also be fuzzed.

Default value is True.

mappingTypesMutators

A dict used to override the global default mapping of types with their default mutators.

Default value is {}.

maxDepth

An int used to limit the recursive calls to the mutator.

Default value is AltMutator.DEFAULT_MAX_DEPTH = 20

Agg options:

Option

Description

mutateChild

If True, the children variables will also be fuzzed.

Default value is True.

mappingTypesMutators

A dict used to override the global default mapping of types with their default mutators.

Default value is {}.

Repeat options:

Option

Description

mutateChild

If True, the children variables will also be fuzzed.

Default value is True.

mappingTypesMutators

A dict used to override the global default mapping of types with their default mutators.

Default value is {}.

interval

The scope of values to generate.

  • If set to FuzzingInterval.DEFAULT_INTERVAL, the values will be randomly generated with a size between the min and max values of the domain.

  • If set to FuzzingInterval.FULL_INTERVAL, the values will be randomly generated with a size of [0, 2^N-1], where N is the length in bits of the integer used to represent the number of repetitions.

  • If it is a tuple of integers (min, max), the values will be randomly generated with a size between min and max.

Default value is FuzzingInterval.FULL_INTERVAL.

lengthBitSize

The size in bits of the memory on which the generated length will be encoded. This parameter should be used in conjunction with FuzzingInterval.FULL_INTERVAL or with a tuple interval, in order to generate a Repeat with a length bigger than the original full interval. This parameter will not have any effect when used with FuzzingInterval.DEFAULT_INTERVAL.

The following sizes are available:

  • None (default value), which indicates to use the unit size set in the field domain.

  • UnitSize.SIZE_1

  • UnitSize.SIZE_4

  • UnitSize.SIZE_8

  • UnitSize.SIZE_16

  • UnitSize.SIZE_24

  • UnitSize.SIZE_32

  • UnitSize.SIZE_64

Optional options:

Option

Description

mutateChild

If True, the children variable will also be fuzzed.

Default value is True.

mappingTypesMutators

A dict used to override the global default mapping of types with their default mutators.

Default value is {}.

Values produced by the determinist generator

Considering a data field whose length allows to store an N bits integer (signed or unsigned) with an interval ranging from P to Q inclusive, the determinist generator will produce the following integer values:

  • Q

  • P

  • P - 1

  • Q - 1

  • P + 1

  • Q + 1

  • 0

  • -1

  • 1

  • for k in [0..N-2]:

    • -2^k

    • -2^k - 1

    • -2^k + 1

    • 2^k

    • 2^k - 1

    • 2^k + 1

Simple fuzzing example

>>> from netzob.all import *
>>> f_data = Field(domain=int8())
>>> symbol = Symbol(fields=[f_data])
>>> preset = Preset(symbol)
>>> preset.fuzz(f_data)
>>> next(symbol.specialize(preset))
b'\x00'

Fuzzing example of a field that contains an integer

>>> from netzob.all import *
>>> f_data = Field(name="data", domain=int16(interval=(1, 4)))
>>> symbol = Symbol(name="sym", fields=[f_data])
>>> preset = Preset(symbol)
>>> preset.fuzz(f_data, interval=(20, 32000))
>>> next(symbol.specialize(preset))
b'U*'

Fuzzing example of a field that contains a size relationship with another field

>>> from netzob.all import *
>>> f_data = Field(name="data", domain=int16(3))
>>> f_size = Field(name="size", domain=Size([f_data], Integer(unitSize=UnitSize.SIZE_16)))
>>> symbol = Symbol(name="sym", fields=[f_data, f_size])
>>> preset = Preset(symbol)
>>> preset.fuzz(f_size, interval=(20, 32000))
>>> next(symbol.specialize(preset))
b'\x00\x03U*'

Fuzzing example in mutation mode of a field that contains an integer

>>> from netzob.all import *
>>> f_data = Field(name="data", domain=int16(2))
>>> symbol = Symbol(name="sym", fields=[f_data])
>>> preset = Preset(symbol)
>>> preset.fuzz(f_data, mode=FuzzingMode.MUTATE, interval=(20, 32000))
>>> res = next(symbol.specialize(preset))
>>> res != b'\x00\x02'
True

Multiple fuzzing call on the same symbol

>>> from netzob.all import *
>>> f_data = Field(name="data", domain=int16(2))
>>> symbol = Symbol(name="sym", fields=[f_data])
>>> preset = Preset(symbol)
>>> preset.fuzz(f_data, interval=(20, 30000))
>>> nbFuzz = 1000
>>> result = set()
>>> for i in range(nbFuzz):
...     result.add(next(symbol.specialize(preset)))
>>> len(result) == 1000
True

Fuzzing of a field that contains sub-fields

>>> from netzob.all import *
>>> f_data1 = Field(name="data1", domain=int8())
>>> f_data2 = Field(name="data2", domain=int16())
>>> f_parent = Field(name="parent", domain=[f_data1, f_data2])
>>> symbol = Symbol(name="sym", fields=[f_parent])
>>> preset = Preset(symbol)
>>> preset.fuzz(f_parent)
>>> next(symbol.specialize(preset))
b'\x00\x00\x00'

Fuzzing of a whole symbol, and covering all field storage spaces with default fuzzing strategy per types

>>> from netzob.all import *
>>> f_data1 = Field(name="data1", domain=int8(interval=(2, 4)))
>>> f_data2 = Field(name="data2", domain=int8(interval=(5, 8)))
>>> symbol = Symbol(name="sym", fields=[f_data1, f_data2])
>>> preset = Preset(symbol)
>>> preset.fuzz(symbol, interval=FuzzingInterval.FULL_INTERVAL)
>>> next(symbol.specialize(preset))
b'\x00\x00'

Fuzzing and covering full storage space of a field

>>> from netzob.all import *
>>> f_data1 = Field(name="data1", domain=int8(2))
>>> f_data2 = Field(name="data2", domain=int8(interval=(10, 20)))
>>> symbol = Symbol(name="sym", fields=[f_data1, f_data2])
>>> preset = Preset(symbol)
>>> preset.fuzz(f_data2, interval=FuzzingInterval.FULL_INTERVAL)
>>> next(symbol.specialize(preset))
b'\x02\x00'

Fuzzing and covering full storage space of a field, after redefining its storage space from 8 to 16 bits

>>> from netzob.all import *
>>> f_data1 = Field(name="data1", domain=int8(2))
>>> f_data2 = Field(name="data2", domain=int8(interval=(10, 20)))
>>> symbol = Symbol(name="sym", fields=[f_data1, f_data2])
>>> preset = Preset(symbol)
>>> preset.fuzz(f_data2, interval=FuzzingInterval.FULL_INTERVAL, lengthBitSize=UnitSize.SIZE_16)
>>> next(symbol.specialize(preset))
b'\x02\x00\x00'

Fuzzing and changing the default fuzzing parameters for types

>>> from netzob.all import *
>>> f_data1 = Field(name="data1", domain=int8(2))
>>> f_data2 = Field(name="data2", domain=int8(4))
>>> symbol = Symbol(name="sym", fields=[f_data1, f_data2])
>>> preset = Preset(symbol)
>>> preset.fuzz(Integer, interval=(10, 12))
>>> preset.fuzz(symbol)
>>> next(symbol.specialize(preset))
b'\x0c\x0c'

Fuzzing of an aggregate of variables with non-default types/mutators mapping

In this example, we use a determinist integer mutator instead of the pseudo-random integer mutator used by default for integer fuzzing.

>>> from netzob.Fuzzing.Mutators.IntegerMutator import IntegerMutator
>>> f_agg = Field(name="agg", domain=Agg([int16(interval=(1, 4)),
...                                       int16(interval=(5, 8))]))
>>> symbol = Symbol(name="sym", fields=[f_agg])
>>> preset = Preset(symbol)
>>> mapping = {}
>>> mapping[Integer] = {'generator':'determinist'}
>>> preset.fuzz(f_agg, mappingTypesMutators=mapping)
>>> res = next(symbol.specialize(preset))
>>> res
b' \x01 \x01'

Fuzzing of an alternate of variables with non-default types/mutators mapping

In this example, we use a determinist integer mutator instead of the pseudo-random integer mutator used by default for integer fuzzing.

>>> from netzob.Fuzzing.Mutators.IntegerMutator import IntegerMutator
>>> f_alt = Field(name="alt", domain=Alt([int16(interval=(1, 4)),
...                                       int16(interval=(5, 8))]))
>>> symbol = Symbol(name="sym", fields=[f_alt])
>>> preset = Preset(symbol)
>>> mapping = {}
>>> mapping[Integer] = {'generator':'determinist'}
>>> preset.fuzz(f_alt, mappingTypesMutators=mapping)
>>> res = next(symbol.specialize(preset))
>>> res
b' \x01'

Fuzzing of an aggregate of variables without fuzzing the children

>>> f_agg = Field(name="agg", domain=Agg([int8(interval=(1, 4)),
...                                       int8(interval=(5, 8))]))
>>> symbol = Symbol(name="sym", fields=[f_agg])
>>> preset = Preset(symbol)
>>> preset.fuzz(f_agg, mutateChild=False)
>>> res = next(symbol.specialize(preset))
>>> 1 <= res[0] <= 4
True
>>> 5 <= res[1] <= 8
True

Fuzzing configuration with a global maximum number of mutations

>>> from netzob.all import *
>>> f_alt = Field(name="alt", domain=Alt([int8(interval=(1, 4)),
...                                       int8(interval=(5, 8))]))
>>> symbol = Symbol(name="sym", fields=[f_alt])
>>> preset = Preset(symbol)
>>> preset.setFuzzingCounterMax(1)
>>> preset.fuzz(f_alt)
>>> next(symbol.specialize(preset))
b'\x00'
>>> next(symbol.specialize(preset))
Traceback (most recent call last):
StopIteration

Fuzzing configuration with a maximum number of mutations, expressed with an absolute limit, on a symbol

>>> from netzob.all import *
>>> field = Field(Agg([uint8(), uint8()]))
>>> symbol = Symbol([field], name="sym")
>>> preset = Preset(symbol)
>>> symbol.count()
65536
>>> preset.fuzz(symbol, counterMax=80)
>>> idx = 0
>>> for data in symbol.specialize(preset):
...     # use data
...     idx += 1
>>> print(idx)
80

Fuzzing configuration with a maximum number of mutations, expressed with a ratio, on a symbol

>>> from netzob.all import *
>>> field = Field(Agg([uint8(), uint8()]))
>>> symbol = Symbol([field], name="sym")
>>> preset = Preset(symbol)
>>> symbol.count()
65536
>>> int(symbol.count() * 0.001)
65
>>> preset.fuzz(symbol, counterMax=0.001)
>>> idx = 0
>>> for data in symbol.specialize(preset):
...     # use data
...     idx += 1
>>> print(idx)
65
>>> preset = Preset(symbol)  # This is needed to restore counterMax default value for unit test purpose
Preset.setFuzzingCounterMax(counterMax: netzob.Model.Vocabulary.Types.Integer.Integer)[source]#

Set the default value for the maximum number of mutations to produce in the context of the Preset instance. A int should be used to represent an absolute value, whereas a float should be used to represent a ratio in percent.

The default maximum value is COUNTER_MAX_DEFAULT = 2**32

Parameters

counterMax (int or float, required) – the maximum number of mutations to produce.

Preset.getFuzzingCounterMax()[source]#

Return the default value for the maximum number of mutations to produce in the context of the Preset instance. A int should be used to represent an absolute value, whereas a float should be used to represent a ratio in percent.

Returns

the maximum number of mutations to produce.

Return type

int or float

Preset.unset(key)[source]#

The unset method deactivates the fixed value or the fuzzing strategy for a symbol, a field or a variable. It is not possible to unset the fuzzing on a type.

The unset method expects some parameters:

Parameters

key (Field, or Symbol, or Variable, required) – The targeted object (either a symbol, a field or a variable).

Example of fuzzing of a whole symbol except one field:

>>> from netzob.all import *
>>> f_data1 = Field(name="data1", domain=int8(2))
>>> f_data2 = Field(name="data2", domain=int8(4))
>>> symbol = Symbol(name="sym", fields=[f_data1, f_data2])
>>> preset = Preset(symbol)
>>> preset.fuzz(symbol, interval=FuzzingInterval.FULL_INTERVAL)
>>> preset.unset(f_data2)
>>> next(symbol.specialize(preset))
b'\x00\x04'