Protocol Overview
See the Quickstart guide for an intro to using Fuzzungus 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"),
))
Making Your Own Block/Primitive
To make your own block/primitive:
Create an object that inherits from
FuzzableorFuzzableBlock- Add it to the _init.py_ files :
- In the primitives or blocks folder :
Import it : from .$primitiveName import $PrimitiveName
Add it in the __all__ table
- In the boofuzz folder :
In the from .primitives import ()
In the __all__ table as $PrimitiveName
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, *args, **kwargs)[source]
Bases:
objectParent 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 from
mutations()or default_value.FuzzableBlocktypes can also encode the data generatedby 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
- 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:
FuzzableFuzzable 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
Flagging blocks/primitives as depreciated
Depending of Fuzzungus evolution, you may need to flag some blocks/primitives as depreciated. To do so, here are two methods.
First method with the warnings package
import warnings
warnings.warn('setDaemon() is deprecated, set the daemon attribute instead',DeprecationWarning, stacklevel=2)
Second method with the deprecated package
from deprecated import deprecated
@deprecated(version='x.x.x', reason="Use YourClass instead")
See Deprecated - PyPi.