dissect.target.plugin#

Dissect plugin system.

See dissect/target/plugins/general/example.py for an example plugin.

Module Contents#

Classes#

OperatingSystem

Sortable and serializible string-based enum

Plugin

Base class for plugins.

OSPlugin

Base class for OS plugins.

ChildTargetPlugin

A Child target is a special plugin that can list more Targets.

NamespacePlugin

Base class for plugins.

InternalPlugin

Parent class for internal plugins.

PluginFunction

Functions#

export

Decorator to be used on Plugin functions that should be exported.

get_nonprivate_attribute_names

Retrieve all attributes that do not start with _.

get_nonprivate_attributes

Retrieve all public attributes of a Plugin.

get_nonprivate_methods

Retrieve all public methods of a Plugin.

get_descriptors_on_nonprivate_methods

Return record descriptors set on nonprivate methods in cls class.

register

Register a plugin, and put related data inside PLUGINS.

internal

Decorator to be used on plugin functions that should be internal only.

arg

Decorator to be used on Plugin functions that accept additional command line arguments.

plugins

Walk the PLUGINS tree and return plugins.

os_plugins

Retrieve all OS plugin descriptors.

child_plugins

Retrieve all child plugin descriptors.

lookup

Lookup a plugin descriptor by function name.

get_plugins_by_func_name

Get a plugin descriptor by function name.

get_plugins_by_namespace

Get a plugin descriptor by namespace.

load

Helper function that loads a plugin from a given plugin description.

failed

Return all plugins that failed to load.

save_plugin_import_failure

Store errors that occurred during plugin import.

find_py_files

Walk all the files and directories in plugin_path and return all files ending in .py.

load_module_from_name

Load a module from module_path.

generate

Internal function to generate the list of available plugins.

load_module_from_file

Loads a module from a file indicated by path relative to base_path.

load_modules_from_paths

Iterate over the plugin_dirs and load all .py files.

get_external_module_paths

Create a deduplicated list of paths.

environment_variable_paths

plugin_function_index

Returns an index-list for plugins.

find_plugin_functions

Finds plugins that match the target and the patterns.

Attributes#

GENERATED

PluginDescriptor

A dictionary type, for what the plugin descriptor looks like.

MODULE_PATH

The base module path to the in-tree plugins.

OUTPUTS

The different output types supported by @export.

log

dissect.target.plugin.GENERATED = True#
dissect.target.plugin.PluginDescriptor#

A dictionary type, for what the plugin descriptor looks like.

dissect.target.plugin.MODULE_PATH = 'dissect.target.plugins'#

The base module path to the in-tree plugins.

dissect.target.plugin.OUTPUTS = ('default', 'record', 'yield', 'none')#

The different output types supported by @export.

dissect.target.plugin.log#
class dissect.target.plugin.OperatingSystem#

Bases: dissect.target.helpers.utils.StrEnum

Sortable and serializible string-based enum

LINUX = 'linux'#
WINDOWS = 'windows'#
ESXI = 'esxi'#
BSD = 'bsd'#
OSX = 'osx'#
UNIX = 'unix'#
ANDROID = 'android'#
VYOS = 'vyos'#
IOS = 'ios'#
FORTIOS = 'fortios'#
CITRIX = 'citrix-netscaler'#
dissect.target.plugin.export(*args, **kwargs) Callable#

Decorator to be used on Plugin functions that should be exported.

Supported keyword arguments:
property (bool): Whether this export should be regarded as a property.

Properties are implicitly cached.

cache (bool): Whether the result of this function should be cached. record (RecordDescriptor): The flow.record.RecordDescriptor for the records that this function yields.

If the records are dynamically made, use DynamicRecord instead.

output (str): The output type of this function. Can be one of:

  • default: Single return value

  • record: Yields records. Implicit when record argument is given.

  • yield: Yields printable values.

  • none: No return value.

The export decorator adds some additional private attributes to an exported method or property:

  • __output__: The output type to expect for this function, this is the same as output.

  • __record__: The type of record to expect, this value is the same as record.

  • __exported__: set to True to indicate the method or property is exported.

Raises:

ValueError – if there was an invalid output type.

Returns:

An exported function from a plugin.

dissect.target.plugin.get_nonprivate_attribute_names(cls: Type[Plugin]) list[str]#

Retrieve all attributes that do not start with _.

dissect.target.plugin.get_nonprivate_attributes(cls: Type[Plugin]) list[Any]#

