Protocol Definition
For the old school Spike-style static protocol definition format, see static protocol definition functions. The non-static protocol definition described here is the newer (but still somewhat experimental) approach.
See the Quickstart guide for an intro to using boofuzz in general and a basic protocol definition example.
Overview
Requests are messages, Blocks are chunks within a message, and Primitives are the elements (bytes, strings, numbers, checksums, etc.) that make up a Block/Request.
Example
Here is an example of an HTTP message. It demonstrates how to use Request, Block, and several primitives:
req = Request("HTTP-Request",children=(
Block("Request-Line", children=(
Group("Method", values= ["GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE"]),
Delim("space-1", " "),
String("URI", "/index.html"),
Delim("space-2", " "),
String("HTTP-Version", "HTTP/1.1"),
Static("CRLF", "\r\n"),
)),
Block("Host-Line", children=(
String("Host-Key", "Host:"),
Delim("space", " "),
String("Host-Value", "example.com"),
Static("CRLF", "\r\n"),
)),
Static("CRLF", "\r\n"),
))
Request
- boofuzz.Request(name=None, children=None)[source]
Top level container. Can hold any block structure or primitive.
This can essentially be thought of as a super-block, root-block, daddy-block or whatever other alias you prefer.
- Parameters:
name (str, optional) – Name of this request
children (boofuzz.Fuzzable, optional) – Children of this request, defaults to None
Blocks
Block
- boofuzz.Block(name=None, default_value=None, request=None, children=None, group=None, encoder=None, dep=None, dep_value=None, dep_values=None, dep_compare='==', *args, **kwargs)[source]
The basic building block. Can contain primitives, sizers, checksums or other blocks.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (Any, optional) – Value used when the element is not being fuzzed - should typically represent a valid value, defaults to None
request (boofuzz.Request, optional) – Request this block belongs to, defaults to None
children (boofuzz.Fuzzable, optional) – Children of this block, defaults to None
group (str, optional) – Name of group to associate this block with, defaults to None
encoder (callable, optional) – Optional pointer to a function to pass rendered data to prior to return, defaults to None
dep (str, optional) – Optional primitive whose specific value this block is dependant on, defaults to None
dep_value (bytes, optional) – Value that field “dep” must contain for block to be rendered, defaults to None
dep_values (list, optional) – Values that field “dep” may contain for block to be rendered, defaults to None
dep_compare (str, optional) – Comparison method to apply to dependency (==, !=, >, >=, <, <=), defaults to None
Checksum
- boofuzz.Checksum(name=None, block_name=None, request=None, algorithm='crc32', length=0, endian='<', ipv4_src_block_name=None, ipv4_dst_block_name=None, *args, **kwargs)[source]
Checksum bound to the block with the specified name.
The algorithm may be chosen by name with the algorithm parameter, or a custom function may be specified with the algorithm parameter.
The length field is only necessary for custom algorithms. When using your own custom checksum function, the return value should be the calculated checksum of the data.
Function signature: <function_name>(data_bytes). Returns a number represented as a bytes type.
Recursive checksums are supported; the checksum field itself will render as all zeros for the sake of checksum or length calculations.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
block_name (str) – Name of target block for checksum calculations.
request (boofuzz.Request, optional) – Request this block belongs to
algorithm (str, function def name, optional) – Checksum algorithm to use from this list, default is crc32 (crc32, crc32c, adler32, md5, sha1, ipv4, udp). See above for custom checksum function example.
length (int, optional) – Length of checksum, auto-calculated by default. Must be specified manually when using custom algorithm, defaults to 0
endian (chr, optional) – Endianness of the bit field (LITTLE_ENDIAN: <, BIG_ENDIAN: >), defaults to LITTLE_ENDIAN
ipv4_src_block_name (str, optional) – Required for ‘udp’ algorithm. Name of block yielding IPv4 source address, defaults to None
ipv4_dst_block_name (str, optional) – Required for ‘udp’ algorithm. Name of block yielding IPv4 destination address, defaults to None
fuzzable (bool, optional) – Enable/disable fuzzing of this block, defaults to true
Repeat
- boofuzz.Repeat(name=None, block_name=None, request=None, min_reps=0, max_reps=25, step=1, variable=None, default_value=None, *args, **kwargs)[source]
Repeat the rendered contents of the specified block cycling from min_reps to max_reps counting by step.
By default renders to nothing. This block modifier is useful for fuzzing overflows in table entries. This block modifier MUST come after the block it is being applied to.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
block_name (str, optional) – Name of block to repeat
request (boofuzz.Request, optional) – Request this block belongs to, defaults to None
min_reps (int, optional) – Minimum number of block repetitions, defaults to 0
max_reps (int, optional) – Maximum number of block repetitions, defaults to None
step (int, optional) – Step count between min and max reps, defaults to 1
variable (Boofuzz Integer Primitive, optional) – Repetitions will be derived from this variable, disables fuzzing, defaults to None
default_value (Raw) – Value used when the element is not being fuzzed - should typically represent a valid value, defaults to None
fuzzable (bool, optional) – Enable/disable fuzzing of this block, defaults to true
Size
- boofuzz.Size(name=None, block_name=None, request=None, offset=0, length=4, endian='<', output_format='binary', inclusive=False, signed=False, math=None, *args, **kwargs)[source]
Create a sizer block bound to the block with the specified name.
Size blocks that size their own parent or grandparent are allowed.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
block_name (str, optional) – Name of block to apply sizer to.
request (boofuzz.Request, optional) – Request this block belongs to.
offset (int, optional) – Offset for calculated size value, defaults to 0
length (int, optional) – Length of sizer, defaults to 4
endian (chr, optional) – Endianness of the bit field (LITTLE_ENDIAN: <, BIG_ENDIAN: >), defaults to LITTLE_ENDIAN
output_format (str, optional) – Output format, “binary” or “ascii”, defaults to binary
inclusive (bool, optional) – Should the sizer count its own length? Defaults to False
signed (bool, optional) – Make size signed vs. unsigned (applicable only with format=”ascii”), defaults to False
math (def, optional) – Apply the mathematical op defined in this function to the size, defaults to None
fuzzable (bool, optional) – Enable/disable fuzzing of this block, defaults to true
Aligned
- boofuzz.Aligned(name=None, modulus=1, request=None, pattern=b'\x00', *args, **kwargs)[source]
FuzzableBlock that aligns its contents to a certain number of bytes
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
modulus (int, optional) – Pad length of child content to this many bytes, defaults to 1
request (boofuzz.Request, optional) – Request this block belongs to
pattern (bytes, optional) – Pad using these byte(s)
fuzzable (bool, optional) – Enable/disable fuzzing of this block, defaults to true
Primitives
Static
- boofuzz.Static(name=None, default_value=None, *args, **kwargs)[source]
Static primitives are fixed and not mutated while fuzzing.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (Raw, optional) – Raw static data
Simple
- boofuzz.Simple(name=None, default_value=None, fuzz_values=None, *args, **kwargs)[source]
Simple bytes value with manually specified fuzz values only.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (Raw, optional) – Raw static data
fuzz_values (list, optional) – List of fuzz values, defaults to None. If empty, Simple is equivalent to Static.
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
Delim
- boofuzz.Delim(name=None, default_value=' ', *args, **kwargs)[source]
Represent a delimiter such as :,r,n, ,=,>,< etc… Mutations include repetition, substitution and exclusion.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (char, optional) – Value used when the element is not being fuzzed - should typically represent a valid value.
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
Group
- boofuzz.Group(name=None, values=None, default_value=None, encoding='ascii', *args, **kwargs)[source]
This primitive represents a list of static values, stepping through each one on mutation.
You can tie a block to a group primitive to specify that the block should cycle through all possible mutations for each value within the group. The group primitive is useful for example for representing a list of valid opcodes.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
values (list of bytes or list of str) – List of possible raw values this group can take.
default_value (str, optional) – Value used when the element is not being fuzzed - should typically represent a valid value, defaults to None
encoding (str, optional) – String encoding, ex: utf_16_le for Microsoft Unicode, defaults to ascii
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
RandomData
- boofuzz.RandomData(name=None, default_value='', min_length=0, max_length=1, max_mutations=25, step=None, *args, **kwargs)[source]
Generate a random chunk of data while maintaining a copy of the original.
A random length range can be specified. For a static length, set min/max length to be the same.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (str or bytes, optional) – Value used when the element is not being fuzzed - should typically represent a valid value, defaults to None
min_length (int, optional) – Minimum length of random block, defaults to 0
max_length (int, optional) – Maximum length of random block, defaults to 1
max_mutations (int, optional) – Number of mutations to make before reverting to default, defaults to 25
step (int, optional) – If not None, step count between min and max reps, otherwise random, defaults to None
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
String
- boofuzz.String(name=None, default_value='', size=None, padding=b'\x00', encoding='utf-8', max_len=None, *args, **kwargs)[source]
Primitive that cycles through a library of “bad” strings.
The class variable ‘fuzz_library’ contains a list of smart fuzz values global across all instances. The ‘this_library’ variable contains fuzz values specific to the instantiated primitive. This allows us to avoid copying the near ~70MB fuzz_library data structure across each instantiated primitive.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (str) – Value used when the element is not being fuzzed - should typically represent a valid value.
size (int, optional) – Static size of this field, leave None for dynamic, defaults to None
padding (chr, optional) – Value to use as padding to fill static field size, defaults to “x00”
encoding (str, optional) – String encoding, ex: utf_16_le for Microsoft Unicode, defaults to ascii
max_len (int, optional) – Maximum string length, defaults to None
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
FromFile
- boofuzz.FromFile(name=None, default_value=b'', filename=None, max_len=0, *args, **kwargs)[source]
Cycles through a list of “bad” values from a file(s).
Takes filename and open the file(s) to read the values to use in fuzzing process. filename may contain glob characters.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (bytes) – Default bytes value
filename (str) – Filename pattern to load all fuzz value
max_len (int, optional) – Maximum string length, defaults to 0
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
Mirror
- boofuzz.Mirror(name=None, primitive_name=None, request=None, *args, **kwargs)[source]
Primitive used to keep updated with another primitive.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
primitive_name (str) – Name of target primitive.
request (boofuzz.Request) – Request this primitive belongs to.
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
BitField
- boofuzz.BitField(name=None, default_value=0, width=8, max_num=None, endian='<', output_format='binary', signed=False, full_range=False, *args, **kwargs)[source]
The bit field primitive represents a number of variable length and is used to define all other integer types.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (int, optional) – Default integer value, defaults to 0
width (int, optional) – Width in bits, defaults to 8
max_num (int, optional) – Maximum number to iterate up to, defaults to None
endian (char, optional) – Endianness of the bit field (LITTLE_ENDIAN: <, BIG_ENDIAN: >), defaults to LITTLE_ENDIAN
output_format (str, optional) – Output format, “binary” or “ascii”, defaults to binary
signed (bool, optional) – Make size signed vs. unsigned (applicable only with format=”ascii”), defaults to False
full_range (bool, optional) – If enabled the field mutates through all possible values, defaults to False
fuzz_values (list, optional) – List of custom fuzz values to add to the normal mutations, defaults to None
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
Byte
- boofuzz.Byte(*args, **kwargs)[source]
The byte sized bit field primitive.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (int, optional) – Default integer value, defaults to 0
max_num (int, optional) – Maximum number to iterate up to, defaults to None
endian (char, optional) – Endianness of the bit field (LITTLE_ENDIAN: <, BIG_ENDIAN: >), defaults to LITTLE_ENDIAN
output_format (str, optional) – Output format, “binary” or “ascii”, defaults to binary
signed (bool, optional) – Make size signed vs. unsigned (applicable only with format=”ascii”), defaults to False
full_range (bool, optional) – If enabled the field mutates through all possible values, defaults to False
fuzz_values (list, optional) – List of custom fuzz values to add to the normal mutations, defaults to None
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
Bytes
- boofuzz.Bytes(name: str = None, default_value: bytes = b'', size: int = None, padding: bytes = b'\x00', max_len: int = None, *args, **kwargs)[source]
Primitive that fuzzes a binary byte string with arbitrary length.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (bytes, optional) – Value used when the element is not being fuzzed - should typically represent a valid value, defaults to b””
size (int, optional) – Static size of this field, leave None for dynamic, defaults to None
padding (chr, optional) – Value to use as padding to fill static field size, defaults to b”x00”
max_len (int, optional) – Maximum string length, defaults to None
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
Word
- boofuzz.Word(*args, **kwargs)[source]
The 2 byte sized bit field primitive.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (int, optional) – Default integer value, defaults to 0
max_num (int, optional) – Maximum number to iterate up to, defaults to None
endian (char, optional) – Endianness of the bit field (LITTLE_ENDIAN: <, BIG_ENDIAN: >), defaults to LITTLE_ENDIAN
output_format (str, optional) – Output format, “binary” or “ascii”, defaults to binary
signed (bool, optional) – Make size signed vs. unsigned (applicable only with format=”ascii”), defaults to False
full_range (bool, optional) – If enabled the field mutates through all possible values, defaults to False
fuzz_values (list, optional) – List of custom fuzz values to add to the normal mutations, defaults to None
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
DWord
- boofuzz.DWord(*args, **kwargs)[source]
The 4 byte sized bit field primitive.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (int, optional) – Default integer value, defaults to 0
max_num (int, optional) – Maximum number to iterate up to, defaults to None
endian (char, optional) – Endianness of the bit field (LITTLE_ENDIAN: <, BIG_ENDIAN: >), defaults to LITTLE_ENDIAN
output_format (str, optional) – Output format, “binary” or “ascii”, defaults to binary
signed (bool, optional) – Make size signed vs. unsigned (applicable only with format=”ascii”), defaults to False
full_range (bool, optional) – If enabled the field mutates through all possible values, defaults to False
fuzz_values (list, optional) – List of custom fuzz values to add to the normal mutations, defaults to None
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
QWord
- boofuzz.QWord(*args, **kwargs)[source]
The 8 byte sized bit field primitive.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (int, optional) – Default integer value, defaults to 0
max_num (int, optional) – Maximum number to iterate up to, defaults to None
endian (char, optional) – Endianness of the bit field (LITTLE_ENDIAN: <, BIG_ENDIAN: >), defaults to LITTLE_ENDIAN
output_format (str, optional) – Output format, “binary” or “ascii”, defaults to binary
signed (bool, optional) – Make size signed vs. unsigned (applicable only with format=”ascii”), defaults to False
full_range (bool, optional) – If enabled the field mutates through all possible values, defaults to False
fuzz_values (list, optional) – List of custom fuzz values to add to the normal mutations, defaults to None
fuzzable (bool, optional) – Enable/disable fuzzing of this primitive, defaults to true
Making Your Own Block/Primitive
Now I know what you’re thinking: “With that many sweet primitives and blocks available, what else could I ever conceivably need? And yet, I am urged by joy to contribute my own sweet blocks!”
To make your own block/primitive:
Create an object that inherits from
Fuzzable
orFuzzableBlock
Optional: Create an accompanying static primitive function. See boofuzz’s __init__.py file for examples.
???
Profit!
If your block depends on references to other blocks, the way a checksum or length field depends on other parts of the
message, see the Size
source code for an example of how to avoid recursion issues, and Be
Careful. :)
- class boofuzz.Fuzzable(name=None, default_value=None, fuzzable=True, fuzz_values=None)[source]
Bases:
object
Parent class for all primitives and blocks.
When making new fuzzable types, one will typically override
mutations()
and/orencode()
.mutations()
is a generator function yielding mutations, typically of type bytes.encode()
is a function that takes a value and encodes it. The value comes frommutations()
ordefault_value
.FuzzableBlock
types can also encode the data generated by child nodes.Implementors may also want to override
num_mutations()
– the default implementation manually exhaustsmutations()
to get a number.The rest of the methods are used by boofuzz to handle fuzzing and are typically not overridden.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
default_value (Any, optional) – Value used when the element is not being fuzzed - should typically represent a valid value. Can be a static value, or a ReferenceValueTestCaseSession, defaults to None
fuzzable (bool, optional) – Enable fuzzing of this primitive, defaults to True
fuzz_values (list, optional) – List of custom fuzz values to add to the normal mutations, defaults to None
- property context_path
Dot-delimited string that describes the path up to this element. Configured after the object is attached to a Request.
- encode(value, mutation_context)[source]
Takes a value and encodes/renders/serializes it to a bytes (byte string).
Optional if mutations() yields bytes.
Example: Yield strings with mutations() and encode them to UTF-8 using encode().
Default behavior: Return value.
- Parameters:
value – Value to encode. Type should match the type yielded by mutations()
mutation_context (MutationContext) – Context for current mutation, if any.
- Returns:
Encoded/serialized value.
- Return type:
bytes
- property fuzzable
If False, this element should not be mutated in normal fuzzing.
- get_mutations()[source]
Iterate mutations. Used by boofuzz framework.
- Yields:
list of Mutation – Mutations
- get_value(mutation_context=None)[source]
Helper method to get the currently applicable value.
This is either the default value, or the active mutation value as dictated by mutation_context.
- Parameters:
mutation_context (MutationContext) –
Returns:
- mutations(default_value)[source]
Generator to yield mutation values for this element.
Values are either plain values or callable functions that take a “default value” and mutate it. Functions are used when the default or “normal” value influences the fuzzed value. Functions are used because the “normal” value is sometimes dynamic and not known at the time of generation.
Each mutation should be a pre-rendered value. That is, it must be suitable to pass to encode().
Default: Empty iterator.
- Parameters:
default_value –
- property name
Element name, should be unique for each instance.
- Return type:
str
- name_counter = 0
- num_mutations(default_value)[source]
Return the total number of mutations for this element (not counting “fuzz_values”).
Default implementation exhausts the mutations() generator, which is inefficient. Override if you can provide a value more efficiently, or if exhausting the mutations() generator has side effects.
- Parameters:
default_value – Use if number of mutations depends on the default value. Provided by FuzzableWrapper. Note: It is generally good behavior to have a consistent number of mutations for a given default value length.
- Returns:
Number of mutated forms this primitive can take
- Return type:
int
- original_value(test_case_context=None)[source]
Original, non-mutated value of element.
- Parameters:
test_case_context (ProtocolSession) – Used to resolve ReferenceValueTestCaseSession type default values.
Returns:
- property qualified_name
Dot-delimited name that describes the request name and the path to the element within the request.
Example: “request1.block1.block2.node1”
- render(mutation_context=None)[source]
Render after applying mutation, if applicable. :type mutation_context: MutationContext
- property request
Reference to the Request to which this object is attached.
- stop_mutations()[source]
Stop yielding mutations on the currently running
mutations()
call.Used by boofuzz to stop fuzzing an element when it’s already caused several failures.
- Returns:
None
- Return type:
NoneType
- class boofuzz.FuzzableBlock(name=None, request=None, children=None, *args, **kwargs)[source]
Bases:
Fuzzable
Fuzzable type designed to have children elements.
FuzzableBlock overrides the following methods, changing the default behavior for any type based on FuzzableBlock:
mutations()
Iterate through the mutations yielded by all child nodes.num_mutations()
Sum the mutations represented by each child node.encode()
Callget_child_data()
.
FuzzableBlock adds the following methods:
get_child_data()
Render and concatenate all child nodes.push()
Add an additional child node; generally used only internally.
- Parameters:
name (str, optional) – Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None
request (boofuzz.Request, optional) – Request this block belongs to, defaults to None
children (boofuzz.Fuzzable, optional) – List of child nodes (typically given to FuzzableBlock types)m defaults to None
- encode(value, mutation_context)[source]
Takes a value and encodes/renders/serializes it to a bytes (byte string).
Optional if mutations() yields bytes.
Example: Yield strings with mutations() and encode them to UTF-8 using encode().
Default behavior: Return value.
- Parameters:
value – Value to encode. Type should match the type yielded by mutations()
mutation_context (MutationContext) – Context for current mutation, if any.
- Returns:
Encoded/serialized value.
- Return type:
bytes
- get_child_data(mutation_context)[source]
Get child or referenced data for this node.
For blocks that reference other data from the message structure (e.g. size, checksum, blocks). See FuzzableBlock for an example.
- Parameters:
mutation_context (MutationContext) – Mutation context.
- Returns:
Child data.
- Return type:
bytes
- mutations(default_value, skip_elements=None)[source]
Generator to yield mutation values for this element.
Values are either plain values or callable functions that take a “default value” and mutate it. Functions are used when the default or “normal” value influences the fuzzed value. Functions are used because the “normal” value is sometimes dynamic and not known at the time of generation.
Each mutation should be a pre-rendered value. That is, it must be suitable to pass to encode().
Default: Empty iterator.
- Parameters:
default_value –
- num_mutations(default_value=None)[source]
Return the total number of mutations for this element (not counting “fuzz_values”).
Default implementation exhausts the mutations() generator, which is inefficient. Override if you can provide a value more efficiently, or if exhausting the mutations() generator has side effects.
- Parameters:
default_value – Use if number of mutations depends on the default value. Provided by FuzzableWrapper. Note: It is generally good behavior to have a consistent number of mutations for a given default value length.
- Returns:
Number of mutated forms this primitive can take
- Return type:
int