Monitors
Monitors are components that monitor the target for specific behaviour. A monitor can be passive and just observe and provide data or behave more actively, interacting directly with the target. Some monitors also have the capability to start, stop and restart targets.
Detecting a crash or misbehaviour of your target can be a complex, non-straight forward process depending on the tools you have available on your targets host; this holds true especially for embedded devices. Boofuzz provides three main monitor implementations:
ProcessMonitor
, a Monitor that collects debug info from process on Windows and Unix. It also can restart the target process and detect segfaults.NetworkMonitor
, a Monitor that passively captures network traffic via PCAP and attaches it to the testcase log.CallbackMonitor
, which is used to implement the callbacks that can be supplied to the Session class.
Monitor Interface (BaseMonitor)
- class boofuzz.monitors.BaseMonitor[source]
Bases:
object
Interface for Target monitors. All Monitors must adhere to this specification.
New in version 0.2.0.
- alive()[source]
Called when a Target containing this Monitor is added to a session. Use this function to connect to e.g. RPC hosts if your target lives on another machine.
You MUST return True if the monitor is alive. You MUST return False otherwise. If a Monitor is not alive, this method will be called until it becomes alive or throws an exception. You SHOULD handle timeouts / connection retry limits in the monitor implementation.
Defaults to return True.
- Returns:
Bool
- get_crash_synopsis()[source]
Called if any monitor indicates that the current testcase has failed, even if this monitor did not detect a crash. You SHOULD return a human- readable representation of the crash synopsis (e.g. hexdump). You MAY save the full crashdump somewhere.
- Returns:
str
- post_send(target=None, fuzz_data_logger=None, session=None)[source]
Called after the current fuzz node is transmitted. Use it to collect data about a target and decide whether it crashed.
You MUST return True if the Target is still alive. You MUST return False if the Target crashed. If one Monitor reports a crash, the whole testcase will be marked as crashing.
Defaults to return True.
- Returns:
Bool
- post_start_target(target=None, fuzz_data_logger=None, session=None)[source]
Called after a target is started or restarted.
- pre_send(target=None, fuzz_data_logger=None, session=None)[source]
Called before the current fuzz node is transmitted.
Defaults to no effect.
- Returns:
None
- restart_target(target=None, fuzz_data_logger=None, session=None)[source]
Restart a target. Must return True if restart was successful, False if it was unsuccessful or this monitor cannot restart a Target, which causes the next monitor in the chain to try to restart.
The first successful monitor causes the restart chain to stop applying.
Defaults to call stop and start, return True if successful.
- Returns:
Bool
- retrieve_data()[source]
Called to retrieve data independent of whether the current fuzz node crashed the target or not. Called before the fuzzer proceeds to a new testcase.
You SHOULD return any auxiliary data that should be recorded. The data MUST be serializable, e.g. bytestring.
Defaults to return None.
- set_options(*args, **kwargs)[source]
Called to set options for your monitor (e.g. local crash dump storage). *args and **kwargs can be explicitly specified by implementing classes, however you SHOULD ignore any kwargs you do not recognize.
Defaults to no effect.
- Returns:
None
ProcessMonitor
The process monitor consists of two parts; the ProcessMonitor
class that implements
BaseMonitor
and a second module that is to be run on the host of your target.
- class boofuzz.monitors.ProcessMonitor(host, port)[source]
Proxy class for the process monitor interface.
In Versions < 0.2.0, boofuzz had network and process monitors that communicated over RPC. The RPC client was directly passed to the session class, and resolved all method calls dynamically on the RPC partner.
Since 0.2.0, every monitor class must implement the abstract class BaseMonitor, which defines a common interface among all Monitors. To aid future typehinting efforts and to disambiguate Network- and Process Monitors, this explicit proxy class has been introduced that fast-forwards all calls to the RPC partner.
New in version 0.2.0.
- on_new_server(new_uuid)[source]
Restores all set options to the RPC daemon if it has restarted since the last call.
- post_send(target=None, fuzz_data_logger=None, session=None)[source]
This method is forwarded to the RPC daemon.
- pre_send(target=None, fuzz_data_logger=None, session=None)[source]
This method is forwarded to the RPC daemon.
- restart_target(target=None, fuzz_data_logger=None, session=None)[source]
This method is forwarded to the RPC daemon.
- set_crash_filename(new_crash_filename)[source]
Deprecated since version 0.2.0.
This option should be set via
set_options
.
- set_options(*args, **kwargs)[source]
The old RPC interfaces specified set_foobar methods to set options. As these vary by RPC implementation, this trampoline method translates arguments that have been passed as keyword arguments to set_foobar calls.
If you call
set_options(foobar="barbaz")
, it will result in a call toset_foobar("barbaz")
on the RPC partner.
- set_proc_name(new_proc_name)[source]
Deprecated since version 0.2.0.
This option should be set via
set_options
.
- set_start_commands(new_start_commands)[source]
Deprecated since version 0.2.0.
This option should be set via
set_options
.
NetworkMonitor
The network monitor consists of two parts; the NetworkMonitor
class that implements
BaseMonitor
and a second module that is to be run on a host that can monitor the traffic.
- class boofuzz.monitors.NetworkMonitor(host, port)[source]
Proxy class for the network monitor interface.
In Versions < 0.2.0, boofuzz had network and process monitors that communicated over RPC. The RPC client was directly passed to the session class, and resolved all method calls dynamically on the RPC partner.
Since 0.2.0, every monitor class must implement the abstract class BaseMonitor, which defines a common interface among all Monitors. To aid future typehinting efforts and to disambiguate Network- and Process Monitors, this explicit proxy class has been introduced that fast-forwards all calls to the RPC partner.
New in version 0.2.0.
- on_new_server(new_uuid)[source]
Restores all set options to the RPC daemon if it has restarted since the last call.
- post_send(target=None, fuzz_data_logger=None, session=None)[source]
This method is forwarded to the RPC daemon.
- pre_send(target=None, fuzz_data_logger=None, session=None)[source]
This method is forwarded to the RPC daemon.
- restart_target(target=None, fuzz_data_logger=None, session=None)[source]
Always returns false as this monitor cannot restart a target.
- set_filter(new_filter)[source]
Deprecated since version 0.2.0.
This option should be set via
set_options
.
- set_log_path(new_log_path)[source]
Deprecated since version 0.2.0.
This option should be set via
set_options
.
- set_options(*args, **kwargs)[source]
The old RPC interfaces specified set_foobar methods to set options. As these vary by RPC implementation, this trampoline method translates arguments that have been passed as keyword arguments to set_foobar calls.
If you call
set_options(foobar="barbaz")
, it will result in a call toset_foobar("barbaz")
on the RPC partner.Additionally, any options set here are cached and re-applied to the RPC server should it restart for whatever reason (e.g. the VM it’s running on was restarted).
CallbackMonitor
- class boofuzz.monitors.CallbackMonitor(on_pre_send=None, on_post_send=None, on_restart_target=None, on_post_start_target=None)[source]
New-Style Callback monitor that is used in Session to provide callback-arrays. It’s purpose is to keep the *_callbacks arguments in the session class while simplifying the implementation of session by forwarding these callbacks to the monitor infrastructure.
The mapping of arguments to method implementations of this class is as follows:
restart_callbacks –> target_restart
pre_send_callbacks –> pre_send
post_test_case_callbacks –> post_send
post_start_target_callbacks –> post_start_target
All other implemented interface members are stubs only, as no corresponding arguments exist in session. In any case, it is probably wiser to implement a custom Monitor than to use the callback functions.
New in version 0.2.0.
- post_send(target=None, fuzz_data_logger=None, session=None)[source]
This method iterates over all supplied post send callbacks and executes them. Their return values are discarded, exceptions are caught and logged:
BoofuzzTargetConnectionReset
will log a failureBoofuzzTargetConnectionAborted
will log an infoBoofuzzTargetConnectionFailedError
will log a failureBoofuzzSSLError
will log either info or failure, depending on if the session ignores SSL/TLS errors.every other exception is logged as an error.
All exceptions are discarded after handling.
- post_start_target(target=None, fuzz_data_logger=None, session=None)[source]
Called after a target is started or restarted.