Retrieve all public attributes of a Plugin.

dissect.target.plugin.get_nonprivate_methods(cls: Type[Plugin]) list[Callable]#

Retrieve all public methods of a Plugin.

dissect.target.plugin.get_descriptors_on_nonprivate_methods(cls: Type[Plugin]) list[flow.record.RecordDescriptor]#

Return record descriptors set on nonprivate methods in cls class.

class dissect.target.plugin.Plugin(target: dissect.target.Target)#

Base class for plugins.

Plugins can optionally be namespaced by specifying the __namespace__ class attribute. Namespacing results in your plugin needing to be prefixed with this namespace when being called. For example, if your plugin has specified test as namespace and a function called example, you must call your plugin with test.example:

A Plugin class has the following private class attributes:

  • __namespace__

  • __record_descriptors__

With the following three being assigned in register():

  • __plugin__

  • __functions__

  • __exports__

Additionally, the methods and attributes of Plugin receive more private attributes by using decorators.

The export() decorator adds the following private attributes

  • __exported__

  • __output__: Set with the export() decorator.

  • __record__: Set with the export() decorator.

The internal() decorator and InternalPlugin set the __internal__ attribute. Finally. args() decorator sets the __args__ attribute.

Parameters:

target – The Target object to load the plugin for.

__namespace__: str#

Defines the plugin namespace.

__record_descriptors__: list[flow.record.RecordDescriptor]#

Defines a list of RecordDescriptor of the exported plugin functions.

__register__: bool = True#

Determines whether this plugin will be registered.

__findable__: bool = True#

Determines whether this plugin will be revealed when using search patterns.

Some (meta)-plugins are not very suitable for wild cards on CLI or plugin searches, because they will produce duplicate records or results. For instance a plugin that offers the same functions as subplugins will produce redundant results when used with a wild card (browser.* -> browser.history + browser.*.history).

classmethod __init_subclass__(**kwargs)#
is_compatible() bool#

Perform a compatibility check with the target.

abstract check_compatible() None#

Perform a compatibility check with the target.

This function should return None if the plugin is compatible with the current target (self.target). For example, check if a certain file exists. Otherwise it should raise an UnsupportedPluginError.

Raises:

UnsupportedPluginError – If the plugin could not be loaded.

get_all_records() Iterator[flow.record.Record]#

Return the records of all exported methods.

Raises:

PluginError – If the subclass is not a namespace plugin.

__call__(*args, **kwargs)#

A shortcut to get_all_records().

Raises:

PluginError – If the subclass is not a namespace plugin.

class dissect.target.plugin.OSPlugin(target: dissect.target.Target)#

Bases: Plugin

Base class for OS plugins.

This provides a base class for certain common functions of OS’s, which each OS plugin has to implement separately.

For example, it provides an interface for retrieving the hostname and users of a target.

All derived classes MUST implement ALL the classmethods and exported methods with the same @classmethod or @export(...) annotation.

classmethod __init_subclass__(**kwargs)#
check_compatible() bool#

OSPlugin’s use a different compatibility check, override the one from the Plugin class.

Returns:

This function always returns True.

abstract classmethod detect(fs: dissect.target.filesystem.Filesystem) dissect.target.filesystem.Filesystem | None#

Provide detection of this OSPlugin on a given filesystem.

Parameters:

fsFilesystem to detect the OS on.

Returns:

The root filesystem / sysvol when found.

abstract classmethod create(target: dissect.target.Target, sysvol: dissect.target.filesystem.Filesystem) OSPlugin#

Initiate this OSPlugin with the given target and detected filesystem.

Parameters:
  • target – The Target object.

  • sysvol – The filesystem that was detected in the detect() function.

Returns:

An instantiated version of the OSPlugin.

abstract hostname() str | None#

Return the target’s hostname.

Returns:

The hostname as string.

abstract ips() list[str]#

Return the IP addresses configured in the target.

Returns:

The IPs as list.

abstract version() str | None#

Return the target’s OS version.

Returns:

The OS version as string.

abstract users() list[flow.record.Record]#

Return the users available in the target.

Returns:

A list of user records.

abstract os() str#

Return a slug of the target’s OS name.

Returns:

A slug of the OS name, e.g. ‘windows’ or ‘linux’.

abstract architecture() str | None#

Return a slug of the target’s OS architecture.

Returns:

