-
Notifications
You must be signed in to change notification settings - Fork 12
Create your own plugins
Dettectinator comes with a rich set of plugins for common detection systems and data source platforms, but you can easily add new ones to accomodate your own flow.
Dettectinator scans the ./plugins folder for modules containing data import plugins. The class name of the plugin has to be unique within Dettectinator.
To create your own Technique plugins create a Python module in the ./plugins folder and a class like the example below:
from plugins.technique_import import TechniqueBase
from argparse import ArgumentParser
from collections.abc import Iterable
class TechniqueCustom(TechniqueBase):
"""
Demo data import plugin
"""
def __init__(self, parameters: dict) -> None:
super().__init__(parameters)
if 'dummy' not in self._parameters:
raise Exception('TechniqueCustom: "dummy" parameter is required.')
@staticmethod
def set_plugin_params(parser: ArgumentParser) -> None:
"""
Set command line arguments specific for the plugin
:param parser: Argument parser
"""
TechniqueBase.set_plugin_params(parser)
parser.add_argument('--dummy', help='Dummy parameter', required=True)
def get_data_from_source(self) -> Iterable:
"""
Gets the use-case/technique data from the source.
:return: Iterable, yields technique, detection, applicable_to
"""
detections = {'T1055': 'Test', 'T1236': 'Another test'}
for technique, detection in detections.items():
detection = self._parameters["dummy"] + ": " + detection
yield technique, detection, NoneThe custom data import plugin needs to derive from TechniqueBase and the name has to start with Technique. There are two methods that need to be implemented:
set_plugin_params: Call the function in the base class to add the default arguments. Then add arguments like in the example above, you can add as many as you need. When an argument is mandatory set the required argument to True. Validate if the required arguments are present in the __init__ method like in the example above.
get_data_from_source: Use this function to get the data from the source. The function is defined as an Iterable, yield every techique/ detection combination from the source. You can optionally specify a value voor applicable_to as well. This will overrule the value given from the command line.
You can load the plugin by specifying the class name after the -p argument on the commandline.
To create your own Datasource plugins create a Python module in the ./plugins folder and a class like the example below:
from plugins.datasources_import import DatasourceBase
from argparse import ArgumentParser
from collections.abc import Iterable
class DatasourceCustom(DatasourceBase):
"""
Demo data import plugin
"""
def __init__(self, parameters: dict) -> None:
super().__init__(parameters)
if 'dummy' not in self._parameters:
raise Exception('DatasourceCustom: "dummy" parameter is required.')
@staticmethod
def set_plugin_params(parser: ArgumentParser) -> None:
"""
Set command line arguments specific for the plugin
:param parser: Argument parser
"""
parser.add_argument('--dummy', help='Dummy parameter', required=True)
def get_data_from_source(self) -> Iterable:
"""
Gets the datasource/product data from the source.
:return: Iterable, yields datasource, product, applicable_to
"""
datasources = {'Active Directory Object Access': 'Test',
'File Access': 'Another test'}
for datasource, product in datasources.items():
product = self._parameters["dummy"] + ": " + detection
yield datasource, product, NoneThe custom data import plugin needs to derive from DatasourceBase and the name has to start with Datasource. There are two methods that need to be implemented:
set_plugin_params: Call the function in the base class to add the default arguments. Then add arguments like in the example above, you can add as many as you need. When an argument is mandatory set the required argument to True. Validate if the required arguments are present in the __init__ method like in the example above.
get_data_from_source: Use this function to get the data from the source. The function is defined as an Iterable, yield every technique/ detection combination from the source.
You can load the plugin by specifying the class name after the -p argument on the commandline. You can optionally specify a value for applicable_to as well. This will overrule the value given from the command line.
To create your own Groups plugins create a Python module in the ./plugins folder and a class like the example below:
from plugins.groups_import import GroupBase
from argparse import ArgumentParser
from collections.abc import Iterable
class GroupCustom(GroupBase):
"""
Demo data import plugin
"""
def __init__(self, parameters: dict) -> None:
super().__init__(parameters)
if 'dummy' not in self._parameters:
raise Exception('GroupCustom: "dummy" parameter is required.')
@staticmethod
def set_plugin_params(parser: ArgumentParser) -> None:
"""
Set command line arguments specific for the plugin
:param parser: Argument parser
"""
parser.add_argument('--dummy', help='Dummy parameter', required=True)
def get_data_from_source(self) -> Iterable:
"""
Retrieves group/technique/software data from the source
:return: Iterable, yields group, campaign, techniques, software
"""
data = {'APT1': {'campaign': 'P0wn them all', 'techniques': ['T1566.002', 'T1059.001', 'T1053.005'],
'software': ['S0002']}}
for group, group_data in data.items():
group_name = self._parameters["dummy"] + ": " + group
yield group_name, group_data['campaign'], group_data['techniques'], group_data['software']The custom data import plugin needs to derive from GroupBase and the name has to start with Group. There are two methods that need to be implemented:
set_plugin_params: Call the function in the base class to add the default arguments. Then add arguments like in the example above, you can add as many as you need. When an argument is mandatory set the required argument to True. Validate if the required arguments are present in the __init__ method like in the example above.
get_data_from_source: Use this function to get the data from the source. The function is defined as an Iterable, yield every group, campaign, techniques, software combination from the source.
You can load the plugin by specifying the class name after the -p argument on the commandline. You can optionally specify values for Group (-gr) and Campaign (-ca) as well on the commandline. These values will be used when no value for Group or Campaign has been supplied from the source.