-
Notifications
You must be signed in to change notification settings - Fork 9
Creating a New Module
Modules have to follow certain rules in order to successfully work with AVAIN. The data format for a module's results is shown above. New modules have to be placed into the src/modules
subdirectory. All modules have to be prefixed with the word avain
to be distinguishable from other files / scripts. Have a look at the current module structure to see some examples. As modules have to be written in Python, their file extension has to be .py
. Also, modules are required to have a run(results: list)
function. To share its results with AVAIN's core, a module has to append them to the list results
list. For this, every result has to be appended to the list as a tuple of (TYPE, RESULT)
, where TYPE
is a key or string contained in the enum defined in core/result_types.py
and RESULT
can either be the filepath to a JSON file or the result itself as a Python dictionary. All non-essential / intermediate results of a module can be returned separately. Every such result needs to be stored in a separate file. To return all of these files, the module has to store the filepaths in a global CREATED_FILES
list. Also, it is important to mention that AVAIN switches into the directory of a module when calling it, so that every module can run within its own environment.
There are two ways a module can receive parameters from the core: configuration files (see further below) and global variables within the module. E.g. if a module has defined the global variable NETWORKS
, the core assigns that variable its corresponding value. Currently available module parameters are:
* VERBOSE
– Specifies whether AVAIN should be verbose
* CONFIG
– The part of the config file relevant to this module
* CORE_CONFIG
– The part of the config file relevant for all modules
* NETWORKS
– A list of network (expressions) to scan, possibly containing wildcards and prefixes
* OMIT_NETWORKS
–   A list of network (expressions) not to scan, possibly containing wildcards and prefixes
* PORTS
– A list of ports to scan, possibly containing the prefix "T" for TCP or "U" for UDP as well a range of ports to scan
* HOSTS
– A list of all (pure) host addresses to scan, not containing any wildcards or prefixes
Furthermore, to retrieve any of the intermediate / shared results, modules have to define which kind of results they want to retrieve as well as a variable to store them in. This can be done by defining the global dict INTERMEDIATE_RESULTS
and putting into it the requested types of intermediate results as keys. The available results types are defined in core/result_types.py
as enum. Example:
INTERMEDIATE_RESULTS = {ResultType.SCAN: None} # get the current SCAN result
Alternatively to the enum keys, their values can be put into the dict of intermediate results. Example:
INTERMEDIATE_RESULTS = {"SCAN": None} # get the current SCAN result
Every module has the ability to log events. First a logger needs to be setup. This can be done simply with:
import logging
logger = logging.getLogger(__name__)
Once set up, the logger can be used like this:
logger.info("Starting the Nmap scan")