A slug of the OS architecture, e.g. ‘x86_32-unix’, ‘MIPS-linux’ or ‘AMD64-win32’, or ‘unknown’ if the architecture is unknown.

class dissect.target.plugin.ChildTargetPlugin(target: dissect.target.Target)#

Bases: Plugin

A Child target is a special plugin that can list more Targets.

For example, ESXiChildTargetPlugin can list all of the Virtual Machines on the host.

__type__#
abstract list_children() Iterator[dissect.target.helpers.record.ChildTargetRecord]#

Yield ChildTargetRecord records of all possible child targets on this target.

dissect.target.plugin.register(plugincls: Type[Plugin]) None#

Register a plugin, and put related data inside PLUGINS.

This function uses the following private attributes that are set using decorators:

Additionally, register sets the following private attributes on the plugincls:

  • __plugin__: Always set to True.

  • __functions__: A list of all the methods and properties that are __internal__ or __exported__.

  • __exports__: A list of all the methods or properties that were explicitly exported.

Parameters:

plugincls – A plugin class to register.

Raises:

ValueError – If plugincls is not a subclass of Plugin.

dissect.target.plugin.internal(*args, **kwargs) Callable#

Decorator to be used on plugin functions that should be internal only.

Making a plugin internal means that it’s only callable from the Python API and not through target-query.

This decorator adds the __internal__ private attribute to a method or property. The attribute is always set to True, to tell register() that it is an internal method or property.

dissect.target.plugin.arg(*args, **kwargs) Callable#

Decorator to be used on Plugin functions that accept additional command line arguments.

Command line arguments can be added using the @arg decorator. Arguments to this decorator are directly forwarded to the ArgumentParser.add_argument function of argparse. Resulting arguments are passed to the function using kwargs. The keyword argument name must match the argparse argument name.

This decorator adds the __args__ private attribute to a method or property. This attribute holds all the command line arguments that were added to the plugin function.

dissect.target.plugin.plugins(osfilter: type[OSPlugin] | None = None, special_keys: set[str] = set(), only_special_keys: bool = False) Iterator[PluginDescriptor]#

Walk the PLUGINS tree and return plugins.

If osfilter is specified, only plugins related to the provided OSPlugin, or plugins with no OS relation are returned. If osfilter is None, all plugins will be returned.

One exception to this is if the osfilter is a (sub-)class of DefaultPlugin, then plugins are returned as if no osfilter was specified.

Another exeption to this are plugins in the PLUGINS tree which are under a key that starts with a ‘_’. Those are only returned if their exact key is specified in special_keys.

An exception to these exceptions is in the case of OSPlugin (sub-)class plugins and os_filter is not None. These plugins live in the PLUGINS tree under the _os special key. Those plugins are only returned if they fully match the provided osfilter.

The only_special_keys option returns only the plugins which are under a special key that is defined in special_keys. All filtering here will happen as stated in the above cases.

Parameters:
  • osfilter – The optional OSPlugin to filter the returned plugins on.

  • special_keys – Also return plugins which are under the special (‘_’) keys in this set.

  • only_special_keys – Only return the plugins under the keys in special_keys and no others.

Yields:

Plugins in the PLUGINS tree based on the given filter criteria.

dissect.target.plugin.os_plugins() Iterator[PluginDescriptor]#

Retrieve all OS plugin descriptors.

dissect.target.plugin.child_plugins() Iterator[PluginDescriptor]#

Retrieve all child plugin descriptors.

dissect.target.plugin.lookup(func_name: str, osfilter: type[OSPlugin] | None = None) Iterator[PluginDescriptor]#

Lookup a plugin descriptor by function name.

Parameters:
  • func_name – Function name to lookup.

  • osfilter – The OSPlugin to use as template to find os specific plugins for.

dissect.target.plugin.get_plugins_by_func_name(func_name: str, osfilter: type[OSPlugin] | None = None) Iterator[PluginDescriptor]#

Get a plugin descriptor by function name.

Parameters:
  • func_name – Function name to lookup.

  • osfilter – The OSPlugin to use as template to find os specific plugins for.

dissect.target.plugin.get_plugins_by_namespace(namespace: str, osfilter: type[OSPlugin] | None = None) Iterator[PluginDescriptor]#

Get a plugin descriptor by namespace.

Parameters:
  • namespace – Plugin namespace to match.

  • osfilter – The OSPlugin to use as template to find os specific plugins for.

dissect.target.plugin.load(plugin_desc: PluginDescriptor) Type[Plugin]#

