This is a framework meant to allow for easy integration of any third-party security vendor.
Based on various input parameters (details below), the script returns a list of Host/Accounts/Detections to be blocked/unblocked.
The code defines an abstract class which third-party clients must extend, which allows for easy integration with the workflow implemented by the base script.
Since adding a new third party integration only requires to extend that class, I'd encourage to use this framework for any new integrations being built.
Currently, the following third party integrations are implemented:
Integration-specific documentation can be found in the relevant folders of the third party integrations.
Install the python module requirements utilizing pip3:
pip3 install -r requirements.txt
Vectra API Tools version 2.4+ is required to support account based groups.
The script supports host, account, and detection based blocking. Parameters defining what host/account/detections get blocked are defined in the config.py file.
This script utilize the Python Keyring package to securely store secrets locally to where the script is ran. The script will check the default keyring for the necessary secrets and prompt the user if they are not found. The default configuration is to store the secrets after input. If user desires not to store the secrets, utilize the --no_store_secrets option.
Vectra Detect API v2 utilizes token based authentication. To create a token, login into Vectra, go to "My Profile" and click to create an API token. Note that only local accounts can generate API tokens.
Vectra API tokens will be linked to the user that created them, and inherit the rights of that user. Any actions done using that API token will also show under the same username in the audit logs.
You may want to create a separate user for the API integration for audit purposes, and only give it fine-grained RBAC rights. For the integration to work, the user will need:
Access to the Vectra Platform API is done through the creation of an API Client. Creation of an API Client will provide a set of OAuth 2.0 credentials that will be used to gain authorization to the Vectra Platform API. Please note that management of API Clients is restricted to Detect users with the role of “Super Admin”. To create an API client, log into your Detect portal and navigate to Manage > API Clients. From the API Clients page, select ‘Add API Client’ to create a new client. Once created, be sure to record your Client ID and Secret Key for safekeeping. You will need these two pieces of information to obtain an access token from the Vectra Platform API. An access token is required to make requests to all of the Vectra Platform API endpoints.
Vectra API Clients will inherit the rights of the role selected during creation.
You may want to create a separate role for the API integration for audit purposes, and only give it fine-grained RBAC rights. For the integration to work, the API Client will need:
The goal of host-based blocking is identifying internal hosts who need to be prevented from being able to further communicate internally and/or externally. The blocking will happen on host specific attributes, such as for instance the internal IP address, the MAC address or the hostname.
There are multiple parameters within the config.py file which define how hosts are being selected for blocking:
Besides this, the _NO_BLOCK_HOST_GROUPNAME Defines a group name from which all members will never be blocked. Users need to create that group themselves, it is not created automatically by the script.
Important: when blocking conditions are no longer fulfilled for a host, either because the blocking tag was removed, its score decreased, group membership was revoked, or the specific detection types causing blocking were fixed, the host will be automatically unblocked by the script on the next run.
The goal of account-based blocking is to disable or otherwise restrict an account to limit its usage by an adversary.
Currently, the only module supporting this functionality is by calling an external program with the external_call
module.
The goal of detection-based blocking is identifying detection containing external components (IP or domain), which can then be blacklisted on various security tools to prevent communication towards those from any internal machine.
Most internal-focused third party clients, such as NACs or endpoints will not implement detection-based blocking, as they are not able to block public IPs/domains. This is mainly relevant for Firewall specific third party clients. Nevertheless, using detection based blocking with a mix of clients supporting it and not is not an issue, but will cause warnings to be logged when executing the script.
Since this usually will block the IP/domain for the whole environment, extreme care is advised, as in the case of false-positives it can have a large impact on the network.
There are multiple parameters within the config.py file which define how detections are being selected for blocking:
Users need to configure which third-party clients they intend the script to use. This configuration needs to be done directly in the config.py file. The user can manually update the config.py and the [third_party_clients/third_party_client/third_party_client_config.py], or utilize the var_config_helper.py script. To run the script:
python3 var_config_helper.py
The script will pull all of the pertinent variables and present them to the user for configuration. When the script is complete, all configurations will be written to the appropriate configuration file(s).
By default, all clients configured in the config.py file are automatically instantiated.
Once all required third party clients have been instantiated, they are appended to the list argument _(third_partyclient)\. When the instantiation call of the VectraAutomatedResponse() class is called, all required third party clients will be available to that class.
Users can also configure if they want to run only host-based, account-based, detection-based blocking or all.
If one type is not desired, you can comment out the corresponding code blocks:
# Those 3 lines handle host-based blocking; comment them out if you don't want it
hosts_to_block, hosts_to_unblock = var.get_hosts_to_block_unblock()
var.block_hosts(hosts_to_block)
var.unblock_hosts(hosts_to_unblock)
# Those 3 lines handle detection-based blocking; comment them out if you don't want it
detections_to_block, detections_to_unblock = var.get_detections_to_block_unblock()
var.block_detections(detections_to_block)
var.unblock_detections(detections_to_unblock)
The external call module's configuration file contains a list per blocking/unblocking action which supplies the command and required arguments to the external program to execute the desired functionality.
HOST_BLOCK_CMD = []
HOST_UNBLOCK_CMD = []
ACCOUNT_BLOCK_CMD = []
ACCOUNT_UNBLOCK_CMD = []
DETECTION_BLOCK_CMD = []
DETECTION_UNBLOCK_CMD = []
QUARANTAINE_POLICY = "block"
To configure commands, each element of the command must become an element in the appropriate list. As an example, if the desired command to execute is to ping source IP 5 times, the list would be configured as such:
```python
HOST_BLOCK_CMD = ['ping', '-t', '5']
The default code in the external_call.py
module is written to supply the command and arguments followed by the host IP or account name, by appending the host IP or account name to the command list.
def block_host(self, host):
if HOST_BLOCK_CMD:
id = uuid.uuid4()
cmd = HOST_BLOCK_CMD
cmd.append(host.ip)
r = subprocess.run(cmd)
The IP or account name may need to be inserted into command list vs appending, this requires modification to the default code.
Blocking of static IPs/Subnets is supported with FortiGate and Palo Alto firewalls by specifying IPs/subnets one per line,
in the main configuration file config.py
. The parameter and default file name are:
STATIC_BLOCK_DESTINATION_IPS = 'static_dst_ips_to_block.txt'
IPs or subnets can be added to the file, one per line, for blocking as a destination address. Example:
1.1.1.1
2.2.2.0/24
3.3.3.3
Removing an entry(ies) from the configuration file will result in the IP/subnet being removed from the firewall during the next run of the script.
The script can be run manually, via a cron job, or as a service. If running as a service, specify the --loop
flag to run the script in a continuous loop with the pause time configured in the config.py
file's variable
SLEEP_MINUTES
.
Modules may support attempting to re-block a host (re-grooming) if that host's IP has changed since it was originally
blocked. To enable re-grooming for supported modules specify the --groom
flag.