Fuzzing Message Format
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
andOpt
) with themutateChild
parameter. Besides, it is possible to specifically deactivate fuzzing on a object with theunset
method.The
fuzz
method expects some parameters:- Parameters
key (
Field
, orSymbol
, orVariable
, orAbstractType
, 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
. TheMutator.SEED_DEFAULT
constant is initialized from the configuration variableConf.seed
from the Netzob APIConf
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 ofString
.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 withFuzzingInterval.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 dangerousstr
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 withFuzzingInterval.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 withFuzzingInterval.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 withFuzzingInterval.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 withFuzzingInterval.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 fromP
toQ
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 afloat
should be used to represent a ratio in percent.The default maximum value is
COUNTER_MAX_DEFAULT
=2**32
- Parameters
counterMax (
int
orfloat
, 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 afloat
should be used to represent a ratio in percent.- Returns
the maximum number of mutations to produce.
- Return type
int
orfloat
- 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
, orSymbol
, orVariable
, 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'