Helper function that loads a plugin from a given plugin description.

Parameters:

plugin_desc – Plugin description as returned by plugin.lookup().

Returns:

The plugin class.

Raises:

PluginError – Raised when any other exception occurs while trying to load the plugin.

dissect.target.plugin.failed() list[dict[str, Any]]#

Return all plugins that failed to load.

dissect.target.plugin.save_plugin_import_failure(module: str) None#

Store errors that occurred during plugin import.

dissect.target.plugin.find_py_files(plugin_path: pathlib.Path) Iterator[pathlib.Path]#

Walk all the files and directories in plugin_path and return all files ending in .py.

Do not walk or yield paths containing the following names:

  • __pycache__

  • __init__

Furthermore, it logs an error if plugin_path does not exist.

Parameters:

plugin_path – The path to a directory or file to walk and filter.

dissect.target.plugin.load_module_from_name(module_path: str) None#

Load a module from module_path.

dissect.target.plugin.generate() dict[str, Any]#

Internal function to generate the list of available plugins.

Walks the plugins directory and imports any .py files in there. Plugins will be automatically registered due to the decorators on them.

Returns:

The global PLUGINS dictionary.

dissect.target.plugin.load_module_from_file(path: pathlib.Path, base_path: pathlib.Path)#

Loads a module from a file indicated by path relative to base_path.

The module is added to sys.modules so it can be found everywhere.

Parameters:
  • path – The file to load as module.

  • base_path – The base directory of the module.

dissect.target.plugin.load_modules_from_paths(plugin_dirs: list[pathlib.Path]) None#

Iterate over the plugin_dirs and load all .py files.

dissect.target.plugin.get_external_module_paths(path_list: list[pathlib.Path]) list[pathlib.Path]#

Create a deduplicated list of paths.

dissect.target.plugin.environment_variable_paths() list[pathlib.Path]#
class dissect.target.plugin.NamespacePlugin(target: dissect.target.Target)#

Bases: Plugin

Base class for plugins.

Plugins can optionally be namespaced by specifying the __namespace__ class attribute. Namespacing results in your plugin needing to be prefixed with this namespace when being called. For example, if your plugin has specified test as namespace and a function called example, you must call your plugin with test.example:

A Plugin class has the following private class attributes:

  • __namespace__

  • __record_descriptors__

With the following three being assigned in register():

  • __plugin__

  • __functions__

  • __exports__

Additionally, the methods and attributes of Plugin receive more private attributes by using decorators.

The export() decorator adds the following private attributes

  • __exported__

  • __output__: Set with the export() decorator.

  • __record__: Set with the export() decorator.

The internal() decorator and InternalPlugin set the __internal__ attribute. Finally. args() decorator sets the __args__ attribute.

Parameters:

target – The Target object to load the plugin for.

check_compatible() None#

Perform a compatibility check with the target.

This function should return None if the plugin is compatible with the current target (self.target). For example, check if a certain file exists. Otherwise it should raise an UnsupportedPluginError.

Raises:

UnsupportedPluginError – If the plugin could not be loaded.

__init_subclass_namespace__(**kwargs)#
__init_subclass_subplugin__(**kwargs)#
classmethod __init_subclass__(**kwargs)#
class dissect.target.plugin.InternalPlugin(target: dissect.target.Target)#

Bases: Plugin

Parent class for internal plugins.

InternalPlugin marks all non-private methods internal by default (same as @internal decorator).

classmethod __init_subclass__(**kwargs)#
class dissect.target.plugin.PluginFunction#
name: str#
path: str#
output_type: str#
class_object: type[Plugin]#
method_name: str#
plugin_desc: PluginDescriptor#
dissect.target.plugin.plugin_function_index(target: dissect.target.Target | None) tuple[dict[str, PluginDescriptor], set[str]]#

Returns an index-list for plugins.

This list is used to match CLI expressions against to find the desired plugin. Also returns the roots to determine whether a CLI expression has to be compared to the plugin tree or parsed using legacy rules.

dissect.target.plugin.find_plugin_functions(target: dissect.target.Target | None, patterns: str, compatibility: bool = False, **kwargs) tuple[list[PluginFunction], set[str]]#

Finds plugins that match the target and the patterns.

Given a target, a comma separated list of patterns and an optional compatibility flag, this function finds matching plugins, optionally checking compatibility and returns a list of plugin function descriptors (including output types).