From 145aa20b02b98593ce6451c7442988773379e246 Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Fri, 17 Sep 2021 22:50:27 +0200 Subject: [PATCH 01/60] [MC-683] Init plugin | Add action Get Indicator by Value --- plugins/intsights/.CHECKSUM | 15 ++ plugins/intsights/.dockerignore | 9 + plugins/intsights/Dockerfile | 26 +++ plugins/intsights/Makefile | 53 +++++ plugins/intsights/bin/icon_intsights | 46 ++++ plugins/intsights/help.md | 103 +++++++++ plugins/intsights/icon_intsights/__init__.py | 1 + .../icon_intsights/actions/__init__.py | 2 + .../get_indicator_by_value/__init__.py | 2 + .../actions/get_indicator_by_value/action.py | 33 +++ .../actions/get_indicator_by_value/schema.py | 213 ++++++++++++++++++ .../icon_intsights/connection/__init__.py | 2 + .../icon_intsights/connection/connection.py | 29 +++ .../icon_intsights/connection/schema.py | 58 +++++ .../icon_intsights/triggers/__init__.py | 1 + .../intsights/icon_intsights/util/__init__.py | 1 + plugins/intsights/icon_intsights/util/api.py | 54 +++++ plugins/intsights/plugin.spec.yaml | 131 +++++++++++ plugins/intsights/requirements.txt | 3 + plugins/intsights/setup.py | 14 ++ plugins/intsights/unit_test/__init__.py | 0 .../payloads/iocs_ioc-by-value.json.resp | 33 +++ .../intsights/unit_test/test_connection.py | 40 ++++ .../unit_test/test_get_indicator_by_value.py | 61 +++++ plugins/intsights/unit_test/util.py | 52 +++++ 25 files changed, 982 insertions(+) create mode 100644 plugins/intsights/.CHECKSUM create mode 100755 plugins/intsights/.dockerignore create mode 100755 plugins/intsights/Dockerfile create mode 100755 plugins/intsights/Makefile create mode 100755 plugins/intsights/bin/icon_intsights create mode 100755 plugins/intsights/help.md create mode 100755 plugins/intsights/icon_intsights/__init__.py create mode 100755 plugins/intsights/icon_intsights/actions/__init__.py create mode 100755 plugins/intsights/icon_intsights/actions/get_indicator_by_value/__init__.py create mode 100755 plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py create mode 100755 plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py create mode 100755 plugins/intsights/icon_intsights/connection/__init__.py create mode 100755 plugins/intsights/icon_intsights/connection/connection.py create mode 100755 plugins/intsights/icon_intsights/connection/schema.py create mode 100755 plugins/intsights/icon_intsights/triggers/__init__.py create mode 100755 plugins/intsights/icon_intsights/util/__init__.py create mode 100644 plugins/intsights/icon_intsights/util/api.py create mode 100644 plugins/intsights/plugin.spec.yaml create mode 100755 plugins/intsights/requirements.txt create mode 100755 plugins/intsights/setup.py create mode 100644 plugins/intsights/unit_test/__init__.py create mode 100644 plugins/intsights/unit_test/payloads/iocs_ioc-by-value.json.resp create mode 100644 plugins/intsights/unit_test/test_connection.py create mode 100644 plugins/intsights/unit_test/test_get_indicator_by_value.py create mode 100644 plugins/intsights/unit_test/util.py diff --git a/plugins/intsights/.CHECKSUM b/plugins/intsights/.CHECKSUM new file mode 100644 index 0000000000..f75f563ffa --- /dev/null +++ b/plugins/intsights/.CHECKSUM @@ -0,0 +1,15 @@ +{ + "spec": "a157e0f22f3dd6b098eac5d6c3099242", + "manifest": "182eb71e6763e8f3044a2c18ccdd15a9", + "setup": "ea830b2af5f13706b38c5e288f0b6944", + "schemas": [ + { + "identifier": "get_indicator_by_value/schema.py", + "hash": "e1f54a011120ea208c59ff2f24a3cec7" + }, + { + "identifier": "connection/schema.py", + "hash": "1dfa7361a2d78e5dd4aaebfca7348c16" + } + ] +} \ No newline at end of file diff --git a/plugins/intsights/.dockerignore b/plugins/intsights/.dockerignore new file mode 100755 index 0000000000..93dc53fb01 --- /dev/null +++ b/plugins/intsights/.dockerignore @@ -0,0 +1,9 @@ +unit_test/**/* +unit_test +examples/**/* +examples +tests +tests/**/* +**/*.json +**/*.tar +**/*.gz \ No newline at end of file diff --git a/plugins/intsights/Dockerfile b/plugins/intsights/Dockerfile new file mode 100755 index 0000000000..6efb1c8f03 --- /dev/null +++ b/plugins/intsights/Dockerfile @@ -0,0 +1,26 @@ +FROM rapid7/insightconnect-python-3-38-plugin:4 +# Refer to the following documentation for available SDK parent images: https://komand.github.io/python/sdk.html#version + +LABEL organization=rapid7 +LABEL sdk=python + +# Add any custom package dependencies here +# NOTE: Add pip packages to requirements.txt + +# End package dependencies + +# Add source code +WORKDIR /python/src +ADD ./plugin.spec.yaml /plugin.spec.yaml +ADD . /python/src + +# Install pip dependencies +RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + +# Install plugin +RUN python setup.py build && python setup.py install + +# User to run plugin code. The two supported users are: root, nobody +USER root + +ENTRYPOINT ["/usr/local/bin/icon_intsights"] \ No newline at end of file diff --git a/plugins/intsights/Makefile b/plugins/intsights/Makefile new file mode 100755 index 0000000000..cb85f96b6c --- /dev/null +++ b/plugins/intsights/Makefile @@ -0,0 +1,53 @@ +# Include other Makefiles for improved functionality +INCLUDE_DIR = ../../tools/Makefiles +MAKEFILES := $(wildcard $(INCLUDE_DIR)/*.mk) +# We can't guarantee customers will have the include files +# - prefix to ignore Makefiles when not present +# https://www.gnu.org/software/make/manual/html_node/Include.html +-include $(MAKEFILES) + +ifneq ($(MAKEFILES),) + $(info [$(YELLOW)*$(NORMAL)] Use ``make menu`` for available targets) + $(info [$(YELLOW)*$(NORMAL)] Including available Makefiles: $(MAKEFILES)) + $(info --) +else + $(warning Makefile includes directory not present: $(INCLUDE_DIR)) +endif + +VERSION?=$(shell grep '^version: ' plugin.spec.yaml | sed 's/version: //') +NAME?=$(shell grep '^name: ' plugin.spec.yaml | sed 's/name: //') +VENDOR?=$(shell grep '^vendor: ' plugin.spec.yaml | sed 's/vendor: //') +CWD?=$(shell basename $(PWD)) +_NAME?=$(shell echo $(NAME) | awk '{ print toupper(substr($$0,1,1)) tolower(substr($$0,2)) }') +PKG=$(VENDOR)-$(NAME)-$(VERSION).tar.gz + +# Set default target explicitly. Make's default behavior is the first target in the Makefile. +# We don't want that behavior due to includes which are read first +.DEFAULT_GOAL := default # Make >= v3.80 (make -version) + + +default: image tarball + +tarball: + $(info [$(YELLOW)*$(NORMAL)] Creating plugin tarball) + rm -rf build + rm -rf $(PKG) + tar -cvzf $(PKG) --exclude=$(PKG) --exclude=tests --exclude=run.sh * + +image: + $(info [$(YELLOW)*$(NORMAL)] Building plugin image) + docker build --pull -t $(VENDOR)/$(NAME):$(VERSION) . + docker tag $(VENDOR)/$(NAME):$(VERSION) $(VENDOR)/$(NAME):latest + +regenerate: + $(info [$(YELLOW)*$(NORMAL)] Regenerating schema from plugin.spec.yaml) + icon-plugin generate python --regenerate + +export: image + $(info [$(YELLOW)*$(NORMAL)] Exporting docker image) + @printf "\n ---> Exporting Docker image to ./$(VENDOR)_$(NAME)_$(VERSION).tar\n" + @docker save $(VENDOR)/$(NAME):$(VERSION) | gzip > $(VENDOR)_$(NAME)_$(VERSION).tar + +# Make will not run a target if a file of the same name exists unless setting phony targets +# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html +.PHONY: default tarball image regenerate diff --git a/plugins/intsights/bin/icon_intsights b/plugins/intsights/bin/icon_intsights new file mode 100755 index 0000000000..0bf41333a6 --- /dev/null +++ b/plugins/intsights/bin/icon_intsights @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# GENERATED BY KOMAND SDK - DO NOT EDIT +import os +import json +from sys import argv + +Name = "IntSights" +Vendor = "rapid7" +Version = "1.0.0" +Description = "IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy" + + +def main(): + if 'http' in argv: + if os.environ.get("GUNICORN_CONFIG_FILE"): + with open(os.environ.get("GUNICORN_CONFIG_FILE")) as gf: + gunicorn_cfg = json.load(gf) + if gunicorn_cfg.get("worker_class", "sync") == "gevent": + from gevent import monkey + monkey.patch_all() + elif 'gevent' in argv: + from gevent import monkey + monkey.patch_all() + + import insightconnect_plugin_runtime + from icon_intsights import connection, actions, triggers + + class ICONIntsights(insightconnect_plugin_runtime.Plugin): + def __init__(self): + super(self.__class__, self).__init__( + name=Name, + vendor=Vendor, + version=Version, + description=Description, + connection=connection.Connection() + ) + self.add_action(actions.GetIndicatorByValue()) + + + """Run plugin""" + cli = insightconnect_plugin_runtime.CLI(ICONIntsights()) + cli.run() + + +if __name__ == "__main__": + main() diff --git a/plugins/intsights/help.md b/plugins/intsights/help.md new file mode 100755 index 0000000000..07c51309bc --- /dev/null +++ b/plugins/intsights/help.md @@ -0,0 +1,103 @@ +# Description + +IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy + +# Key Features + +Identify key features of plugin. + +# Requirements + +* Example: Requires an API Key from the product +* Example: API must be enabled on the Settings page in the product's user interface + +# Supported Product Versions + +_There are no supported product versions listed._ + +# Documentation + +## Setup + +The connection configuration accepts the following parameters: + +|Name|Type|Default|Required|Description|Enum|Example| +|----|----|-------|--------|-----------|----|-------| +|account_id|credential_secret_key|None|True|Account id|None|{"secret_key": "account_id"}| +|api_key|credential_secret_key|None|True|API key|None|{"secret_key": "api_key"}| + +Example input: + +``` +{ + "account_id": "{\"secret_key\": \"account_id\"}", + "api_key": "{\"secret_key\": \"api_key\"}" +} +``` + +## Technical Details + +### Actions + +#### Get Indicator by Value + +This action this action will search indicators in Intsights TIP. + +##### Input + +|Name|Type|Default|Required|Description|Enum|Example| +|----|----|-------|--------|-----------|----|-------| +|indicator_value|string|None|True|Indicator Value|None|None| + +Example input: + +``` +``` + +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|first_seen|string|True|First Seen| +|geo_location|string|True|GEO Location| +|last_seen|string|True|Last Seen| +|last_update|string|True|Last Update| +|related_campaigns|[]string|True|Related Campaigns| +|related_malware|[]string|True|Related Malware| +|related_threat_actors|[]string|True|Related Threat Actors| +|score|integer|True|Score| +|severity|string|True|Severity| +|sources|[]source|True|Sources| +|system_tags|[]string|True|System Tags| +|tags|[]string|True|Tags| +|type|string|True|Type| +|value|string|True|Value| +|whitelist|string|True|Whitelist| + +Example output: + +``` +``` + +### Triggers + +_This plugin does not contain any triggers._ + +### Custom Output Types + +_This plugin does not contain any custom output types._ + +## Troubleshooting + +_This plugin does not contain any troubleshooting information._ + +# Version History + +* 1.0.0 - Initial plugin + +# Links + +## References + +* [IntSights](LINK TO PRODUCT/VENDOR WEBSITE) + diff --git a/plugins/intsights/icon_intsights/__init__.py b/plugins/intsights/icon_intsights/__init__.py new file mode 100755 index 0000000000..bace8db897 --- /dev/null +++ b/plugins/intsights/icon_intsights/__init__.py @@ -0,0 +1 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT diff --git a/plugins/intsights/icon_intsights/actions/__init__.py b/plugins/intsights/icon_intsights/actions/__init__.py new file mode 100755 index 0000000000..d45f597885 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .get_indicator_by_value.action import GetIndicatorByValue diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/__init__.py b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/__init__.py new file mode 100755 index 0000000000..2ef80e111b --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import GetIndicatorByValue diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py new file mode 100755 index 0000000000..5eafeee39b --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py @@ -0,0 +1,33 @@ +import insightconnect_plugin_runtime +from .schema import GetIndicatorByValueInput, GetIndicatorByValueOutput, Input, Output, Component +# Custom imports below + + +class GetIndicatorByValue(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='get_indicator_by_value', + description=Component.DESCRIPTION, + input=GetIndicatorByValueInput(), + output=GetIndicatorByValueOutput()) + + def run(self, params={}): + response = self.connection.client.get_indicator_by_value(params.get(Input.INDICATOR_VALUE)) + return { + Output.VALUE: response.get('Value'), + Output.TYPE: response.get('Type'), + Output.SEVERITY: response.get('Severity'), + Output.SCORE: response.get('Score', 0), + Output.WHITELIST: response.get('Whitelist'), + Output.FIRST_SEEN: response.get('FirstSeen'), + Output.LAST_SEEN: response.get('LastSeen'), + Output.LAST_UPDATE: response.get('LastUpdate'), + Output.GEO_LOCATION: response.get('Geolocation'), + Output.SOURCES: response.get('Sources', []), + Output.TAGS: response.get('Tags', []), + Output.SYSTEM_TAGS: response.get('SystemTags', []), + Output.RELATED_MALWARE: response.get('RelatedMalware', []), + Output.RELATED_CAMPAIGNS: response.get('RelatedCampaigns', []), + Output.RELATED_THREAT_ACTORS: response.get('RelatedThreatActors', []), + } diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py new file mode 100755 index 0000000000..2892376571 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py @@ -0,0 +1,213 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "This action will search indicators in Intsights TIP" + + +class Input: + INDICATOR_VALUE = "indicator_value" + + +class Output: + FIRST_SEEN = "first_seen" + GEO_LOCATION = "geo_location" + LAST_SEEN = "last_seen" + LAST_UPDATE = "last_update" + RELATED_CAMPAIGNS = "related_campaigns" + RELATED_MALWARE = "related_malware" + RELATED_THREAT_ACTORS = "related_threat_actors" + SCORE = "score" + SEVERITY = "severity" + SOURCES = "sources" + SYSTEM_TAGS = "system_tags" + TAGS = "tags" + TYPE = "type" + VALUE = "value" + WHITELIST = "whitelist" + + +class GetIndicatorByValueInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "indicator_value": { + "type": "string", + "title": "Indicator Value", + "description": "Indicator Value", + "order": 1 + } + }, + "required": [ + "indicator_value" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class GetIndicatorByValueOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "first_seen": { + "type": "string", + "title": "First Seen", + "description": "First Seen", + "order": 6 + }, + "geo_location": { + "type": "string", + "title": "GEO Location", + "description": "GEO Location", + "order": 9 + }, + "last_seen": { + "type": "string", + "title": "Last Seen", + "description": "Last Seen", + "order": 7 + }, + "last_update": { + "type": "string", + "title": "Last Update", + "description": "Last Update", + "order": 8 + }, + "related_campaigns": { + "type": "array", + "title": "Related Campaigns", + "description": "Related Campaigns", + "items": { + "type": "string" + }, + "order": 14 + }, + "related_malware": { + "type": "array", + "title": "Related Malware", + "description": "Related Malware", + "items": { + "type": "string" + }, + "order": 13 + }, + "related_threat_actors": { + "type": "array", + "title": "Related Threat Actors", + "description": "Related Threat Actors", + "items": { + "type": "string" + }, + "order": 15 + }, + "score": { + "type": "integer", + "title": "Score", + "description": "Score", + "order": 4 + }, + "severity": { + "type": "string", + "title": "Severity", + "description": "Severity", + "order": 3 + }, + "sources": { + "type": "array", + "title": "Sources", + "description": "Sources", + "items": { + "$ref": "#/definitions/source" + }, + "order": 10 + }, + "system_tags": { + "type": "array", + "title": "System Tags", + "description": "System Tags", + "items": { + "type": "string" + }, + "order": 12 + }, + "tags": { + "type": "array", + "title": "Tags", + "description": "Tags", + "items": { + "type": "string" + }, + "order": 11 + }, + "type": { + "type": "string", + "title": "Type", + "description": "Type", + "order": 2 + }, + "value": { + "type": "string", + "title": "Value", + "description": "Value", + "order": 1 + }, + "whitelist": { + "type": "string", + "title": "Whitelist", + "description": "Whitelist", + "order": 5 + } + }, + "required": [ + "first_seen", + "geo_location", + "last_seen", + "last_update", + "related_campaigns", + "related_malware", + "related_threat_actors", + "score", + "severity", + "sources", + "system_tags", + "tags", + "type", + "value", + "whitelist" + ], + "definitions": { + "source": { + "type": "object", + "title": "source", + "properties": { + "ConfidenceLevel": { + "type": "integer", + "title": "Confidence Level", + "order": 2 + }, + "Name": { + "type": "string", + "title": "Name", + "order": 1 + } + }, + "required": [ + "ConfidenceLevel", + "Name" + ] + } + } +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/intsights/icon_intsights/connection/__init__.py b/plugins/intsights/icon_intsights/connection/__init__.py new file mode 100755 index 0000000000..a515dcf6b0 --- /dev/null +++ b/plugins/intsights/icon_intsights/connection/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .connection import Connection diff --git a/plugins/intsights/icon_intsights/connection/connection.py b/plugins/intsights/icon_intsights/connection/connection.py new file mode 100755 index 0000000000..8b62f686c3 --- /dev/null +++ b/plugins/intsights/icon_intsights/connection/connection.py @@ -0,0 +1,29 @@ +import insightconnect_plugin_runtime +from typing import Optional +from .schema import ConnectionSchema, Input +# Custom imports below +from icon_intsights.util.api import IntSightAPI +from insightconnect_plugin_runtime.exceptions import PluginException, ConnectionTestException + + +class Connection(insightconnect_plugin_runtime.Connection): + + def __init__(self): + super(self.__class__, self).__init__(input=ConnectionSchema()) + self.client: Optional[IntSightAPI] = None + + def connect(self, params={}): + self.client = IntSightAPI( + params.get(Input.ACCOUNT_ID, {}).get('secretKey'), + params.get(Input.API_KEY, {}).get('secretKey') + ) + self.logger.info("Connect: Connecting...") + + def test(self): + try: + return {"success": self.client.test_credentials()} + except PluginException as e: + raise ConnectionTestException( + cause=e.cause, + assistance=e.assistance + ) diff --git a/plugins/intsights/icon_intsights/connection/schema.py b/plugins/intsights/icon_intsights/connection/schema.py new file mode 100755 index 0000000000..6b11706265 --- /dev/null +++ b/plugins/intsights/icon_intsights/connection/schema.py @@ -0,0 +1,58 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Input: + ACCOUNT_ID = "account_id" + API_KEY = "api_key" + + +class ConnectionSchema(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "account_id": { + "$ref": "#/definitions/credential_secret_key", + "title": "Account ID", + "description": "Account id", + "order": 1 + }, + "api_key": { + "$ref": "#/definitions/credential_secret_key", + "title": "API Key", + "description": "API key", + "order": 2 + } + }, + "required": [ + "account_id", + "api_key" + ], + "definitions": { + "credential_secret_key": { + "id": "credential_secret_key", + "type": "object", + "title": "Credential: Secret Key", + "description": "A shared secret key", + "properties": { + "secretKey": { + "type": "string", + "title": "Secret Key", + "displayType": "password", + "description": "The shared secret key", + "format": "password" + } + }, + "required": [ + "secretKey" + ] + } + } +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/intsights/icon_intsights/triggers/__init__.py b/plugins/intsights/icon_intsights/triggers/__init__.py new file mode 100755 index 0000000000..bace8db897 --- /dev/null +++ b/plugins/intsights/icon_intsights/triggers/__init__.py @@ -0,0 +1 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT diff --git a/plugins/intsights/icon_intsights/util/__init__.py b/plugins/intsights/icon_intsights/util/__init__.py new file mode 100755 index 0000000000..bace8db897 --- /dev/null +++ b/plugins/intsights/icon_intsights/util/__init__.py @@ -0,0 +1 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT diff --git a/plugins/intsights/icon_intsights/util/api.py b/plugins/intsights/icon_intsights/util/api.py new file mode 100644 index 0000000000..4346cffc33 --- /dev/null +++ b/plugins/intsights/icon_intsights/util/api.py @@ -0,0 +1,54 @@ +import json +import requests +from insightconnect_plugin_runtime.exceptions import PluginException +from requests.auth import HTTPBasicAuth + + +class IntSightAPI: + def __init__(self, account_id, api_key): + self.account_id = account_id + self.api_key = api_key + self.url = 'https://api.intsights.com/public/v1' + + def get_indicator_by_value(self, ioc_value: str) -> dict: + response = self.make_request('GET', f'public/v2/iocs/ioc-by-value?iocValue={ioc_value}') + if response.status_code == 204: + return {} + + return response.json() + + def test_credentials(self) -> bool: + return self.make_request('HEAD', 'test-credentials').status_code == 200 + + def make_request(self, method: str, path: str) -> requests.Response: + try: + response = requests.request( + method=method, + url=f"{self.url}/{path}", + headers={"Content-Type": "application/json"}, + verify=True, + auth=HTTPBasicAuth(self.account_id, self.api_key), + ) + + if response.status_code == 401: + raise PluginException(preset=PluginException.Preset.USERNAME_PASSWORD, data=response.text) + if response.status_code == 403: + raise PluginException(preset=PluginException.Preset.API_KEY, data=response.text) + if response.status_code == 404: + raise PluginException(preset=PluginException.Preset.NOT_FOUND, data=response.text) + if 400 <= response.status_code < 500: + raise PluginException( + preset=PluginException.Preset.UNKNOWN, + data=response.text, + ) + if response.status_code >= 500: + raise PluginException(preset=PluginException.Preset.SERVER_ERROR, data=response.text) + + if 200 <= response.status_code < 300: + return response + + raise PluginException(preset=PluginException.Preset.UNKNOWN, data=response.text) + except json.decoder.JSONDecodeError as e: + raise PluginException(preset=PluginException.Preset.INVALID_JSON, data=e) + except requests.exceptions.HTTPError as e: + raise PluginException(preset=PluginException.Preset.UNKNOWN, data=e) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml new file mode 100644 index 0000000000..3ea82aa860 --- /dev/null +++ b/plugins/intsights/plugin.spec.yaml @@ -0,0 +1,131 @@ +plugin_spec_version: v2 +extension: plugin +products: [insightconnect] +name: intsights +title: IntSights +description: IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy +version: 1.0.0 +vendor: rapid7 +support: community +status: [] +resources: + source_url: https://github.com/rapid7/insightconnect-plugins/tree/master/plugins/intsights + license_url: https://github.com/rapid7/insightconnect-plugins/blob/master/LICENSE + vendor_url: https://intsights.com/ +tags: +- intsights +- darkweb +- threatintelligence +hub_tags: + use_cases: [data_utility, threat_detection_and_response] + keywords: [elasticsearch, search, elastic] + features: [] +types: + source: + Name: + title: Name + type: string + required: true + ConfidenceLevel: + title: Confidence Level + type: integer + required: true +connection: + account_id: + title: Account ID + description: Account id + type: credential_secret_key + required: true + example: '{"secret_key": "account_id"}' + api_key: + title: API Key + description: API key + type: credential_secret_key + required: true + example: '{"secret_key": "api_key"}' +actions: + get_indicator_by_value: + title: Get Indicator by Value + description: This action will search indicators in Intsights TIP + input: + indicator_value: + title: Indicator Value + description: Indicator Value + type: string + required: true + output: + value: + title: Value + description: Value + type: string + required: true + type: + title: Type + description: Type + type: string + required: true + severity: + title: Severity + description: Severity + type: string + required: true + score: + title: Score + description: Score + type: integer + required: true + whitelist: + title: Whitelist + description: Whitelist + type: string + required: true + first_seen: + title: First Seen + description: First Seen + type: string + required: true + last_seen: + title: Last Seen + description: Last Seen + type: string + required: true + last_update: + title: Last Update + description: Last Update + type: string + required: true + geo_location: + title: GEO Location + description: GEO Location + type: string + required: true + sources: + title: Sources + description: Sources + type: '[]source' + required: true + tags: + title: Tags + description: Tags + type: '[]string' + required: true + system_tags: + title: System Tags + description: System Tags + type: '[]string' + required: true + related_malware: + title: Related Malware + description: Related Malware + type: '[]string' + required: true + related_campaigns: + title: Related Campaigns + description: Related Campaigns + type: '[]string' + required: true + related_threat_actors: + title: Related Threat Actors + description: Related Threat Actors + type: '[]string' + required: true diff --git a/plugins/intsights/requirements.txt b/plugins/intsights/requirements.txt new file mode 100755 index 0000000000..d0674c75e2 --- /dev/null +++ b/plugins/intsights/requirements.txt @@ -0,0 +1,3 @@ +# List third-party dependencies here, separated by newlines. +# All dependencies must be version-pinned, eg. requests==1.2.0 +# See: https://pip.pypa.io/en/stable/user_guide/#requirements-files \ No newline at end of file diff --git a/plugins/intsights/setup.py b/plugins/intsights/setup.py new file mode 100755 index 0000000000..b4e1de0318 --- /dev/null +++ b/plugins/intsights/setup.py @@ -0,0 +1,14 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from setuptools import setup, find_packages + + +setup(name="intsights-rapid7-plugin", + version="1.0.0", + description="IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy", + author="rapid7", + author_email="", + url="", + packages=find_packages(), + install_requires=['insightconnect-plugin-runtime'], # Add third-party dependencies to requirements.txt, not here! + scripts=['bin/icon_intsights'] + ) diff --git a/plugins/intsights/unit_test/__init__.py b/plugins/intsights/unit_test/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/intsights/unit_test/payloads/iocs_ioc-by-value.json.resp b/plugins/intsights/unit_test/payloads/iocs_ioc-by-value.json.resp new file mode 100644 index 0000000000..884969f6c1 --- /dev/null +++ b/plugins/intsights/unit_test/payloads/iocs_ioc-by-value.json.resp @@ -0,0 +1,33 @@ +{ + "Value": "example.com", + "Type": "Domains", + "Severity": "High", + "Score": 100, + "Whitelist": "false", + "FirstSeen": "2020-01-01T20:01:27.344Z", + "LastSeen": "2020-01-30T16:18:51.148Z", + "LastUpdate": "2020-02-21T23:00:51.268Z", + "Geolocation": "US", + "Sources": [ + { + "Name": "AlienVault OTX", + "ConfidenceLevel": 3 + } + ], + "Tags": [ + "MyTag_1" + ], + "SystemTags": [ + "Phishing" + ], + "RelatedMalware": [ + "doppeldridex", + "dridex" + ], + "RelatedCampaigns": [ + "SolarWinds" + ], + "RelatedThreatActors": [ + "doppelspider" + ] +} \ No newline at end of file diff --git a/plugins/intsights/unit_test/test_connection.py b/plugins/intsights/unit_test/test_connection.py new file mode 100644 index 0000000000..2ec53824d2 --- /dev/null +++ b/plugins/intsights/unit_test/test_connection.py @@ -0,0 +1,40 @@ +import sys +import os +sys.path.append(os.path.abspath('../')) + +from unittest import TestCase +from unittest.mock import patch +from unit_test.util import Util +from icon_intsights.actions.get_indicator_by_value.action import GetIndicatorByValue +from icon_intsights.connection.schema import Input +from insightconnect_plugin_runtime.exceptions import ConnectionTestException + + +class TestConnection(TestCase): + @patch("requests.request", side_effect=Util.mock_request) + def test_connection_should_success_when_good_credentials(self, mock_request) -> None: + action = Util.default_connector(GetIndicatorByValue()) + self.assertEqual(action.connection.test(), {'success': True}) + + @patch("requests.request", side_effect=Util.mock_request) + def test_connection_should_success_when_credentials(self, mock_request) -> None: + action = Util.default_connector(GetIndicatorByValue(), { + Input.API_KEY: {'secretKey': 'api_key'}, + Input.ACCOUNT_ID: {'secretKey': 'account_id'} + }) + + self.assertEqual("https://api.intsights.com/public/v1", action.connection.client.url) + self.assertEqual("api_key", action.connection.client.api_key) + self.assertEqual("account_id", action.connection.client.account_id) + + @patch("requests.request", side_effect=Util.mock_request) + def test_connection_should_fail_when_wrong_credentials(self, mock_request) -> None: + action = Util.default_connector(GetIndicatorByValue(), { + Input.API_KEY: {'secretKey': 'wrong'}, + Input.ACCOUNT_ID: {'secretKey': 'wrong'} + }) + with self.assertRaises(ConnectionTestException) as error: + action.connection.test() + + self.assertEqual("Invalid username or password provided.", error.exception.cause) + self.assertEqual("Verify your username and password are correct.", error.exception.assistance) diff --git a/plugins/intsights/unit_test/test_get_indicator_by_value.py b/plugins/intsights/unit_test/test_get_indicator_by_value.py new file mode 100644 index 0000000000..c8e6b323b6 --- /dev/null +++ b/plugins/intsights/unit_test/test_get_indicator_by_value.py @@ -0,0 +1,61 @@ +import sys +import os + +sys.path.append(os.path.abspath('../')) + +from unittest import TestCase +from unittest.mock import patch +from unit_test.util import Util +from icon_intsights.actions.get_indicator_by_value import GetIndicatorByValue +from icon_intsights.actions.get_indicator_by_value.schema import Input + + +class TestGetIndicatorByValue(TestCase): + @classmethod + @patch("requests.request", side_effect=Util.mock_request) + def setUpClass(cls, mock_request) -> None: + cls.action = Util.default_connector(GetIndicatorByValue()) + + @patch("requests.request", side_effect=Util.mock_request) + def test_get_indicator_by_value_should_success(self, make_request): + actual = self.action.run({Input.INDICATOR_VALUE: 'example.com'}) + expected = { + 'first_seen': '2020-01-01T20:01:27.344Z', + 'geo_location': 'US', + 'last_seen': '2020-01-30T16:18:51.148Z', + 'last_update': '2020-02-21T23:00:51.268Z', + 'related_campaigns': ['SolarWinds'], + 'related_malware': ['doppeldridex', 'dridex'], + 'related_threat_actors': ['doppelspider'], + 'score': 100, + 'severity': 'High', + 'sources': [{'ConfidenceLevel': 3, 'Name': 'AlienVault OTX'}], + 'system_tags': ['Phishing'], + 'tags': ['MyTag_1'], + 'type': 'Domains', + 'value': 'example.com', + 'whitelist': 'false' + } + self.assertEqual(expected, actual) + + @patch("requests.request", side_effect=Util.mock_request) + def test_get_indicator_by_value_should_success_when_empty(self, make_request): + actual = self.action.run({Input.INDICATOR_VALUE: 'empty'}) + expected = { + 'first_seen': None, + 'geo_location': None, + 'last_seen': None, + 'last_update': None, + 'related_campaigns': [], + 'related_malware': [], + 'related_threat_actors': [], + 'score': 0, + 'severity': None, + 'sources': [], + 'system_tags': [], + 'tags': [], + 'type': None, + 'value': None, + 'whitelist': None + } + self.assertEqual(expected, actual) diff --git a/plugins/intsights/unit_test/util.py b/plugins/intsights/unit_test/util.py new file mode 100644 index 0000000000..813756fae9 --- /dev/null +++ b/plugins/intsights/unit_test/util.py @@ -0,0 +1,52 @@ +import json +import logging + +from icon_intsights.connection import Connection +from icon_intsights.connection.schema import Input + + +class Util: + @staticmethod + def default_connector(action, connect_params: object = None): + default_connection = Connection() + default_connection.logger = logging.getLogger("connection logger") + if connect_params: + params = connect_params + else: + params = { + Input.ACCOUNT_ID: {'secretKey': 'account_id'}, + Input.API_KEY: {'secretKey': 'api_key'} + } + default_connection.connect(params) + action.connection = default_connection + action.logger = logging.getLogger("action logger") + return action + + @staticmethod + def read_file_to_string(filename): + with open(filename) as my_file: + return my_file.read() + + @staticmethod + def mock_request(*args, **kwargs): + class MockResponse: + def __init__(self, status_code: int, filename: str = None): + self.status_code = status_code + self.text = '' + self.filename = filename + + def json(self): + return json.loads(Util.read_file_to_string(f'payloads/{self.filename}.json.resp')) + + if kwargs.get('url') == 'https://api.intsights.com/public/v1/test-credentials' \ + and kwargs.get('auth').username == 'wrong': + return MockResponse(401) + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/test-credentials': + return MockResponse(200) + elif kwargs.get( + 'url') == 'https://api.intsights.com/public/v1/public/v2/iocs/ioc-by-value?iocValue=example.com': + return MockResponse(200, 'iocs_ioc-by-value') + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/public/v2/iocs/ioc-by-value?iocValue=empty': + return MockResponse(204) + else: + raise NotImplementedError('Not implemented') From 77a6ef4b5723e02d94d2ae9b72816471b387b73e Mon Sep 17 00:00:00 2001 From: r7-kszczepanskagorna Date: Sat, 18 Sep 2021 01:17:06 +0200 Subject: [PATCH 02/60] IntSights new actions and trigger draft --- plugins/intsights/.CHECKSUM | 36 +- plugins/intsights/Dockerfile | 2 +- plugins/intsights/bin/icon_intsights | 14 + plugins/intsights/help.md | 232 +++++++++++- .../icon_intsights/actions/__init__.py | 6 + .../actions/enrich_indicator/__init__.py | 2 + .../actions/enrich_indicator/action.py | 17 + .../actions/enrich_indicator/schema.py | 77 ++++ .../actions/get_alerts/__init__.py | 2 + .../actions/get_alerts/action.py | 17 + .../actions/get_alerts/schema.py | 152 ++++++++ .../get_complete_alert_by_id/__init__.py | 2 + .../get_complete_alert_by_id/action.py | 17 + .../get_complete_alert_by_id/schema.py | 142 +++++++ .../actions/get_indicator_by_value/schema.py | 5 +- .../get_indicator_scan_status/__init__.py | 2 + .../get_indicator_scan_status/action.py | 17 + .../get_indicator_scan_status/schema.py | 69 ++++ .../actions/rescan_indicator/__init__.py | 2 + .../actions/rescan_indicator/action.py | 17 + .../actions/rescan_indicator/schema.py | 69 ++++ .../actions/takedown_request/__init__.py | 2 + .../actions/takedown_request/action.py | 17 + .../actions/takedown_request/schema.py | 74 ++++ .../icon_intsights/connection/schema.py | 4 +- .../icon_intsights/triggers/__init__.py | 1 + .../triggers/new_alert/__init__.py | 2 + .../triggers/new_alert/schema.py | 51 +++ .../triggers/new_alert/trigger.py | 21 ++ plugins/intsights/plugin.spec.yaml | 347 +++++++++++++++++- 30 files changed, 1393 insertions(+), 25 deletions(-) create mode 100755 plugins/intsights/icon_intsights/actions/enrich_indicator/__init__.py create mode 100755 plugins/intsights/icon_intsights/actions/enrich_indicator/action.py create mode 100755 plugins/intsights/icon_intsights/actions/enrich_indicator/schema.py create mode 100755 plugins/intsights/icon_intsights/actions/get_alerts/__init__.py create mode 100755 plugins/intsights/icon_intsights/actions/get_alerts/action.py create mode 100755 plugins/intsights/icon_intsights/actions/get_alerts/schema.py create mode 100755 plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/__init__.py create mode 100755 plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py create mode 100755 plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/schema.py create mode 100755 plugins/intsights/icon_intsights/actions/get_indicator_scan_status/__init__.py create mode 100755 plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py create mode 100755 plugins/intsights/icon_intsights/actions/get_indicator_scan_status/schema.py create mode 100755 plugins/intsights/icon_intsights/actions/rescan_indicator/__init__.py create mode 100755 plugins/intsights/icon_intsights/actions/rescan_indicator/action.py create mode 100755 plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py create mode 100755 plugins/intsights/icon_intsights/actions/takedown_request/__init__.py create mode 100755 plugins/intsights/icon_intsights/actions/takedown_request/action.py create mode 100755 plugins/intsights/icon_intsights/actions/takedown_request/schema.py create mode 100755 plugins/intsights/icon_intsights/triggers/new_alert/__init__.py create mode 100755 plugins/intsights/icon_intsights/triggers/new_alert/schema.py create mode 100755 plugins/intsights/icon_intsights/triggers/new_alert/trigger.py diff --git a/plugins/intsights/.CHECKSUM b/plugins/intsights/.CHECKSUM index f75f563ffa..277e89258a 100644 --- a/plugins/intsights/.CHECKSUM +++ b/plugins/intsights/.CHECKSUM @@ -1,15 +1,43 @@ { - "spec": "a157e0f22f3dd6b098eac5d6c3099242", - "manifest": "182eb71e6763e8f3044a2c18ccdd15a9", + "spec": "0efd3c2456192d58273be192f496e0bd", + "manifest": "908ff295279c09826a062779c0912477", "setup": "ea830b2af5f13706b38c5e288f0b6944", "schemas": [ + { + "identifier": "enrich_indicator/schema.py", + "hash": "2f448ecb5acfe3083dbbfa71da28a785" + }, + { + "identifier": "get_alerts/schema.py", + "hash": "09bb15b0d4612960fd2f9f24ce567e39" + }, + { + "identifier": "get_complete_alert_by_id/schema.py", + "hash": "fa71f1afe4b7a259160df71668a64e32" + }, { "identifier": "get_indicator_by_value/schema.py", - "hash": "e1f54a011120ea208c59ff2f24a3cec7" + "hash": "a1772f3da9138af8372809cfa8557f08" + }, + { + "identifier": "get_indicator_scan_status/schema.py", + "hash": "59446e651fbae06f439478b26ab45d3c" + }, + { + "identifier": "rescan_indicator/schema.py", + "hash": "dfe65b33ee30ec56a07c489d9f9c12a3" + }, + { + "identifier": "takedown_request/schema.py", + "hash": "3337b1c3fec8889cfdde0d62e7adda08" }, { "identifier": "connection/schema.py", - "hash": "1dfa7361a2d78e5dd4aaebfca7348c16" + "hash": "12bbf6684d6ecd35418685136b4437bd" + }, + { + "identifier": "new_alert/schema.py", + "hash": "ca5ffccc3606a5dde993f3c9688290c9" } ] } \ No newline at end of file diff --git a/plugins/intsights/Dockerfile b/plugins/intsights/Dockerfile index 6efb1c8f03..c9514d3520 100755 --- a/plugins/intsights/Dockerfile +++ b/plugins/intsights/Dockerfile @@ -21,6 +21,6 @@ RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi RUN python setup.py build && python setup.py install # User to run plugin code. The two supported users are: root, nobody -USER root +USER nobody ENTRYPOINT ["/usr/local/bin/icon_intsights"] \ No newline at end of file diff --git a/plugins/intsights/bin/icon_intsights b/plugins/intsights/bin/icon_intsights index 0bf41333a6..b275f574c4 100755 --- a/plugins/intsights/bin/icon_intsights +++ b/plugins/intsights/bin/icon_intsights @@ -34,8 +34,22 @@ def main(): description=Description, connection=connection.Connection() ) + self.add_trigger(triggers.NewAlert()) + + self.add_action(actions.EnrichIndicator()) + + self.add_action(actions.GetAlerts()) + + self.add_action(actions.GetCompleteAlertById()) + self.add_action(actions.GetIndicatorByValue()) + self.add_action(actions.GetIndicatorScanStatus()) + + self.add_action(actions.RescanIndicator()) + + self.add_action(actions.TakedownRequest()) + """Run plugin""" cli = insightconnect_plugin_runtime.CLI(ICONIntsights()) diff --git a/plugins/intsights/help.md b/plugins/intsights/help.md index 07c51309bc..fe42acd7f4 100755 --- a/plugins/intsights/help.md +++ b/plugins/intsights/help.md @@ -1,6 +1,6 @@ # Description -IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy +[IntSights](https://intsights.com/) is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy # Key Features @@ -23,15 +23,15 @@ The connection configuration accepts the following parameters: |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|account_id|credential_secret_key|None|True|Account id|None|{"secret_key": "account_id"}| -|api_key|credential_secret_key|None|True|API key|None|{"secret_key": "api_key"}| +|account_id|credential_secret_key|None|True|Account ID for IntSights|None|9de5069c5afe602b2ea0a04b| +|api_key|credential_secret_key|None|True|API key for IntSights|None|bffce7a2e653eb3e499b69238c6ed672727a642e6f07c19fe19b4d59c7a2d2a61078d1601ded75bac3859fc5c204279402ccf141e1999edf9deb47951f96f4c1| Example input: ``` { - "account_id": "{\"secret_key\": \"account_id\"}", - "api_key": "{\"secret_key\": \"api_key\"}" + "account_id": "9de5069c5afe602b2ea0a04b", + "api_key": "cc805d5fab1fd71a4ab352a9c533e65fb2d5b885518f4e565e68847223b8e6b85cb48f3afad842726d99239c9e36505c64b0dc9a061d9e507d833277ada336ab" } ``` @@ -39,6 +39,202 @@ Example input: ### Actions +#### Takedown Request + +This action is used to request a takedown for a given alert in Intsights. + +##### Input + +|Name|Type|Default|Required|Description|Enum|Example| +|----|----|-------|--------|-----------|----|-------| +|alert_id|string|None|True|Alert's unique ID|None|None| +|target|string|Domain|True|Target|['Website', 'Domain']|Domain| + +Example input: + +``` +{ + "target": "Domain" +} +``` + +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|response|object|True|Response from IntSights| + +Example output: + +``` +``` + +#### Get Complete Alert by ID + +This action is used to get an alert's complete details for a given alert ID. + +##### Input + +|Name|Type|Default|Required|Description|Enum|Example| +|----|----|-------|--------|-----------|----|-------| +|alert_id|string|None|True|Alert's unique ID|None|None| + +Example input: + +``` +``` + +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|assets|[]string|True|List of assets| +|assignees|[]string|True|List of assignees| +|details|object|True|Alert Details| +|found_date|date|True|Alert found date| +|id|string|True|Alert ID| +|is_closed|boolean|True|Is alert closed| +|is_flagged|boolean|True|Is alert flagged| +|leak_name|string|False|Name of the leak DBs in data leakage alerts| +|takedown_status|string|True|Alert remediation status| +|update_date|date|True|Alert update date| + +Example output: + +``` +``` + +#### Rescan Indicator + +This action is used to force an indicator scan in Intsights TIP system. + +##### Input + +|Name|Type|Default|Required|Description|Enum|Example| +|----|----|-------|--------|-----------|----|-------| +|indicator_value|string|None|True|IOC value in type file hash|None|None| + +Example input: + +``` +``` + +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|status|string|True|Status| +|task_id|string|True|Task ID| + +Example output: + +``` +``` + +#### Get Indicator Scan Status + +This action is used to get the scan status of an indicator in Insights TIP system. + +##### Input + +|Name|Type|Default|Required|Description|Enum|Example| +|----|----|-------|--------|-----------|----|-------| +|task_id|string|None|True|A string representing the request ID|None|None| + +Example input: + +``` +``` + +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|status|string|True|Status| +|task_id|string|True|Task ID| + +Example output: + +``` +``` + +#### Get Alerts + +This action is used to search Alerts based on criteria. + +##### Input + +|Name|Type|Default|Required|Description|Enum|Example| +|----|----|-------|--------|-----------|----|-------| +|alert_type|string|None|False|Comma separated list of alert types. Allowed values - AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip|None|None| +|assigned|boolean|None|False|Show assigned/unAssigned alerts|None|True| +|found_date_from|number|None|False|Start date to fetch from in Unix Millisecond Timestamp|None|0| +|found_date_to|number|None|False|End date to fetch to in Unix Millisecond Timestamp|None|None| +|has_indicators|boolean|None|False|Show alerts with IOCs results|None|False| +|is_closed|boolean|None|False|Is closed/open alerts|None|False| +|is_flagged|boolean|None|False|Show flagged/unflagged alerts|None|True| +|matched_asset_value|string|None|False|Comma separated list|None|None| +|network_type|string|None|False|Comma separated list of network type. Allowed values - ClearWeb, DarkWeb|None|None| +|remediation_status|string|None|False|Comma separated list of remediation status. Allowed values - InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed|None|None| +|severity|string|None|False|Comma separated list of alerts severity. Allowed values - High, Medium, Low|None|None| +|source_date_from|number|None|False|Start date to fetch from in Unix Millisecond Timestamp|None|None| +|source_date_to|number|None|False|End date to fetch to in Unix Millisecond Timestamp|None|None| +|source_type|string|None|False|Comma separated list of alerts source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others|None|None| + +Example input: + +``` +{ + "assigned": true, + "found_date_from": 0, + "has_indicators": false, + "is_closed": false, + "is_flagged": true +} +``` + +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|alert_ids|[]string|True|List of alert IDs| + +Example output: + +``` +``` + +#### Enrich Indicator + +This action is used to submit an indicator to IntSights for investigation and return the results. + +##### Input + +|Name|Type|Default|Required|Description|Enum|Example| +|----|----|-------|--------|-----------|----|-------| +|indicator_value|string|None|True|Value of the indicator|None|https://example.com| + +Example input: + +``` +{ + "indicator_value": "example.com" +} +``` + +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|data|object|True|Data| +|original_value|string|True|Original value| +|status|string|True|Status| + +Example output: + +``` +``` + #### Get Indicator by Value This action this action will search indicators in Intsights TIP. @@ -47,11 +243,14 @@ This action this action will search indicators in Intsights TIP. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_value|string|None|True|Indicator Value|None|None| +|indicator_value|string|None|True|Value of the indicator|None|https://example.com| Example input: ``` +{ + "indicator_value": "example.com" +} ``` ##### Output @@ -81,7 +280,24 @@ Example output: ### Triggers -_This plugin does not contain any triggers._ +#### New Alert + +This trigger is used to run when a new alert that matches the given criteria is created in IntSights. + +##### Input + +_This trigger does not contain any inputs._ + +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|response|[]string|True|Response| + +Example output: + +``` +``` ### Custom Output Types @@ -99,5 +315,5 @@ _This plugin does not contain any troubleshooting information._ ## References -* [IntSights](LINK TO PRODUCT/VENDOR WEBSITE) +* [IntSights](https://intsights.com/) diff --git a/plugins/intsights/icon_intsights/actions/__init__.py b/plugins/intsights/icon_intsights/actions/__init__.py index d45f597885..b0f3613f38 100755 --- a/plugins/intsights/icon_intsights/actions/__init__.py +++ b/plugins/intsights/icon_intsights/actions/__init__.py @@ -1,2 +1,8 @@ # GENERATED BY KOMAND SDK - DO NOT EDIT +from .enrich_indicator.action import EnrichIndicator +from .get_alerts.action import GetAlerts +from .get_complete_alert_by_id.action import GetCompleteAlertById from .get_indicator_by_value.action import GetIndicatorByValue +from .get_indicator_scan_status.action import GetIndicatorScanStatus +from .rescan_indicator.action import RescanIndicator +from .takedown_request.action import TakedownRequest diff --git a/plugins/intsights/icon_intsights/actions/enrich_indicator/__init__.py b/plugins/intsights/icon_intsights/actions/enrich_indicator/__init__.py new file mode 100755 index 0000000000..c437cb2736 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/enrich_indicator/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import EnrichIndicator diff --git a/plugins/intsights/icon_intsights/actions/enrich_indicator/action.py b/plugins/intsights/icon_intsights/actions/enrich_indicator/action.py new file mode 100755 index 0000000000..27f5d41c5e --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/enrich_indicator/action.py @@ -0,0 +1,17 @@ +import insightconnect_plugin_runtime +from .schema import EnrichIndicatorInput, EnrichIndicatorOutput, Input, Output, Component +# Custom imports below + + +class EnrichIndicator(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='enrich_indicator', + description=Component.DESCRIPTION, + input=EnrichIndicatorInput(), + output=EnrichIndicatorOutput()) + + def run(self, params={}): + # TODO: Implement run function + return {} diff --git a/plugins/intsights/icon_intsights/actions/enrich_indicator/schema.py b/plugins/intsights/icon_intsights/actions/enrich_indicator/schema.py new file mode 100755 index 0000000000..61e77e01a4 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/enrich_indicator/schema.py @@ -0,0 +1,77 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "Submit an indicator to IntSights for investigation and return the results" + + +class Input: + INDICATOR_VALUE = "indicator_value" + + +class Output: + DATA = "data" + ORIGINAL_VALUE = "original_value" + STATUS = "status" + + +class EnrichIndicatorInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "indicator_value": { + "type": "string", + "title": "Indicator Value", + "description": "Value of the indicator", + "order": 1 + } + }, + "required": [ + "indicator_value" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class EnrichIndicatorOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "data": { + "type": "object", + "title": "Data", + "description": "Data", + "order": 3 + }, + "original_value": { + "type": "string", + "title": "Original Value", + "description": "Original value", + "order": 1 + }, + "status": { + "type": "string", + "title": "Status", + "description": "Status", + "order": 2 + } + }, + "required": [ + "data", + "original_value", + "status" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/intsights/icon_intsights/actions/get_alerts/__init__.py b/plugins/intsights/icon_intsights/actions/get_alerts/__init__.py new file mode 100755 index 0000000000..368493f6b5 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/get_alerts/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import GetAlerts diff --git a/plugins/intsights/icon_intsights/actions/get_alerts/action.py b/plugins/intsights/icon_intsights/actions/get_alerts/action.py new file mode 100755 index 0000000000..2b3a236434 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/get_alerts/action.py @@ -0,0 +1,17 @@ +import insightconnect_plugin_runtime +from .schema import GetAlertsInput, GetAlertsOutput, Input, Output, Component +# Custom imports below + + +class GetAlerts(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='get_alerts', + description=Component.DESCRIPTION, + input=GetAlertsInput(), + output=GetAlertsOutput()) + + def run(self, params={}): + # TODO: Implement run function + return {} diff --git a/plugins/intsights/icon_intsights/actions/get_alerts/schema.py b/plugins/intsights/icon_intsights/actions/get_alerts/schema.py new file mode 100755 index 0000000000..b27fb41129 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/get_alerts/schema.py @@ -0,0 +1,152 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "Search Alerts based on criteria" + + +class Input: + ALERT_TYPE = "alert_type" + ASSIGNED = "assigned" + FOUND_DATE_FROM = "found_date_from" + FOUND_DATE_TO = "found_date_to" + HAS_INDICATORS = "has_indicators" + IS_CLOSED = "is_closed" + IS_FLAGGED = "is_flagged" + MATCHED_ASSET_VALUE = "matched_asset_value" + NETWORK_TYPE = "network_type" + REMEDIATION_STATUS = "remediation_status" + SEVERITY = "severity" + SOURCE_DATE_FROM = "source_date_from" + SOURCE_DATE_TO = "source_date_to" + SOURCE_TYPE = "source_type" + + +class Output: + ALERT_IDS = "alert_ids" + + +class GetAlertsInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "alert_type": { + "type": "string", + "title": "Alert Type", + "description": "Comma separated list of alert types. Allowed values - AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip", + "order": 1 + }, + "assigned": { + "type": "boolean", + "title": "Assigned", + "description": "Show assigned/unAssigned alerts", + "order": 11 + }, + "found_date_from": { + "type": "number", + "title": "Found Date From", + "description": "Start date to fetch from in Unix Millisecond Timestamp", + "order": 9 + }, + "found_date_to": { + "type": "number", + "title": "Found Date To", + "description": "End date to fetch to in Unix Millisecond Timestamp", + "order": 10 + }, + "has_indicators": { + "type": "boolean", + "title": "Has Indicators", + "description": "Show alerts with IOCs results", + "order": 14 + }, + "is_closed": { + "type": "boolean", + "title": "Is Closed", + "description": "Is closed/open alerts", + "order": 13 + }, + "is_flagged": { + "type": "boolean", + "title": "Is Flagged", + "description": "Show flagged/unflagged alerts", + "order": 12 + }, + "matched_asset_value": { + "type": "string", + "title": "Matched Asset Value", + "description": "Comma separated list", + "order": 5 + }, + "network_type": { + "type": "string", + "title": "Network Type", + "description": "Comma separated list of network type. Allowed values - ClearWeb, DarkWeb", + "order": 4 + }, + "remediation_status": { + "type": "string", + "title": "Remediation Status", + "description": "Comma separated list of remediation status. Allowed values - InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed", + "order": 6 + }, + "severity": { + "type": "string", + "title": "Severity", + "description": "Comma separated list of alerts severity. Allowed values - High, Medium, Low", + "order": 2 + }, + "source_date_from": { + "type": "number", + "title": "Source Date From", + "description": "Start date to fetch from in Unix Millisecond Timestamp", + "order": 7 + }, + "source_date_to": { + "type": "number", + "title": "Source Date To", + "description": "End date to fetch to in Unix Millisecond Timestamp", + "order": 8 + }, + "source_type": { + "type": "string", + "title": "Source Type", + "description": "Comma separated list of alerts source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others", + "order": 3 + } + } +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class GetAlertsOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "alert_ids": { + "type": "array", + "title": "Alert IDs", + "description": "List of alert IDs", + "items": { + "type": "string" + }, + "order": 1 + } + }, + "required": [ + "alert_ids" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/__init__.py b/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/__init__.py new file mode 100755 index 0000000000..103e9d30bf --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import GetCompleteAlertById diff --git a/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py b/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py new file mode 100755 index 0000000000..9d6e362368 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py @@ -0,0 +1,17 @@ +import insightconnect_plugin_runtime +from .schema import GetCompleteAlertByIdInput, GetCompleteAlertByIdOutput, Input, Output, Component +# Custom imports below + + +class GetCompleteAlertById(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='get_complete_alert_by_id', + description=Component.DESCRIPTION, + input=GetCompleteAlertByIdInput(), + output=GetCompleteAlertByIdOutput()) + + def run(self, params={}): + # TODO: Implement run function + return {} diff --git a/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/schema.py b/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/schema.py new file mode 100755 index 0000000000..e0e8973a7c --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/schema.py @@ -0,0 +1,142 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "Get an alert's complete details for a given alert ID" + + +class Input: + ALERT_ID = "alert_id" + + +class Output: + ASSETS = "assets" + ASSIGNEES = "assignees" + DETAILS = "details" + FOUND_DATE = "found_date" + ID = "id" + IS_CLOSED = "is_closed" + IS_FLAGGED = "is_flagged" + LEAK_NAME = "leak_name" + TAKEDOWN_STATUS = "takedown_status" + UPDATE_DATE = "update_date" + + +class GetCompleteAlertByIdInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "alert_id": { + "type": "string", + "title": "Alert ID", + "description": "Alert's unique ID", + "order": 1 + } + }, + "required": [ + "alert_id" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class GetCompleteAlertByIdOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "assets": { + "type": "array", + "title": "Assets", + "description": "List of assets", + "items": { + "type": "string" + }, + "order": 2 + }, + "assignees": { + "type": "array", + "title": "Assignees", + "description": "List of assignees", + "items": { + "type": "string" + }, + "order": 3 + }, + "details": { + "type": "object", + "title": "Details", + "description": "Alert Details", + "order": 4 + }, + "found_date": { + "type": "string", + "title": "Found Date", + "displayType": "date", + "description": "Alert found date", + "format": "date-time", + "order": 5 + }, + "id": { + "type": "string", + "title": "ID", + "description": "Alert ID", + "order": 1 + }, + "is_closed": { + "type": "boolean", + "title": "Is Closed", + "description": "Is alert closed", + "order": 8 + }, + "is_flagged": { + "type": "boolean", + "title": "Is Flagged", + "description": "Is alert flagged", + "order": 9 + }, + "leak_name": { + "type": "string", + "title": "Leak Name", + "description": "Name of the leak DBs in data leakage alerts", + "order": 10 + }, + "takedown_status": { + "type": "string", + "title": "Takedown Status", + "description": "Alert remediation status", + "order": 7 + }, + "update_date": { + "type": "string", + "title": "Found Date", + "displayType": "date", + "description": "Alert update date", + "format": "date-time", + "order": 6 + } + }, + "required": [ + "assets", + "assignees", + "details", + "found_date", + "id", + "is_closed", + "is_flagged", + "takedown_status", + "update_date" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py index 2892376571..7f271177a2 100755 --- a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py +++ b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py @@ -4,7 +4,7 @@ class Component: - DESCRIPTION = "This action will search indicators in Intsights TIP" + DESCRIPTION = "Search indicators in IntSights TIP" class Input: @@ -38,7 +38,7 @@ class GetIndicatorByValueInput(insightconnect_plugin_runtime.Input): "indicator_value": { "type": "string", "title": "Indicator Value", - "description": "Indicator Value", + "description": "Value of the indicator", "order": 1 } }, @@ -192,6 +192,7 @@ class GetIndicatorByValueOutput(insightconnect_plugin_runtime.Output): "ConfidenceLevel": { "type": "integer", "title": "Confidence Level", + "description": "Level of confidence", "order": 2 }, "Name": { diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/__init__.py b/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/__init__.py new file mode 100755 index 0000000000..60a69abe94 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import GetIndicatorScanStatus diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py b/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py new file mode 100755 index 0000000000..99fade5128 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py @@ -0,0 +1,17 @@ +import insightconnect_plugin_runtime +from .schema import GetIndicatorScanStatusInput, GetIndicatorScanStatusOutput, Input, Output, Component +# Custom imports below + + +class GetIndicatorScanStatus(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='get_indicator_scan_status', + description=Component.DESCRIPTION, + input=GetIndicatorScanStatusInput(), + output=GetIndicatorScanStatusOutput()) + + def run(self, params={}): + # TODO: Implement run function + return {} diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/schema.py b/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/schema.py new file mode 100755 index 0000000000..08da69a93a --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/schema.py @@ -0,0 +1,69 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "Get the scan status of an indicator in Insights TIP system" + + +class Input: + TASK_ID = "task_id" + + +class Output: + STATUS = "status" + TASK_ID = "task_id" + + +class GetIndicatorScanStatusInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "task_id": { + "type": "string", + "title": "Task ID", + "description": "A string representing the request ID", + "order": 1 + } + }, + "required": [ + "task_id" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class GetIndicatorScanStatusOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "status": { + "type": "string", + "title": "Status", + "description": "Status", + "order": 2 + }, + "task_id": { + "type": "string", + "title": "Task ID", + "description": "Task ID", + "order": 1 + } + }, + "required": [ + "status", + "task_id" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/intsights/icon_intsights/actions/rescan_indicator/__init__.py b/plugins/intsights/icon_intsights/actions/rescan_indicator/__init__.py new file mode 100755 index 0000000000..1a33d45f3b --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/rescan_indicator/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import RescanIndicator diff --git a/plugins/intsights/icon_intsights/actions/rescan_indicator/action.py b/plugins/intsights/icon_intsights/actions/rescan_indicator/action.py new file mode 100755 index 0000000000..f0df5cd09f --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/rescan_indicator/action.py @@ -0,0 +1,17 @@ +import insightconnect_plugin_runtime +from .schema import RescanIndicatorInput, RescanIndicatorOutput, Input, Output, Component +# Custom imports below + + +class RescanIndicator(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='rescan_indicator', + description=Component.DESCRIPTION, + input=RescanIndicatorInput(), + output=RescanIndicatorOutput()) + + def run(self, params={}): + # TODO: Implement run function + return {} diff --git a/plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py b/plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py new file mode 100755 index 0000000000..0281a8a52a --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py @@ -0,0 +1,69 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "Force an indicator scan in Intsights TIP system" + + +class Input: + INDICATOR_VALUE = "indicator_value" + + +class Output: + STATUS = "status" + TASK_ID = "task_id" + + +class RescanIndicatorInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "indicator_value": { + "type": "string", + "title": "Indicator Value", + "description": "IOC value in type file hash", + "order": 1 + } + }, + "required": [ + "indicator_value" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class RescanIndicatorOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "status": { + "type": "string", + "title": "Status", + "description": "Status", + "order": 2 + }, + "task_id": { + "type": "string", + "title": "Task ID", + "description": "Task ID", + "order": 1 + } + }, + "required": [ + "status", + "task_id" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/intsights/icon_intsights/actions/takedown_request/__init__.py b/plugins/intsights/icon_intsights/actions/takedown_request/__init__.py new file mode 100755 index 0000000000..d328efb579 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/takedown_request/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import TakedownRequest diff --git a/plugins/intsights/icon_intsights/actions/takedown_request/action.py b/plugins/intsights/icon_intsights/actions/takedown_request/action.py new file mode 100755 index 0000000000..ea34dc301c --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/takedown_request/action.py @@ -0,0 +1,17 @@ +import insightconnect_plugin_runtime +from .schema import TakedownRequestInput, TakedownRequestOutput, Input, Output, Component +# Custom imports below + + +class TakedownRequest(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='takedown_request', + description=Component.DESCRIPTION, + input=TakedownRequestInput(), + output=TakedownRequestOutput()) + + def run(self, params={}): + # TODO: Implement run function + return {} diff --git a/plugins/intsights/icon_intsights/actions/takedown_request/schema.py b/plugins/intsights/icon_intsights/actions/takedown_request/schema.py new file mode 100755 index 0000000000..aa60164206 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/takedown_request/schema.py @@ -0,0 +1,74 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "Request a takedown for a given alert in Intsights" + + +class Input: + ALERT_ID = "alert_id" + TARGET = "target" + + +class Output: + RESPONSE = "response" + + +class TakedownRequestInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "alert_id": { + "type": "string", + "title": "Alert ID", + "description": "Alert's unique ID", + "order": 1 + }, + "target": { + "type": "string", + "title": "Target", + "description": "Target", + "default": "Domain", + "enum": [ + "Website", + "Domain" + ], + "order": 2 + } + }, + "required": [ + "alert_id", + "target" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class TakedownRequestOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "response": { + "type": "object", + "title": "Response", + "description": "Response from IntSights", + "order": 1 + } + }, + "required": [ + "response" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/intsights/icon_intsights/connection/schema.py b/plugins/intsights/icon_intsights/connection/schema.py index 6b11706265..108dc0d32e 100755 --- a/plugins/intsights/icon_intsights/connection/schema.py +++ b/plugins/intsights/icon_intsights/connection/schema.py @@ -17,13 +17,13 @@ class ConnectionSchema(insightconnect_plugin_runtime.Input): "account_id": { "$ref": "#/definitions/credential_secret_key", "title": "Account ID", - "description": "Account id", + "description": "Account ID for IntSights", "order": 1 }, "api_key": { "$ref": "#/definitions/credential_secret_key", "title": "API Key", - "description": "API key", + "description": "API key for IntSights", "order": 2 } }, diff --git a/plugins/intsights/icon_intsights/triggers/__init__.py b/plugins/intsights/icon_intsights/triggers/__init__.py index bace8db897..9fb0d5a464 100755 --- a/plugins/intsights/icon_intsights/triggers/__init__.py +++ b/plugins/intsights/icon_intsights/triggers/__init__.py @@ -1 +1,2 @@ # GENERATED BY KOMAND SDK - DO NOT EDIT +from .new_alert.trigger import NewAlert diff --git a/plugins/intsights/icon_intsights/triggers/new_alert/__init__.py b/plugins/intsights/icon_intsights/triggers/new_alert/__init__.py new file mode 100755 index 0000000000..8d0f48bfdb --- /dev/null +++ b/plugins/intsights/icon_intsights/triggers/new_alert/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .trigger import NewAlert diff --git a/plugins/intsights/icon_intsights/triggers/new_alert/schema.py b/plugins/intsights/icon_intsights/triggers/new_alert/schema.py new file mode 100755 index 0000000000..0a6446b042 --- /dev/null +++ b/plugins/intsights/icon_intsights/triggers/new_alert/schema.py @@ -0,0 +1,51 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "Run when a new alert that matches the given criteria is created in IntSights" + + +class Input: + pass + + +class Output: + + RESPONSE = "response" + + +class NewAlertInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + {} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class NewAlertOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "response": { + "type": "array", + "title": "Response", + "description": "Response", + "items": { + "type": "string" + }, + "order": 1 + } + }, + "required": [ + "response" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/intsights/icon_intsights/triggers/new_alert/trigger.py b/plugins/intsights/icon_intsights/triggers/new_alert/trigger.py new file mode 100755 index 0000000000..6ca40aad2d --- /dev/null +++ b/plugins/intsights/icon_intsights/triggers/new_alert/trigger.py @@ -0,0 +1,21 @@ +import insightconnect_plugin_runtime +import time +from .schema import NewAlertInput, NewAlertOutput, Input, Output, Component +# Custom imports below + + +class NewAlert(insightconnect_plugin_runtime.Trigger): + + def __init__(self): + super(self.__class__, self).__init__( + name='new_alert', + description=Component.DESCRIPTION, + input=NewAlertInput(), + output=NewAlertOutput()) + + def run(self, params={}): + """Run the trigger""" + while True: + # TODO: Implement trigger functionality + self.send({}) + time.sleep(params.get("interval", 5)) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 3ea82aa860..b59cfdf57c 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -5,8 +5,9 @@ name: intsights title: IntSights description: IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy version: 1.0.0 +supported_versions: [] vendor: rapid7 -support: community +support: rapid7 status: [] resources: source_url: https://github.com/rapid7/insightconnect-plugins/tree/master/plugins/intsights @@ -18,41 +19,44 @@ tags: - threatintelligence hub_tags: use_cases: [data_utility, threat_detection_and_response] - keywords: [elasticsearch, search, elastic] + keywords: [threat_intelligence, phishing, remediation, block, malware_analysis] features: [] types: source: Name: title: Name + descirption: Name type: string required: true ConfidenceLevel: title: Confidence Level + description: Level of confidence type: integer required: true connection: account_id: title: Account ID - description: Account id + description: Account ID for IntSights type: credential_secret_key required: true - example: '{"secret_key": "account_id"}' + example: 9de5069c5afe602b2ea0a04b api_key: title: API Key - description: API key + description: API key for IntSights type: credential_secret_key required: true - example: '{"secret_key": "api_key"}' + example: cc805d5fab1fd71a4ab352a9c533e65fb2d5b885518f4e565e68847223b8e6b85cb48f3afad842726d99239c9e36505c64b0dc9a061d9e507d833277ada336ab actions: get_indicator_by_value: title: Get Indicator by Value - description: This action will search indicators in Intsights TIP + description: Search indicators in IntSights TIP input: indicator_value: title: Indicator Value - description: Indicator Value + description: Value of the indicator type: string required: true + example: example.com output: value: title: Value @@ -129,3 +133,330 @@ actions: description: Related Threat Actors type: '[]string' required: true + enrich_indicator: + title: Enrich Indicator + description: Submit an indicator to IntSights for investigation and return the results + input: + indicator_value: + title: Indicator Value + description: Value of the indicator + type: string + required: true + example: example.com + output: + original_value: + title: Original Value + description: Original value + type: string + required: true + status: + title: Status + description: Status + type: string + required: true + data: + title: Data + description: Data + type: object + required: true + rescan_indicator: + title: Rescan Indicator + description: Force an indicator scan in Intsights TIP system + input: + indicator_value: + title: Indicator Value + description: IOC value in type file hash + type: string + required: true + output: + task_id: + title: Task ID + description: Task ID + type: string + required: true + status: + title: Status + description: Status + type: string + required: true + get_indicator_scan_status: + title: Get Indicator Scan Status + description: Get the scan status of an indicator in Insights TIP system + input: + task_id: + title: Task ID + description: A string representing the request ID + type: string + required: true + output: + task_id: + title: Task ID + description: Task ID + type: string + required: true + status: + title: Status + description: Status + type: string + required: true + get_alerts: + title: Get Alerts + description: Search Alerts based on criteria + input: + alert_type: + title: Alert Type + description: Comma separated list of alert types. Allowed values - AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip + type: string + required: false + severity: + title: Severity + description: Comma separated list of alerts severity. Allowed values - High, Medium, Low + type: string + required: false + source_type: + title: Source Type + description: Comma separated list of alerts source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others + type: string + required: false + network_type: + title: Network Type + description: Comma separated list of network type. Allowed values - ClearWeb, DarkWeb + type: string + required: false + matched_asset_value: + title: Matched Asset Value + description: Comma separated list + type: string + required: false + remediation_status: + title: Remediation Status + description: Comma separated list of remediation status. Allowed values - InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed + type: string + required: false + source_date_from: + title: Source Date From + description: Start date to fetch from in Unix Millisecond Timestamp + type: number + required: false + source_date_to: + title: Source Date To + description: End date to fetch to in Unix Millisecond Timestamp + type: number + required: false + found_date_from: + title: Found Date From + description: Start date to fetch from in Unix Millisecond Timestamp + type: number + required: false + example: 0 + found_date_to: + title: Found Date To + description: End date to fetch to in Unix Millisecond Timestamp + type: number + required: false + assigned: + title: Assigned + description: Show assigned/unAssigned alerts + type: boolean + required: false + example: true + is_flagged: + title: Is Flagged + description: Show flagged/unflagged alerts + type: boolean + required: false + example: true + is_closed: + title: Is Closed + description: Is closed/open alerts + type: boolean + required: false + example: false + has_indicators: + title: Has Indicators + description: Show alerts with IOCs results + type: boolean + required: false + example: false + output: + alert_ids: + title: Alert IDs + description: List of alert IDs + type: "[]string" + required: true + get_complete_alert_by_id: + title: Get Complete Alert by ID + description: Get an alert's complete details for a given alert ID + input: + alert_id: + title: Alert ID + description: Alert's unique ID + type: string + required: true + output: + id: + title: ID + description: Alert ID + type: string + required: true + assets: + title: Assets + description: List of assets + type: "[]string" + required: true + assignees: + title: Assignees + description: List of assignees + type: "[]string" + required: true + details: + title: Details + description: Alert Details + type: object + required: true + found_date: + title: Found Date + description: Alert found date + type: date + required: true + update_date: + title: Found Date + description: Alert update date + type: date + required: true + takedown_status: + title: Takedown Status + description: Alert remediation status + type: string + required: true + is_closed: + title: Is Closed + description: Is alert closed + type: boolean + required: true + is_flagged: + title: Is Flagged + description: Is alert flagged + type: boolean + required: true + leak_name: + title: Leak Name + description: Name of the leak DBs in data leakage alerts + type: string + required: false + takedown_request: + title: Takedown Request + description: Request a takedown for a given alert in Intsights + input: + alert_id: + title: Alert ID + description: Alert's unique ID + type: string + required: true + target: + title: Target + description: Target + type: string + required: true + enum: + - Website + - Domain + default: Domain + example: Domain + output: + response: + title: Response + description: Response from IntSights + type: object + required: true + +triggers: + new_alert: + title: New Alert + description: Run when a new alert that matches the given criteria is created in IntSights + inputs: + alert_type: + title: Alert Type + description: Coma separated list of alerts type. Allowed values - AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip + type: string + required: false + example: AttackIndication, DataLeakage + severity: + title: Severity + description: Coma separated list of severity. Allowed values - High, Medium, Low + type: string + required: false + example: High + source_type: + title: Source Type + description: Coma separated list of source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others + type: string + required: false + example: ApplicationStores, BlackMarkets + network_type: + title: Network Type + description: Coma separated list of network type. Allowed values - ClearWeb, DarkWeb + type: string + required: false + example: ClearWeb + matched_asset_value: + title: Matched Asset Value + description: Coma separated list of network matched asset value + type: string + required: false + remediation_status: + title: Remediation Status + description: Coma separated list of alert's remediation status. Allowed values - InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed + type: string + required: false + source_date_from: + title: Source Date From + description: Start date to fetch from in Unix Millisecond Timestamp + type: number + required: false + end_date_to: + title: End Date To + description: End date to fetch to in Unix Millisecond Timestam + type: number + required: false + found_date_from: + title: Found Date From + description: Start date to fetch from in Unix Millisecond Timestamp + type: number + required: false + example: 0 + found_date_to: + title: Found Date To + description: End date to fetch to in Unix Millisecond Timestamp + type: number + required: false + assigned: + title: Assigned + description: Show assigned/unAssigned alerts + type: boolean + required: false + example: true + is_flagged: + title: Is Flagged + description: Show flagged/unflagged alerts + type: boolean + required: false + example: true + is_closed: + title: Is Closed + description: Is closed/open alerts + type: boolean + required: false + example: false + has_indicators: + title: Has Indicators + description: Show alerts with IOCs results + type: boolean + required: false + example: false + output: + response: + title: Response + description: Response + type: "[]string" + required: true \ No newline at end of file From daf88b31585efe7fcc508599cae53a308034d74d Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Tue, 21 Sep 2021 17:23:35 +0200 Subject: [PATCH 03/60] [MC-717] Add action Get Indicator By Value --- plugins/intsights/.CHECKSUM | 4 +- plugins/intsights/help.md | 214 +++++++++++++++++- .../actions/enrich_indicator/action.py | 8 +- .../actions/get_indicator_by_value/action.py | 7 +- .../actions/get_indicator_by_value/schema.py | 9 +- plugins/intsights/icon_intsights/util/api.py | 15 +- plugins/intsights/plugin.spec.yaml | 16 +- .../enrich_indicator-in_progress.json.resp | 4 + .../payloads/enrich_indicator.json.resp | 4 + .../intsights/unit_test/test_connection.py | 2 +- .../unit_test/test_enrich_indicator.py | 41 ++++ .../unit_test/test_get_indicator_by_value.py | 9 +- plugins/intsights/unit_test/util.py | 13 +- plugins/microsoft_atp/.CHECKSUM | 2 +- plugins/microsoft_atp/help.md | 44 ++-- 15 files changed, 322 insertions(+), 70 deletions(-) create mode 100644 plugins/intsights/unit_test/payloads/enrich_indicator-in_progress.json.resp create mode 100644 plugins/intsights/unit_test/payloads/enrich_indicator.json.resp create mode 100644 plugins/intsights/unit_test/test_enrich_indicator.py diff --git a/plugins/intsights/.CHECKSUM b/plugins/intsights/.CHECKSUM index 277e89258a..3bef03d265 100644 --- a/plugins/intsights/.CHECKSUM +++ b/plugins/intsights/.CHECKSUM @@ -1,5 +1,5 @@ { - "spec": "0efd3c2456192d58273be192f496e0bd", + "spec": "a820b26f2d06d061efd629ceb33890e0", "manifest": "908ff295279c09826a062779c0912477", "setup": "ea830b2af5f13706b38c5e288f0b6944", "schemas": [ @@ -17,7 +17,7 @@ }, { "identifier": "get_indicator_by_value/schema.py", - "hash": "a1772f3da9138af8372809cfa8557f08" + "hash": "3bc77481896bc956c08c47ead9d243b2" }, { "identifier": "get_indicator_scan_status/schema.py", diff --git a/plugins/intsights/help.md b/plugins/intsights/help.md index fe42acd7f4..a42d5b6b11 100755 --- a/plugins/intsights/help.md +++ b/plugins/intsights/help.md @@ -233,6 +233,204 @@ Example input: Example output: ``` +{ + "data": { + "Subdomains": [ + "itunes", + "apps" + ], + "Tags": [], + "Type": "Domains", + "Value": "apple.com", + "Whitelisted": true, + "IsKnownIoc": false, + "RelatedHashes": { + "downloaded": [ + "5d8c914e53bf34fdeac7441b99fe412240a1211fe2e074dfb2...", + "7d2970c279d399214f83f140bb509441e9ae7262f98e8ae41f..." + ], + "referencing": [ + "004b5bb9d28f03397ab3462863cd5902", + "00f44bc82df0e8808b70abad0993bdb3" + ], + "communicating": [ + "03b0f52b4d517d2a4f8a7994acd26adb77b8c7d9b25ef37c9a...", + "09277de376a14f6475a242ca9ad4743dc81bd951853228d625..." + ] + }, + "RelatedThreatActors": [], + "Sources": [], + "Whois": { + "Current": { + "RegistrantDetails": [ + { + "City": "Cupertino", + "Country": "UNITED STATES", + "CountryCode": "US", + "PostalCode": "95014", + "Telephone": "14089961010", + "State": "", + "Address": "One Apple Park Way", + "Email": "user@example.com", + "Fax": "14089741560", + "Name": "Apple Inc.", + "Organization": "Apple Inc." + } + ], + "RegistrationDetails": { + "CreatedDate": "1987-02-19T00:00:00.000Z", + "ExpiresDate": "2022-02-20T05:00:00.000Z", + "NameServers": [ + "b.ns.apple.com", + "a.ns.apple.com" + ], + "Statuses": [ + "clientTransferProhibited", + "serverDeleteProhibited" + ], + "UpdatedDate": "2021-02-16T01:26:20.000Z" + } + }, + "History": [ + { + "RegistrantDetails": [ + { + "Address": "1 Infinite Loop", + "Country": "UNITED STATES", + "Fax": "14089741560", + "Name": "Domain Administrator", + "Telephone": "14089961010", + "State": "CA", + "City": "Cupertino", + "CountryCode": "", + "Email": "user@example.com", + "Organization": "Apple Inc.", + "PostalCode": "95014" + }, + { + "Address": "1 Infinite Loop", + "CountryCode": "", + "Email": "user@example.com", + "Fax": "14089741560", + "Organization": "Apple Inc.", + "Telephone": "14089961010", + "City": "Cupertino", + "Country": "UNITED STATES", + "Name": "Domain Administrator", + "PostalCode": "95014", + "State": "CA" + } + ], + "RegistrationDetails": { + "CreatedDate": "1987-02-19T01:27:12.000Z", + "ExpiresDate": "2021-02-20T01:27:12.000Z", + "NameServers": [ + "ADNS1.APPLE.COM", + "ADNS2.APPLE.COM" + ], + "Statuses": [ + "clientTransferProhibited" + ], + "UpdatedDate": "2012-12-04T01:27:12.000Z" + } + }, + { + "RegistrantDetails": [ + { + "City": "Cupertino", + "CountryCode": "", + "Email": "user@example.com", + "Fax": "", + "Name": "Domain Administrator", + "State": "CA", + "Telephone": "14089961010", + "Address": "1 Infinite Loop", + "Organization": "Apple Inc.", + "PostalCode": "95014", + "Country": "UNITED STATES" + }, + { + "Address": "1 Infinite Loop", + "City": "Cupertino", + "Fax": "", + "PostalCode": "95014", + "State": "CA", + "Telephone": "14089961010", + "Country": "UNITED STATES", + "CountryCode": "", + "Email": "user@example.com", + "Name": "Domain Administrator", + "Organization": "Apple Inc." + } + ], + "RegistrationDetails": { + "UpdatedDate": "2012-12-04T13:10:47.000Z", + "CreatedDate": "1987-02-19T13:10:47.000Z", + "ExpiresDate": "2021-02-20T13:10:47.000Z", + "NameServers": [ + "ADNS1.APPLE.COM", + "ADNS2.APPLE.COM" + ], + "Statuses": [ + "clientTransferProhibited" + ] + } + } + ] + }, + "DnsRecords": [ + { + "Type": "NS", + "Value": "a.ns.apple.com.", + "Count": 123, + "FirstResolved": null, + "LastResolved": null + }, + { + "FirstResolved": null, + "LastResolved": null, + "Type": "NS", + "Value": "b.ns.apple.com.", + "Count": 123 + } + ], + "RelatedMalwares": [], + "Resolutions": [ + { + "ResolvedIpAddress": "17.253.144.10", + "ASN": 714, + "FirstResolved": "2020-10-09T02:47:17.000Z", + "LastResolved": "2021-09-18T13:35:55.000Z", + "Location": "US", + "Operator": "Apple Inc.", + "ReportingSources": [ + "Farsight", + "VirusTotal" + ] + }, + { + "ResolvedIpAddress": "17.142.160.59", + "ASN": 714, + "FirstResolved": "2014-07-09T16:35:28.000Z", + "LastResolved": "2020-10-09T03:00:19.000Z", + "Location": "US", + "Operator": "Apple Inc.", + "ReportingSources": [ + "Farsight", + "VirusTotal" + ] + } + ], + "SystemTags": [], + "RelatedCampaigns": [], + "Severity": { + "Score": 0, + "Value": "Low" + } + }, + "original_value": "apple.com", + "status": "Done" +} ``` #### Get Indicator by Value @@ -257,21 +455,21 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|first_seen|string|True|First Seen| -|geo_location|string|True|GEO Location| -|last_seen|string|True|Last Seen| -|last_update|string|True|Last Update| +|first_seen|string|False|First Seen| +|geo_location|string|False|GEO Location| +|last_seen|string|False|Last Seen| +|last_update|string|False|Last Update| |related_campaigns|[]string|True|Related Campaigns| |related_malware|[]string|True|Related Malware| |related_threat_actors|[]string|True|Related Threat Actors| |score|integer|True|Score| -|severity|string|True|Severity| +|severity|string|False|Severity| |sources|[]source|True|Sources| |system_tags|[]string|True|System Tags| |tags|[]string|True|Tags| -|type|string|True|Type| -|value|string|True|Value| -|whitelist|string|True|Whitelist| +|type|string|False|Type| +|value|string|False|Value| +|whitelist|boolean|True|Whitelist| Example output: diff --git a/plugins/intsights/icon_intsights/actions/enrich_indicator/action.py b/plugins/intsights/icon_intsights/actions/enrich_indicator/action.py index 27f5d41c5e..604117e776 100755 --- a/plugins/intsights/icon_intsights/actions/enrich_indicator/action.py +++ b/plugins/intsights/icon_intsights/actions/enrich_indicator/action.py @@ -13,5 +13,9 @@ def __init__(self): output=EnrichIndicatorOutput()) def run(self, params={}): - # TODO: Implement run function - return {} + response = self.connection.client.enrich_indicator(params.get(Input.INDICATOR_VALUE)) + return { + Output.ORIGINAL_VALUE: response.get('OriginalValue'), + Output.STATUS: response.get('Status'), + Output.DATA: response.get('Data', {}) + } diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py index 5eafeee39b..728c5612de 100755 --- a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py +++ b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py @@ -1,6 +1,7 @@ import insightconnect_plugin_runtime from .schema import GetIndicatorByValueInput, GetIndicatorByValueOutput, Input, Output, Component # Custom imports below +from insightconnect_plugin_runtime.helper import clean class GetIndicatorByValue(insightconnect_plugin_runtime.Action): @@ -14,12 +15,12 @@ def __init__(self): def run(self, params={}): response = self.connection.client.get_indicator_by_value(params.get(Input.INDICATOR_VALUE)) - return { + return clean({ Output.VALUE: response.get('Value'), Output.TYPE: response.get('Type'), Output.SEVERITY: response.get('Severity'), Output.SCORE: response.get('Score', 0), - Output.WHITELIST: response.get('Whitelist'), + Output.WHITELIST: response.get('Whitelist', False), Output.FIRST_SEEN: response.get('FirstSeen'), Output.LAST_SEEN: response.get('LastSeen'), Output.LAST_UPDATE: response.get('LastUpdate'), @@ -30,4 +31,4 @@ def run(self, params={}): Output.RELATED_MALWARE: response.get('RelatedMalware', []), Output.RELATED_CAMPAIGNS: response.get('RelatedCampaigns', []), Output.RELATED_THREAT_ACTORS: response.get('RelatedThreatActors', []), - } + }) diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py index 7f271177a2..e11d5e2e37 100755 --- a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py +++ b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py @@ -161,27 +161,20 @@ class GetIndicatorByValueOutput(insightconnect_plugin_runtime.Output): "order": 1 }, "whitelist": { - "type": "string", + "type": "boolean", "title": "Whitelist", "description": "Whitelist", "order": 5 } }, "required": [ - "first_seen", - "geo_location", - "last_seen", - "last_update", "related_campaigns", "related_malware", "related_threat_actors", "score", - "severity", "sources", "system_tags", "tags", - "type", - "value", "whitelist" ], "definitions": { diff --git a/plugins/intsights/icon_intsights/util/api.py b/plugins/intsights/icon_intsights/util/api.py index 4346cffc33..4c9f7cd91c 100644 --- a/plugins/intsights/icon_intsights/util/api.py +++ b/plugins/intsights/icon_intsights/util/api.py @@ -1,4 +1,6 @@ import json +import time + import requests from insightconnect_plugin_runtime.exceptions import PluginException from requests.auth import HTTPBasicAuth @@ -8,7 +10,7 @@ class IntSightAPI: def __init__(self, account_id, api_key): self.account_id = account_id self.api_key = api_key - self.url = 'https://api.intsights.com/public/v1' + self.url = 'https://api.intsights.com' def get_indicator_by_value(self, ioc_value: str) -> dict: response = self.make_request('GET', f'public/v2/iocs/ioc-by-value?iocValue={ioc_value}') @@ -17,8 +19,17 @@ def get_indicator_by_value(self, ioc_value: str) -> dict: return response.json() + def enrich_indicator(self, ioc_value: str) -> dict: + while True: + response = self.make_request('GET', f'public/v1/iocs/enrich/{ioc_value}').json() + if response.get('Status', 'InProgress') in ['Done', 'Failed']: + break + time.sleep(5) + + return response + def test_credentials(self) -> bool: - return self.make_request('HEAD', 'test-credentials').status_code == 200 + return self.make_request('HEAD', 'public/v1/test-credentials').status_code == 200 def make_request(self, method: str, path: str) -> requests.Response: try: diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index b59cfdf57c..33e78bf9b2 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -62,17 +62,17 @@ actions: title: Value description: Value type: string - required: true + required: false type: title: Type description: Type type: string - required: true + required: false severity: title: Severity description: Severity type: string - required: true + required: false score: title: Score description: Score @@ -81,28 +81,28 @@ actions: whitelist: title: Whitelist description: Whitelist - type: string + type: boolean required: true first_seen: title: First Seen description: First Seen type: string - required: true + required: false last_seen: title: Last Seen description: Last Seen type: string - required: true + required: false last_update: title: Last Update description: Last Update type: string - required: true + required: false geo_location: title: GEO Location description: GEO Location type: string - required: true + required: false sources: title: Sources description: Sources diff --git a/plugins/intsights/unit_test/payloads/enrich_indicator-in_progress.json.resp b/plugins/intsights/unit_test/payloads/enrich_indicator-in_progress.json.resp new file mode 100644 index 0000000000..618c9d8350 --- /dev/null +++ b/plugins/intsights/unit_test/payloads/enrich_indicator-in_progress.json.resp @@ -0,0 +1,4 @@ +{ + "Status": "InProgress", + "OriginalValue": "example.com" +} \ No newline at end of file diff --git a/plugins/intsights/unit_test/payloads/enrich_indicator.json.resp b/plugins/intsights/unit_test/payloads/enrich_indicator.json.resp new file mode 100644 index 0000000000..0b077e4dd1 --- /dev/null +++ b/plugins/intsights/unit_test/payloads/enrich_indicator.json.resp @@ -0,0 +1,4 @@ +{ + "Status": "Done", + "OriginalValue": "example.com" +} \ No newline at end of file diff --git a/plugins/intsights/unit_test/test_connection.py b/plugins/intsights/unit_test/test_connection.py index 2ec53824d2..4da6ccb56a 100644 --- a/plugins/intsights/unit_test/test_connection.py +++ b/plugins/intsights/unit_test/test_connection.py @@ -23,7 +23,7 @@ def test_connection_should_success_when_credentials(self, mock_request) -> None: Input.ACCOUNT_ID: {'secretKey': 'account_id'} }) - self.assertEqual("https://api.intsights.com/public/v1", action.connection.client.url) + self.assertEqual("https://api.intsights.com", action.connection.client.url) self.assertEqual("api_key", action.connection.client.api_key) self.assertEqual("account_id", action.connection.client.account_id) diff --git a/plugins/intsights/unit_test/test_enrich_indicator.py b/plugins/intsights/unit_test/test_enrich_indicator.py new file mode 100644 index 0000000000..c611230a2d --- /dev/null +++ b/plugins/intsights/unit_test/test_enrich_indicator.py @@ -0,0 +1,41 @@ +import sys +import os +import time + +sys.path.append(os.path.abspath('../')) + +from unittest import TestCase +from unittest.mock import patch +from unit_test.util import Util +from icon_intsights.actions.enrich_indicator import EnrichIndicator +from icon_intsights.actions.enrich_indicator.schema import Input + + +class TestEnrichIndicator(TestCase): + @classmethod + @patch("requests.request", side_effect=Util.mock_request) + def setUpClass(cls, mock_request) -> None: + Util.request_count = 0 + cls.action = Util.default_connector(EnrichIndicator()) + + @patch("requests.request", side_effect=Util.mock_request) + def test_enrich_indicator_should_success(self, make_request): + Util.request_count = 1 + actual = self.action.run({Input.INDICATOR_VALUE: 'example.com'}) + Util.request_count = 0 + expected = { + 'data': {}, + 'original_value': 'example.com', + 'status': 'Done' + } + self.assertEqual(expected, actual) + + @patch("requests.request", side_effect=Util.mock_request) + def test_enrich_indicator_should_success_when_in_progress(self, make_request): + Util.request_count = 0 + time_start = time.time() + self.action.run({Input.INDICATOR_VALUE: 'example.com'}) + expected = 1 + expected_time_elapsed = time.time() - time_start + self.assertEqual(expected, Util.request_count) + self.assertTrue(expected_time_elapsed > 5) diff --git a/plugins/intsights/unit_test/test_get_indicator_by_value.py b/plugins/intsights/unit_test/test_get_indicator_by_value.py index c8e6b323b6..6d5857fd18 100644 --- a/plugins/intsights/unit_test/test_get_indicator_by_value.py +++ b/plugins/intsights/unit_test/test_get_indicator_by_value.py @@ -42,20 +42,13 @@ def test_get_indicator_by_value_should_success(self, make_request): def test_get_indicator_by_value_should_success_when_empty(self, make_request): actual = self.action.run({Input.INDICATOR_VALUE: 'empty'}) expected = { - 'first_seen': None, - 'geo_location': None, - 'last_seen': None, - 'last_update': None, 'related_campaigns': [], 'related_malware': [], 'related_threat_actors': [], 'score': 0, - 'severity': None, 'sources': [], 'system_tags': [], 'tags': [], - 'type': None, - 'value': None, - 'whitelist': None + 'whitelist': False } self.assertEqual(expected, actual) diff --git a/plugins/intsights/unit_test/util.py b/plugins/intsights/unit_test/util.py index 813756fae9..5c71065da3 100644 --- a/plugins/intsights/unit_test/util.py +++ b/plugins/intsights/unit_test/util.py @@ -6,6 +6,8 @@ class Util: + request_count = 0 + @staticmethod def default_connector(action, connect_params: object = None): default_connection = Connection() @@ -43,10 +45,15 @@ def json(self): return MockResponse(401) elif kwargs.get('url') == 'https://api.intsights.com/public/v1/test-credentials': return MockResponse(200) - elif kwargs.get( - 'url') == 'https://api.intsights.com/public/v1/public/v2/iocs/ioc-by-value?iocValue=example.com': + elif kwargs.get('url') == 'https://api.intsights.com/public/v2/iocs/ioc-by-value?iocValue=example.com': return MockResponse(200, 'iocs_ioc-by-value') - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/public/v2/iocs/ioc-by-value?iocValue=empty': + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/enrich/example.com' \ + and Util.request_count == 0: + Util.request_count = Util.request_count + 1 + return MockResponse(200, 'enrich_indicator-in_progress') + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/enrich/example.com': + return MockResponse(200, 'enrich_indicator') + elif kwargs.get('url') == 'https://api.intsights.com/public/v2/iocs/ioc-by-value?iocValue=empty': return MockResponse(204) else: raise NotImplementedError('Not implemented') diff --git a/plugins/microsoft_atp/.CHECKSUM b/plugins/microsoft_atp/.CHECKSUM index 42ed99bb8b..f898684e59 100644 --- a/plugins/microsoft_atp/.CHECKSUM +++ b/plugins/microsoft_atp/.CHECKSUM @@ -1,5 +1,5 @@ { - "spec": "973667a57579262af1678d0236ae8c9a", + "spec": "02ab4b32669fc75b47f89f41108efc88", "manifest": "d046d7ea8bb7e5e0d7555d28f5588dda", "setup": "273e654e5089823d8aa45a3acd2c1306", "schemas": [ diff --git a/plugins/microsoft_atp/help.md b/plugins/microsoft_atp/help.md index 9c4da5b956..a019a268d3 100644 --- a/plugins/microsoft_atp/help.md +++ b/plugins/microsoft_atp/help.md @@ -15,14 +15,13 @@ This plugin utilizes the [Microsoft ATP API](https://docs.microsoft.com/en-us/wi * Windows Defender Advanced Threat Protection application credentials -# Documentation +# Supported Product Versions -## Setup +_There are no supported product versions listed._ -This plugin uses the Windows Defender ATP API. It will use an Azure application to connect to the API and run actions from InsightConnect. +# Documentation -For information on how to setup your application and assign permissions go here: -https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/exposed-apis-create-app-webapp +## Setup The connection configuration accepts the following parameters: @@ -55,7 +54,7 @@ This action collects investigation package from a machine. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| |comment|string|Investigation package collected via InsightConnect|False|Comment to associate with the action|None|Investigation package collected via InsightConnect| -|machine|string|None|True|Machine IP address, hostname, or machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| +|machine|string|None|True|Machine IP address, hostname, or machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| Example input: @@ -102,7 +101,7 @@ This action is used to get machines related to an file hash(SHA1), domain or use |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator|string|None|True|File hash(SHA1), domain or username indicator|None|example.com| +|indicator|string|None|True|File hash(SHA1), domain or username indicator|None|https://example.com| Example input: @@ -158,7 +157,7 @@ This action is used to add or remove machine tags. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|machine|string|None|True|Machine IP address, hostname, or machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| +|machine|string|None|True|Machine IP address, hostname, or machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| |tag|string|None|True|The tag value|None|example tag| |type|boolean|True|True|True to add tag, false to remove it|None|True| @@ -214,7 +213,7 @@ This action retrieves a collection of installed software related to a given mach |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|machine|string|None|True|Machine IP address, hostname, or machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| +|machine|string|None|True|Machine IP address, hostname, or machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| Example input: @@ -267,7 +266,7 @@ This action is used to retrieve a list of software updates. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|machine|string|None|True|Machine IP address, hostname or machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| +|machine|string|None|True|Machine IP address, hostname or machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| Example input: @@ -312,7 +311,7 @@ This action is used to retrieve a list of security recommendations. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|machine|string|None|True|Machine IP address, hostname or machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| +|machine|string|None|True|Machine IP address, hostname or machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| Example input: @@ -369,7 +368,7 @@ This action is used to submit or update new indicator. |application|string|None|False|The application associated with the indicator|None|demo-test| |description|string|Indicator Blacklisted from InsightConnect|False|Description of the indicator|None|Indicator Blacklisted from InsightConnect| |expiration_time|string|None|False|The expiration time of the indicator, default value is one year from now|None|2020-12-12T00:00:00Z| -|indicator|string|None|True|A supported indicator to blacklist or unblacklist. Supported indicators are IP addresses, URLs, domains, and SHA1 and SHA256 hashes|None|220e7d15b011d7fac48f2bd61114db1022197f7f| +|indicator|string|None|True|A supported indicator to blacklist or unblacklist. Supported indicators are IP addresses, URLs, domains, and SHA1 and SHA256 hashes|None|02699626f388ed830012e5b787640e71c56d42d8| |indicator_state|boolean|False|False|True to add indicator, false to remove it from the list|None|True| |rbac_group_names|[]string|None|False|List of RBAC group names the indicator would be applied to|None|["group1","group2"]| |recommended_actions|string|None|False|TI indicator alert recommended actions|None|nothing| @@ -386,10 +385,7 @@ Example input: "expiration_time": "2020-12-12T00:00:00Z", "indicator": "220e7d15b011d7fac48f2bd61114db1022197f7f", "indicator_state": true, - "rbac_group_names": [ - "group1", - "group2" - ], + "rbac_group_names": "[\"group1\",\"group2\"]", "recommended_actions": "nothing", "severity": "High", "title": "test" @@ -444,7 +440,7 @@ This action retrieves a collection of discovered vulnerabilities related to a gi |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|machine|string|None|True|Machine IP address, hostname or machine ID|None|9de5069c5afe602b2ea0a04b66beb2c0cef77fdf| +|machine|string|None|True|Machine IP address, hostname or machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| Example input: @@ -532,7 +528,7 @@ This action is used to get details about a machine from its ID. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|machine|string|None|True|Machine IP address, hostname and machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| +|machine|string|None|True|Machine IP address, hostname and machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| Example input: @@ -631,7 +627,7 @@ This action is used to isolate a machine from the network, but keep the connecti |----|----|-------|--------|-----------|----|-------| |comment|string|None|True|Comment to associate with the isolation action|None|Isolated by InsightConnect| |isolation_type|string|None|True|Type of isolation to perform on target machine|['Full', 'Selective']|Full| -|machine|string|None|True|Machine IP address, hostname and machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| +|machine|string|None|True|Machine IP address, hostname and machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| Example input: @@ -675,7 +671,7 @@ This action is used to restore network connectivity to a machine. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| |comment|string|None|True|Comment to associate with the unisolate action|None|Unisolated by InsightConnect| -|machine|string|None|True|Machine IP address, hostname and machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| +|machine|string|None|True|Machine IP address, hostname and machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| Example input: @@ -718,8 +714,8 @@ This action is used to stop the execution of a file on a machine and delete it. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| |comment|string|None|True|Comment to associate with the stop and quarantine action|None|InsightConnect has stopped a file.| -|machine|string|None|True|Machine IP address, hostname and machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| -|sha1|string|None|True|SHA1 hash of the file to stop and quarantine on the machine|None|ad0c0f2fa80411788e81a4567d1d8758b83cd76e| +|machine|string|None|True|Machine IP address, hostname and machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| +|sha1|string|None|True|SHA1 hash of the file to stop and quarantine on the machine|None|02699626f388ed830012e5b787640e71c56d42d8| Example input: @@ -766,7 +762,7 @@ This action is used to initiate a Windows Defender antivirus scan on a machine. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| |comment|string|None|True|Comment to associate with the antivirus scan action|None|InsightConnect has started an antivirus scan.| -|machine|string|None|True|Machine IP address, hostname and machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| +|machine|string|None|True|Machine IP address, hostname and machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| |scan_type|string|None|True|The type of antivirus scan to run|['Full', 'Quick']|Full| Example input: @@ -858,7 +854,7 @@ looking for a match. |----|----|-------|--------|-----------|----|-------| |frequency|integer|10|False|Poll frequency in seconds|None|10| |key|string|None|True|The key to look for in the alert. This key must match the case shown in the example output section in help|None|assignedTo| -|value|string|None|True|The value to look for in the alert. The value must match the case of the value returned|None|user@example.com| +|value|string|None|True|The value to look for in the alert. The value must match the case of the value returned|None|https://example.com| Example input: From 8c7c1b85805d54657c60defee3cba977072bbea7 Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Fri, 1 Oct 2021 01:39:16 +0200 Subject: [PATCH 04/60] [MC-683][MC-673][MC-681][MC-682][MC-684][MC-686][MC-688][MC-687] Add new Plugin IntSights --- plugins/intsights/bin/icon_intsights | 2 + plugins/intsights/help.md | 40 +++- .../icon_intsights/actions/__init__.py | 1 + .../actions/add_manual_alert/__init__.py | 2 + .../actions/add_manual_alert/action.py | 31 +++ .../actions/add_manual_alert/schema.py | 218 ++++++++++++++++++ .../actions/get_alerts/action.py | 23 +- .../get_complete_alert_by_id/action.py | 16 +- .../get_indicator_scan_status/action.py | 7 +- .../actions/rescan_indicator/action.py | 8 +- .../actions/rescan_indicator/schema.py | 8 +- .../actions/takedown_request/action.py | 10 +- .../icon_intsights/connection/connection.py | 3 +- plugins/intsights/icon_intsights/util/api.py | 171 +++++++++++++- plugins/intsights/plugin.spec.yaml | 186 ++++++++++++++- .../payloads/add_manual_alert.json.resp | 1 + .../enrich_indicator-in_progress.json.resp | 2 +- .../payloads/enrich_indicator.json.resp | 2 +- .../unit_test/payloads/get_alerts.json.resp | 6 + .../payloads/get_alerts_empty_list.json.resp | 1 + .../get_complete_alert_by_id.json.resp | 28 +++ .../get_indicator_scan_status.bad.json.resp | 5 + .../get_indicator_scan_status.json.resp | 4 + .../payloads/iocs_ioc-by-value.json.resp | 2 +- .../payloads/rescan_indicator.bad.json.resp | 5 + .../payloads/rescan_indicator.json.resp | 4 + .../unit_test/test_add_manual_alert.py | 59 +++++ .../unit_test/test_enrich_indicator.py | 6 +- .../intsights/unit_test/test_get_alerts.py | 53 +++++ .../test_get_complete_alert_by_id.py | 48 ++++ .../unit_test/test_get_indicator_by_value.py | 4 +- .../test_get_indicator_scan_status.py | 39 ++++ .../unit_test/test_rescan_indicator.py | 39 ++++ plugins/intsights/unit_test/util.py | 34 ++- 34 files changed, 1020 insertions(+), 48 deletions(-) create mode 100755 plugins/intsights/icon_intsights/actions/add_manual_alert/__init__.py create mode 100755 plugins/intsights/icon_intsights/actions/add_manual_alert/action.py create mode 100755 plugins/intsights/icon_intsights/actions/add_manual_alert/schema.py create mode 100644 plugins/intsights/unit_test/payloads/add_manual_alert.json.resp create mode 100644 plugins/intsights/unit_test/payloads/get_alerts.json.resp create mode 100644 plugins/intsights/unit_test/payloads/get_alerts_empty_list.json.resp create mode 100644 plugins/intsights/unit_test/payloads/get_complete_alert_by_id.json.resp create mode 100644 plugins/intsights/unit_test/payloads/get_indicator_scan_status.bad.json.resp create mode 100644 plugins/intsights/unit_test/payloads/get_indicator_scan_status.json.resp create mode 100644 plugins/intsights/unit_test/payloads/rescan_indicator.bad.json.resp create mode 100644 plugins/intsights/unit_test/payloads/rescan_indicator.json.resp create mode 100644 plugins/intsights/unit_test/test_add_manual_alert.py create mode 100644 plugins/intsights/unit_test/test_get_alerts.py create mode 100644 plugins/intsights/unit_test/test_get_complete_alert_by_id.py create mode 100644 plugins/intsights/unit_test/test_get_indicator_scan_status.py create mode 100644 plugins/intsights/unit_test/test_rescan_indicator.py diff --git a/plugins/intsights/bin/icon_intsights b/plugins/intsights/bin/icon_intsights index b275f574c4..088922f049 100755 --- a/plugins/intsights/bin/icon_intsights +++ b/plugins/intsights/bin/icon_intsights @@ -36,6 +36,8 @@ def main(): ) self.add_trigger(triggers.NewAlert()) + self.add_action(actions.AddManualAlert()) + self.add_action(actions.EnrichIndicator()) self.add_action(actions.GetAlerts()) diff --git a/plugins/intsights/help.md b/plugins/intsights/help.md index a42d5b6b11..1b75f68b0e 100755 --- a/plugins/intsights/help.md +++ b/plugins/intsights/help.md @@ -39,6 +39,43 @@ Example input: ### Actions +#### Add Manual Alert + +This action this action will create a manual alert with the provided parameters. + +##### Input + +|Name|Type|Default|Required|Description|Enum|Example| +|----|----|-------|--------|-----------|----|-------| +|description|string|None|True|Alert description|None|None| +|found_date|string|None|False|Alert found date|None|None| +|images|[]image|None|False|Alert images|None|None| +|severity|string|None|True|Alert severity|['High', 'Medium', 'Low']|None| +|source_date|string|None|False|Alert source date|None|None| +|source_network_type|string|None|True|Source network type|['ClearWeb', 'DarkWeb']|None| +|source_type|string|None|True|Source type|['Application Store', 'Cyber Security Blog', 'Hacking News', 'Cyber Crime Forum', 'Hacktivism Forum', 'Social Media', 'Facebook', 'Twitter', 'LinkedIn', 'Google Plus', 'VK', 'Vimeo', 'YouTube', 'IRC Channel', 'IOC Block List', 'Credit Card Black Market', 'Paste Site', 'Data Leakage Website', 'Leaked Database', 'File Sharing Website', 'Gray Hat Website', 'Black Market', 'WHOIS servers', 'Company Website', 'Wikileaks', 'Pinterest', 'Tumblr', 'Instagram', 'Telegram', 'Webmail', 'Malware Analysis', 'Firehol', 'VRA', 'Other']|None| +|source_url|string|None|True|Source URL|None|None| +|sub_type|string|None|True|Alert sub type, needs to correlate with the selected "Type"|None|None| +|title|string|None|True|Alert title|None|None| +|type|string|None|True|Alert type|['AttackIndication', 'DataLeakage', 'Phishing', 'BrandSecurity', 'ExploitableData', 'vip']|None| + +Example input: + +``` +``` + +##### Output + +|Name|Type|Required|Description| +|----|----|--------|-----------| +|alert_id|string|True|New created alert ID| + +Example output: + +``` + +``` + #### Takedown Request This action is used to request a takedown for a given alert in Intsights. @@ -112,7 +149,7 @@ This action is used to force an indicator scan in Intsights TIP system. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_value|string|None|True|IOC value in type file hash|None|None| +|indicator_file_hash|string|None|True|IOC value in type file hash|None|None| Example input: @@ -129,6 +166,7 @@ Example input: Example output: ``` + ``` #### Get Indicator Scan Status diff --git a/plugins/intsights/icon_intsights/actions/__init__.py b/plugins/intsights/icon_intsights/actions/__init__.py index b0f3613f38..b61f2ddbfc 100755 --- a/plugins/intsights/icon_intsights/actions/__init__.py +++ b/plugins/intsights/icon_intsights/actions/__init__.py @@ -1,4 +1,5 @@ # GENERATED BY KOMAND SDK - DO NOT EDIT +from .add_manual_alert.action import AddManualAlert from .enrich_indicator.action import EnrichIndicator from .get_alerts.action import GetAlerts from .get_complete_alert_by_id.action import GetCompleteAlertById diff --git a/plugins/intsights/icon_intsights/actions/add_manual_alert/__init__.py b/plugins/intsights/icon_intsights/actions/add_manual_alert/__init__.py new file mode 100755 index 0000000000..5f6ad928bf --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/add_manual_alert/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +from .action import AddManualAlert diff --git a/plugins/intsights/icon_intsights/actions/add_manual_alert/action.py b/plugins/intsights/icon_intsights/actions/add_manual_alert/action.py new file mode 100755 index 0000000000..318c1526ce --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/add_manual_alert/action.py @@ -0,0 +1,31 @@ +import insightconnect_plugin_runtime +from .schema import AddManualAlertInput, AddManualAlertOutput, Input, Output, Component +# Custom imports below +from icon_intsights.util.api import ManualAlertParams + + +class AddManualAlert(insightconnect_plugin_runtime.Action): + + def __init__(self): + super(self.__class__, self).__init__( + name='add_manual_alert', + description=Component.DESCRIPTION, + input=AddManualAlertInput(), + output=AddManualAlertOutput()) + + def run(self, params={}): + return { + Output.ALERT_ID: self.connection.client.add_manual_alert(ManualAlertParams( + title=params.get(Input.TITLE), + found_date=params.get(Input.FOUND_DATE), + description=params.get(Input.DESCRIPTION), + type=params.get(Input.TYPE), + sub_type=params.get(Input.SUB_TYPE), + severity=params.get(Input.SEVERITY), + source_type=params.get(Input.SOURCE_TYPE), + source_network_type=params.get(Input.SOURCE_NETWORK_TYPE), + source_url=params.get(Input.SOURCE_URL), + source_date=params.get(Input.SOURCE_DATE), + images=params.get(Input.IMAGES) + )) + } diff --git a/plugins/intsights/icon_intsights/actions/add_manual_alert/schema.py b/plugins/intsights/icon_intsights/actions/add_manual_alert/schema.py new file mode 100755 index 0000000000..5a886dcae9 --- /dev/null +++ b/plugins/intsights/icon_intsights/actions/add_manual_alert/schema.py @@ -0,0 +1,218 @@ +# GENERATED BY KOMAND SDK - DO NOT EDIT +import insightconnect_plugin_runtime +import json + + +class Component: + DESCRIPTION = "This action will create a manual alert with the provided parameters" + + +class Input: + DESCRIPTION = "description" + FOUND_DATE = "found_date" + IMAGES = "images" + SEVERITY = "severity" + SOURCE_DATE = "source_date" + SOURCE_NETWORK_TYPE = "source_network_type" + SOURCE_TYPE = "source_type" + SOURCE_URL = "source_url" + SUB_TYPE = "sub_type" + TITLE = "title" + TYPE = "type" + + +class Output: + ALERT_ID = "alert_id" + + +class AddManualAlertInput(insightconnect_plugin_runtime.Input): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "description": { + "type": "string", + "title": "Description", + "description": "Alert description", + "order": 2 + }, + "found_date": { + "type": "string", + "title": "Found Date", + "description": "Alert found date", + "order": 9 + }, + "images": { + "type": "array", + "title": "Images", + "description": "Alert images", + "items": { + "$ref": "#/definitions/image" + }, + "order": 11 + }, + "severity": { + "type": "string", + "title": "Severity", + "description": "Alert severity", + "enum": [ + "High", + "Medium", + "Low" + ], + "order": 5 + }, + "source_date": { + "type": "string", + "title": "Source Date", + "description": "Alert source date", + "order": 10 + }, + "source_network_type": { + "type": "string", + "title": "Source Network Type", + "description": "Source network type", + "enum": [ + "ClearWeb", + "DarkWeb" + ], + "order": 7 + }, + "source_type": { + "type": "string", + "title": "Source Type", + "description": "Source type", + "enum": [ + "Application Store", + "Cyber Security Blog", + "Hacking News", + "Cyber Crime Forum", + "Hacktivism Forum", + "Social Media", + "Facebook", + "Twitter", + "LinkedIn", + "Google Plus", + "VK", + "Vimeo", + "YouTube", + "IRC Channel", + "IOC Block List", + "Credit Card Black Market", + "Paste Site", + "Data Leakage Website", + "Leaked Database", + "File Sharing Website", + "Gray Hat Website", + "Black Market", + "WHOIS servers", + "Company Website", + "Wikileaks", + "Pinterest", + "Tumblr", + "Instagram", + "Telegram", + "Webmail", + "Malware Analysis", + "Firehol", + "VRA", + "Other" + ], + "order": 6 + }, + "source_url": { + "type": "string", + "title": "Source URL", + "description": "Source URL", + "order": 8 + }, + "sub_type": { + "type": "string", + "title": "Sub Type", + "description": "Alert sub type, needs to correlate with the selected \\"Type\\"", + "order": 4 + }, + "title": { + "type": "string", + "title": "Title", + "description": "Alert title", + "order": 1 + }, + "type": { + "type": "string", + "title": "Type", + "description": "Alert type", + "enum": [ + "AttackIndication", + "DataLeakage", + "Phishing", + "BrandSecurity", + "ExploitableData", + "vip" + ], + "order": 3 + } + }, + "required": [ + "description", + "severity", + "source_network_type", + "source_type", + "source_url", + "sub_type", + "title", + "type" + ], + "definitions": { + "image": { + "type": "object", + "title": "image", + "properties": { + "data": { + "type": "string", + "title": "Data", + "description": "Data", + "order": 2 + }, + "type": { + "type": "string", + "title": "Type", + "description": "Type", + "order": 1 + } + }, + "required": [ + "data", + "type" + ] + } + } +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) + + +class AddManualAlertOutput(insightconnect_plugin_runtime.Output): + schema = json.loads(""" + { + "type": "object", + "title": "Variables", + "properties": { + "alert_id": { + "type": "string", + "title": "Alert ID", + "description": "New created alert ID", + "order": 1 + } + }, + "required": [ + "alert_id" + ] +} + """) + + def __init__(self): + super(self.__class__, self).__init__(self.schema) diff --git a/plugins/intsights/icon_intsights/actions/get_alerts/action.py b/plugins/intsights/icon_intsights/actions/get_alerts/action.py index 2b3a236434..9a6ef84cc1 100755 --- a/plugins/intsights/icon_intsights/actions/get_alerts/action.py +++ b/plugins/intsights/icon_intsights/actions/get_alerts/action.py @@ -1,6 +1,7 @@ import insightconnect_plugin_runtime from .schema import GetAlertsInput, GetAlertsOutput, Input, Output, Component # Custom imports below +from icon_intsights.util.api import AlertParams class GetAlerts(insightconnect_plugin_runtime.Action): @@ -13,5 +14,23 @@ def __init__(self): output=GetAlertsOutput()) def run(self, params={}): - # TODO: Implement run function - return {} + alert_params = AlertParams( + alert_type=params.get(Input.ALERT_TYPE), + severity=params.get(Input.SEVERITY), + source_type=params.get(Input.SOURCE_TYPE), + network_type=params.get(Input.NETWORK_TYPE), + matched_asset_value=params.get(Input.MATCHED_ASSET_VALUE), + remediation_status=params.get(Input.REMEDIATION_STATUS), + source_date_from=params.get(Input.SOURCE_DATE_FROM), + source_date_to=params.get(Input.SOURCE_DATE_TO), + found_date_from=params.get(Input.FOUND_DATE_FROM), + found_date_to=params.get(Input.FOUND_DATE_TO), + assigned=params.get(Input.ASSIGNED), + is_flagged=params.get(Input.IS_FLAGGED), + is_closed=params.get(Input.IS_CLOSED), + has_ioc=params.get(Input.HAS_INDICATORS), + ) + response = self.connection.client.get_alerts(alert_params) + return { + Output.ALERT_IDS: response + } diff --git a/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py b/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py index 9d6e362368..75bfc43580 100755 --- a/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py +++ b/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py @@ -1,6 +1,7 @@ import insightconnect_plugin_runtime from .schema import GetCompleteAlertByIdInput, GetCompleteAlertByIdOutput, Input, Output, Component # Custom imports below +from insightconnect_plugin_runtime.helper import clean class GetCompleteAlertById(insightconnect_plugin_runtime.Action): @@ -13,5 +14,16 @@ def __init__(self): output=GetCompleteAlertByIdOutput()) def run(self, params={}): - # TODO: Implement run function - return {} + response = self.connection.client.get_complete_alert_by_id(params.get(Input.ALERT_ID)) + return clean({ + Output.ID: response.get('_id'), + Output.ASSETS: response.get('Assets', []), + Output.ASSIGNEES: response.get('Assignees', []), + Output.DETAILS: response.get('Details', {}), + Output.FOUND_DATE: response.get('FoundDate'), + Output.UPDATE_DATE: response.get('UpdateDate'), + Output.TAKEDOWN_STATUS: response.get('TakedownStatus'), + Output.IS_CLOSED: response.get('IsClosed', False), + Output.IS_FLAGGED: response.get('IsFlagged', False), + Output.LEAK_NAME: response.get('LeakName'), + }) diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py b/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py index 99fade5128..6528a1b5ae 100755 --- a/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py +++ b/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py @@ -13,5 +13,8 @@ def __init__(self): output=GetIndicatorScanStatusOutput()) def run(self, params={}): - # TODO: Implement run function - return {} + response = self.connection.client.get_scan_status(params.get(Input.TASK_ID)) + return { + Output.TASK_ID: response.get('TaskId'), + Output.STATUS: response.get('Status') + } diff --git a/plugins/intsights/icon_intsights/actions/rescan_indicator/action.py b/plugins/intsights/icon_intsights/actions/rescan_indicator/action.py index f0df5cd09f..3b4f148991 100755 --- a/plugins/intsights/icon_intsights/actions/rescan_indicator/action.py +++ b/plugins/intsights/icon_intsights/actions/rescan_indicator/action.py @@ -1,6 +1,7 @@ import insightconnect_plugin_runtime from .schema import RescanIndicatorInput, RescanIndicatorOutput, Input, Output, Component # Custom imports below +from insightconnect_plugin_runtime.helper import clean class RescanIndicator(insightconnect_plugin_runtime.Action): @@ -13,5 +14,8 @@ def __init__(self): output=RescanIndicatorOutput()) def run(self, params={}): - # TODO: Implement run function - return {} + response = self.connection.client.rescan_indicator(params.get(Input.INDICATOR_FILE_HASH)) + return clean({ + Output.TASK_ID: response.get('TaskId'), + Output.STATUS: response.get('Status') + }) diff --git a/plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py b/plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py index 0281a8a52a..847a38047c 100755 --- a/plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py +++ b/plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py @@ -8,7 +8,7 @@ class Component: class Input: - INDICATOR_VALUE = "indicator_value" + INDICATOR_FILE_HASH = "indicator_file_hash" class Output: @@ -22,15 +22,15 @@ class RescanIndicatorInput(insightconnect_plugin_runtime.Input): "type": "object", "title": "Variables", "properties": { - "indicator_value": { + "indicator_file_hash": { "type": "string", - "title": "Indicator Value", + "title": "Indicator File Hash", "description": "IOC value in type file hash", "order": 1 } }, "required": [ - "indicator_value" + "indicator_file_hash" ] } """) diff --git a/plugins/intsights/icon_intsights/actions/takedown_request/action.py b/plugins/intsights/icon_intsights/actions/takedown_request/action.py index ea34dc301c..e0a703bb4c 100755 --- a/plugins/intsights/icon_intsights/actions/takedown_request/action.py +++ b/plugins/intsights/icon_intsights/actions/takedown_request/action.py @@ -1,6 +1,7 @@ import insightconnect_plugin_runtime from .schema import TakedownRequestInput, TakedownRequestOutput, Input, Output, Component # Custom imports below +from insightconnect_plugin_runtime.helper import clean class TakedownRequest(insightconnect_plugin_runtime.Action): @@ -13,5 +14,10 @@ def __init__(self): output=TakedownRequestOutput()) def run(self, params={}): - # TODO: Implement run function - return {} + self.connection.client.takedown_request( + params.get(Input.ALERT_ID), + params.get(Input.TARGET) + ) + return clean({ + Output.STATUS: True + }) diff --git a/plugins/intsights/icon_intsights/connection/connection.py b/plugins/intsights/icon_intsights/connection/connection.py index 8b62f686c3..cccd8ce7c2 100755 --- a/plugins/intsights/icon_intsights/connection/connection.py +++ b/plugins/intsights/icon_intsights/connection/connection.py @@ -15,7 +15,8 @@ def __init__(self): def connect(self, params={}): self.client = IntSightAPI( params.get(Input.ACCOUNT_ID, {}).get('secretKey'), - params.get(Input.API_KEY, {}).get('secretKey') + params.get(Input.API_KEY, {}).get('secretKey'), + self.logger ) self.logger.info("Connect: Connecting...") diff --git a/plugins/intsights/icon_intsights/util/api.py b/plugins/intsights/icon_intsights/util/api.py index 4c9f7cd91c..5e48feec7a 100644 --- a/plugins/intsights/icon_intsights/util/api.py +++ b/plugins/intsights/icon_intsights/util/api.py @@ -1,43 +1,194 @@ import json import time - +from dataclasses import dataclass +from logging import Logger import requests from insightconnect_plugin_runtime.exceptions import PluginException +from insightconnect_plugin_runtime.helper import clean from requests.auth import HTTPBasicAuth +@dataclass +class AlertParams: + alert_type: str + severity: str + source_type: str + network_type: str + matched_asset_value: str + remediation_status: str + source_date_from: int + source_date_to: int + found_date_from: int + found_date_to: int + assigned: bool + is_flagged: bool + is_closed: bool + has_ioc: bool + + def to_dict(self) -> dict: + return clean({ + 'alertType': self.alert_type, + 'severity': self.severity, + 'sourceType': self.source_type, + 'networkType': self.network_type, + 'matchedAssetValue': self.matched_asset_value, + 'remediationStatus': self.remediation_status, + 'sourceDateFrom': self.source_date_from, + 'sourceDateTo': self.source_date_to, + 'foundDateFrom': self.found_date_from, + 'foundDateTo': self.found_date_to, + 'assigned': self.assigned, + 'isFlagged': self.is_flagged, + 'isClosed': self.is_closed, + 'hasIoc': self.has_ioc, + }) + + +@dataclass +class Image: + type: str + data: str + + +@dataclass +class ManualAlertParams: + title: str + found_date: str + description: str + type: str + sub_type: str + severity: str + source_type: int + source_network_type: int + source_url: int + source_date: int + images: [Image] + + def to_dict(self) -> dict: + images = [] + if self.images: + for image in self.images: + if not image: + continue + try: + images.append({ + "Type": image["type"], + "Data": image["data"] + }) + except KeyError as e: + raise PluginException( + cause="Wrong input parameter.", + assistance=f"Wrong image: {e}." + ) + + return clean({ + 'FoundDate': self.found_date, + 'Details': { + "Title": self.title, + "Description": self.description, + "Type": self.type, + "SubType": self.sub_type, + "Severity": self.severity, + "Source": { + "Type": self.source_type, + "NetworkType": self.source_network_type, + "URL": self.source_url, + "Date": self.source_date + }, + "Images": images + } + }) + + class IntSightAPI: - def __init__(self, account_id, api_key): + def __init__(self, account_id: str, api_key: str, logger: Logger): self.account_id = account_id self.api_key = api_key self.url = 'https://api.intsights.com' + self.logger = logger def get_indicator_by_value(self, ioc_value: str) -> dict: - response = self.make_request('GET', f'public/v2/iocs/ioc-by-value?iocValue={ioc_value}') - if response.status_code == 204: - return {} - - return response.json() + return self.make_json_request('GET', f'public/v2/iocs/ioc-by-value?iocValue={ioc_value}') def enrich_indicator(self, ioc_value: str) -> dict: while True: - response = self.make_request('GET', f'public/v1/iocs/enrich/{ioc_value}').json() + response = self.make_json_request('GET', f'public/v1/iocs/enrich/{ioc_value}') if response.get('Status', 'InProgress') in ['Done', 'Failed']: break time.sleep(5) return response + def rescan_indicator(self, indicator_file_hash: str) -> dict: + return self.make_json_request('POST', 'public/v1/iocs/rescan', json_data={ + "IocValue": indicator_file_hash + }) + + def get_scan_status(self, task_id: str) -> dict: + return self.make_json_request('GET', f'public/v1/iocs/rescan/status/{task_id}') + + def get_complete_alert_by_id(self, alert_id: str) -> dict: + return self.make_json_request('GET', f'public/v1/data/alerts/get-complete-alert/{alert_id}') + + def takedown_request(self, alert_id: str, target: str) -> dict: + return self.make_json_request('PATCH', f'public/v1/data/alerts/takedown-request/{alert_id}', json_data={ + "Target": target + }) + + def get_alerts(self, alert_params: AlertParams) -> list: + return self.make_request('GET', 'public/v1/data/alerts/alerts-list', params=alert_params.to_dict()).json() + + def add_manual_alert(self, manual_alert_params: ManualAlertParams) -> str: + return self.make_request('PUT', 'public/v1/data/alerts/add-alert', json_data=manual_alert_params.to_dict()).text + def test_credentials(self) -> bool: return self.make_request('HEAD', 'public/v1/test-credentials').status_code == 200 - def make_request(self, method: str, path: str) -> requests.Response: + def make_json_request( + self, + method: str, + path: str, + json_data: dict = None, + params: dict = None + ) -> dict: + try: + response = self.make_request( + method=method, + path=path, + json_data=json_data, + params=params + ) + if response.status_code == 204: + return {} + + json_response = response.json() + + if json_response.get("Status") == "Invalid": + raise PluginException( + cause="There is an error in response.", + assistance=f"{json_response.get('FailedReason')}." + ) + + self.logger.info(f"response: {response.json()}") + return json_response + except json.decoder.JSONDecodeError as e: + raise PluginException(preset=PluginException.Preset.INVALID_JSON, data=e) + + def make_request( + self, + method: str, + path: str, + json_data: dict = None, + params: dict = None + ) -> requests.Response: try: response = requests.request( method=method, url=f"{self.url}/{path}", headers={"Content-Type": "application/json"}, verify=True, + params=params, + json=json_data, auth=HTTPBasicAuth(self.account_id, self.api_key), ) @@ -59,7 +210,5 @@ def make_request(self, method: str, path: str) -> requests.Response: return response raise PluginException(preset=PluginException.Preset.UNKNOWN, data=response.text) - except json.decoder.JSONDecodeError as e: - raise PluginException(preset=PluginException.Preset.INVALID_JSON, data=e) except requests.exceptions.HTTPError as e: raise PluginException(preset=PluginException.Preset.UNKNOWN, data=e) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 33e78bf9b2..17114894d3 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -33,6 +33,17 @@ types: description: Level of confidence type: integer required: true + image: + type: + title: Type + description: Type + type: string + required: true + data: + title: Data + description: Data + type: string + required: true connection: account_id: title: Account ID @@ -163,8 +174,8 @@ actions: title: Rescan Indicator description: Force an indicator scan in Intsights TIP system input: - indicator_value: - title: Indicator Value + indicator_file_hash: + title: Indicator File Hash description: IOC value in type file hash type: string required: true @@ -208,21 +219,70 @@ actions: description: Comma separated list of alert types. Allowed values - AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip type: string required: false + enum: + - AttackIndication + - DataLeakage + - Phishing + - BrandSecurity + - ExploitableData + - vip severity: title: Severity description: Comma separated list of alerts severity. Allowed values - High, Medium, Low type: string required: false + enum: + - High + - Medium + - Low source_type: title: Source Type description: Comma separated list of alerts source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others type: string required: false + enum: + - Application Store + - Cyber Security Blog + - Hacking News + - Cyber Crime Forum + - Hacktivism Forum + - Social Media + - Facebook + - Twitter + - LinkedIn + - Google Plus + - VK + - Vimeo + - YouTube + - IRC Channel + - IOC Block List + - Credit Card Black Market + - Paste Site + - Data Leakage Website + - Leaked Database + - File Sharing Website + - Gray Hat Website + - Black Market + - WHOIS servers + - Company Website + - Wikileaks + - Pinterest + - Tumblr + - Instagram + - Telegram + - Webmail + - Malware Analysis + - Firehol + - VRA + - Other network_type: title: Network Type description: Comma separated list of network type. Allowed values - ClearWeb, DarkWeb type: string required: false + enum: + - ClearWeb + - DarkWeb matched_asset_value: title: Matched Asset Value description: Comma separated list @@ -364,10 +424,124 @@ actions: default: Domain example: Domain output: - response: - title: Response - description: Response from IntSights - type: object + status: + title: Status + description: Status from IntSights + type: boolean + required: true + add_manual_alert: + title: Add Manual Alert + description: This action will create a manual alert with the provided parameters + input: + title: + title: Title + description: Alert title + type: string + required: true + description: + title: Description + description: Alert description + type: string + required: true + type: + title: Type + description: Alert type + type: string + required: true + enum: + - AttackIndication + - DataLeakage + - Phishing + - BrandSecurity + - ExploitableData + - vip + sub_type: + title: Sub Type + description: Alert sub type, needs to correlate with the selected "Type" + type: string + required: true + severity: + title: Severity + description: Alert severity + type: string + required: true + enum: + - High + - Medium + - Low + source_type: + title: Source Type + description: Source type + type: string + required: true + enum: + - Application Store + - Cyber Security Blog + - Hacking News + - Cyber Crime Forum + - Hacktivism Forum + - Social Media + - Facebook + - Twitter + - LinkedIn + - Google Plus + - VK + - Vimeo + - YouTube + - IRC Channel + - IOC Block List + - Credit Card Black Market + - Paste Site + - Data Leakage Website + - Leaked Database + - File Sharing Website + - Gray Hat Website + - Black Market + - WHOIS servers + - Company Website + - Wikileaks + - Pinterest + - Tumblr + - Instagram + - Telegram + - Webmail + - Malware Analysis + - Firehol + - VRA + - Other + source_network_type: + title: Source Network Type + description: Source network type + type: string + required: true + enum: + - ClearWeb + - DarkWeb + source_url: + title: Source URL + description: Source URL + type: string + required: true + found_date: + title: Found Date + description: Alert found date + type: string + required: false + source_date: + title: Source Date + description: Alert source date + type: string + required: false + images: + title: Images + description: Alert images + type: "[]image" + required: false + output: + alert_id: + title: Alert ID + description: New created alert ID + type: string required: true triggers: diff --git a/plugins/intsights/unit_test/payloads/add_manual_alert.json.resp b/plugins/intsights/unit_test/payloads/add_manual_alert.json.resp new file mode 100644 index 0000000000..8f0d3e7636 --- /dev/null +++ b/plugins/intsights/unit_test/payloads/add_manual_alert.json.resp @@ -0,0 +1 @@ +7cafac7ec5adaebf62257a4c \ No newline at end of file diff --git a/plugins/intsights/unit_test/payloads/enrich_indicator-in_progress.json.resp b/plugins/intsights/unit_test/payloads/enrich_indicator-in_progress.json.resp index 618c9d8350..4237d8178f 100644 --- a/plugins/intsights/unit_test/payloads/enrich_indicator-in_progress.json.resp +++ b/plugins/intsights/unit_test/payloads/enrich_indicator-in_progress.json.resp @@ -1,4 +1,4 @@ { "Status": "InProgress", - "OriginalValue": "example.com" + "OriginalValue": "rapid7.com" } \ No newline at end of file diff --git a/plugins/intsights/unit_test/payloads/enrich_indicator.json.resp b/plugins/intsights/unit_test/payloads/enrich_indicator.json.resp index 0b077e4dd1..4ce54098e2 100644 --- a/plugins/intsights/unit_test/payloads/enrich_indicator.json.resp +++ b/plugins/intsights/unit_test/payloads/enrich_indicator.json.resp @@ -1,4 +1,4 @@ { "Status": "Done", - "OriginalValue": "example.com" + "OriginalValue": "rapid7.com" } \ No newline at end of file diff --git a/plugins/intsights/unit_test/payloads/get_alerts.json.resp b/plugins/intsights/unit_test/payloads/get_alerts.json.resp new file mode 100644 index 0000000000..65f8fb9ccc --- /dev/null +++ b/plugins/intsights/unit_test/payloads/get_alerts.json.resp @@ -0,0 +1,6 @@ +[ + "7cafac7ec5adaebf62257a4c", + "7cafac7ec5adaebf62257a4d", + "7cafac7ec5adaebf62257a4e", + "7cafac7ec5adaebf62257a4f" +] \ No newline at end of file diff --git a/plugins/intsights/unit_test/payloads/get_alerts_empty_list.json.resp b/plugins/intsights/unit_test/payloads/get_alerts_empty_list.json.resp new file mode 100644 index 0000000000..0637a088a0 --- /dev/null +++ b/plugins/intsights/unit_test/payloads/get_alerts_empty_list.json.resp @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/plugins/intsights/unit_test/payloads/get_complete_alert_by_id.json.resp b/plugins/intsights/unit_test/payloads/get_complete_alert_by_id.json.resp new file mode 100644 index 0000000000..80dcc4dbd4 --- /dev/null +++ b/plugins/intsights/unit_test/payloads/get_complete_alert_by_id.json.resp @@ -0,0 +1,28 @@ +{ + "_id": "7cafac7ec5adaebf62257a4c", + "Details": { + "Source": { + "Type": "Application Store", + "NetworkType": "ClearWeb", + "URL": "http://www.rapid7.com" + }, + "Images": [], + "Title": "Alerttest3", + "Type": "Phishing", + "SubType": "SuspiciousEmailAddress", + "Severity": "High", + "Tags": [], + "Description": "APIDescription" + }, + "Assignees": [], + "FoundDate": "2021-09-30T19:35:42.441Z", + "Assets": [], + "TakedownStatus": "NotSent", + "IsFlagged": false, + "UpdateDate": "2021-09-30T19:35:42.441Z", + "RelatedIocs": [], + "RelatedThreatIDs": [], + "Closed": { + "IsClosed": false + } +} \ No newline at end of file diff --git a/plugins/intsights/unit_test/payloads/get_indicator_scan_status.bad.json.resp b/plugins/intsights/unit_test/payloads/get_indicator_scan_status.bad.json.resp new file mode 100644 index 0000000000..380dacd3a0 --- /dev/null +++ b/plugins/intsights/unit_test/payloads/get_indicator_scan_status.bad.json.resp @@ -0,0 +1,5 @@ +{ + "OriginalValue": "123", + "Status": "Invalid", + "FailedReason": "Invalid task id" +} \ No newline at end of file diff --git a/plugins/intsights/unit_test/payloads/get_indicator_scan_status.json.resp b/plugins/intsights/unit_test/payloads/get_indicator_scan_status.json.resp new file mode 100644 index 0000000000..af3788e0e6 --- /dev/null +++ b/plugins/intsights/unit_test/payloads/get_indicator_scan_status.json.resp @@ -0,0 +1,4 @@ +{ + "TaskId": "abcdefg123456", + "Status": "InProgress" +} \ No newline at end of file diff --git a/plugins/intsights/unit_test/payloads/iocs_ioc-by-value.json.resp b/plugins/intsights/unit_test/payloads/iocs_ioc-by-value.json.resp index 884969f6c1..6218e53842 100644 --- a/plugins/intsights/unit_test/payloads/iocs_ioc-by-value.json.resp +++ b/plugins/intsights/unit_test/payloads/iocs_ioc-by-value.json.resp @@ -1,5 +1,5 @@ { - "Value": "example.com", + "Value": "rapid7.com", "Type": "Domains", "Severity": "High", "Score": 100, diff --git a/plugins/intsights/unit_test/payloads/rescan_indicator.bad.json.resp b/plugins/intsights/unit_test/payloads/rescan_indicator.bad.json.resp new file mode 100644 index 0000000000..ffc4272ff3 --- /dev/null +++ b/plugins/intsights/unit_test/payloads/rescan_indicator.bad.json.resp @@ -0,0 +1,5 @@ +{ + "OriginalValue":"", + "Status":"Invalid", + "FailedReason":"Invalid IOC value. Supported IOC types: file hashes" +} \ No newline at end of file diff --git a/plugins/intsights/unit_test/payloads/rescan_indicator.json.resp b/plugins/intsights/unit_test/payloads/rescan_indicator.json.resp new file mode 100644 index 0000000000..9424008eb7 --- /dev/null +++ b/plugins/intsights/unit_test/payloads/rescan_indicator.json.resp @@ -0,0 +1,4 @@ +{ + "TaskId": "abcdefg123456", + "Status": "Queued" +} \ No newline at end of file diff --git a/plugins/intsights/unit_test/test_add_manual_alert.py b/plugins/intsights/unit_test/test_add_manual_alert.py new file mode 100644 index 0000000000..ca24dd5836 --- /dev/null +++ b/plugins/intsights/unit_test/test_add_manual_alert.py @@ -0,0 +1,59 @@ +import sys +import os + +sys.path.append(os.path.abspath('../')) + +from unittest import TestCase +from unittest.mock import patch +from unit_test.util import Util +from icon_intsights.actions.add_manual_alert import AddManualAlert +from icon_intsights.actions.add_manual_alert.schema import Input +from insightconnect_plugin_runtime.exceptions import PluginException + + +class TestAddManualAlert(TestCase): + @classmethod + @patch("requests.request", side_effect=Util.mock_request) + def setUpClass(cls, mock_request) -> None: + cls.action = Util.default_connector(AddManualAlert()) + + @patch("requests.request", side_effect=Util.mock_request) + def test_add_manual_alert_should_success(self, make_request): + actual = self.action.run({ + Input.TITLE: "Test Alert", + Input.DESCRIPTION: "Test description", + Input.TYPE: "Phishing", + Input.SUB_TYPE: "SuspiciousEmailAddress", + Input.SEVERITY: "High", + Input.SOURCE_TYPE: "Application Store", + Input.SOURCE_NETWORK_TYPE: "ClearWeb", + Input.SOURCE_URL: "http://www.rapid7.com", + Input.SOURCE_DATE: "2020-01-01T20:01:27.344Z", + Input.FOUND_DATE: "2020-01-01T20:01:27.344Z", + Input.IMAGES: [{"type": "gif", "data": "R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="}] + }) + expected = { + 'alert_id': '7cafac7ec5adaebf62257a4c' + } + self.assertEqual(expected, actual) + + @patch("requests.request", side_effect=Util.mock_request) + def test_add_manual_alert_should_fail_when_wrong_image(self, make_request): + params = { + Input.TITLE: "Test Alert", + Input.DESCRIPTION: "Test description", + Input.TYPE: "Phishing", + Input.SUB_TYPE: "SuspiciousEmailAddress", + Input.SEVERITY: "High", + Input.SOURCE_TYPE: "Application Store", + Input.SOURCE_NETWORK_TYPE: "ClearWeb", + Input.SOURCE_URL: "http://www.example.com", + Input.SOURCE_DATE: "2020-01-01T20:01:27.344Z", + Input.FOUND_DATE: "2020-01-01T20:01:27.344Z", + Input.IMAGES: [{"type": "gif"}] + } + with self.assertRaises(PluginException) as error: + self.action.run(params) + + self.assertEqual("Wrong input parameter.", error.exception.cause) + self.assertEqual("Wrong image: 'data'.", error.exception.assistance) diff --git a/plugins/intsights/unit_test/test_enrich_indicator.py b/plugins/intsights/unit_test/test_enrich_indicator.py index c611230a2d..2c6fd3487d 100644 --- a/plugins/intsights/unit_test/test_enrich_indicator.py +++ b/plugins/intsights/unit_test/test_enrich_indicator.py @@ -21,11 +21,11 @@ def setUpClass(cls, mock_request) -> None: @patch("requests.request", side_effect=Util.mock_request) def test_enrich_indicator_should_success(self, make_request): Util.request_count = 1 - actual = self.action.run({Input.INDICATOR_VALUE: 'example.com'}) + actual = self.action.run({Input.INDICATOR_VALUE: 'rapid7.com'}) Util.request_count = 0 expected = { 'data': {}, - 'original_value': 'example.com', + 'original_value': 'rapid7.com', 'status': 'Done' } self.assertEqual(expected, actual) @@ -34,7 +34,7 @@ def test_enrich_indicator_should_success(self, make_request): def test_enrich_indicator_should_success_when_in_progress(self, make_request): Util.request_count = 0 time_start = time.time() - self.action.run({Input.INDICATOR_VALUE: 'example.com'}) + self.action.run({Input.INDICATOR_VALUE: 'rapid7.com'}) expected = 1 expected_time_elapsed = time.time() - time_start self.assertEqual(expected, Util.request_count) diff --git a/plugins/intsights/unit_test/test_get_alerts.py b/plugins/intsights/unit_test/test_get_alerts.py new file mode 100644 index 0000000000..4a5cc1933c --- /dev/null +++ b/plugins/intsights/unit_test/test_get_alerts.py @@ -0,0 +1,53 @@ +import sys +import os + +sys.path.append(os.path.abspath('../')) + +from unittest import TestCase +from unittest.mock import patch +from unit_test.util import Util +from icon_intsights.actions.get_alerts import GetAlerts +from icon_intsights.actions.get_alerts.schema import Input + + +class TestAddManualAlert(TestCase): + @classmethod + @patch("requests.request", side_effect=Util.mock_request) + def setUpClass(cls, mock_request) -> None: + cls.action = Util.default_connector(GetAlerts()) + + @patch("requests.request", side_effect=Util.mock_request) + def test_get_alerts_success_with_empty_params(self, make_request): + actual = self.action.run({}) + expected = { + 'alert_ids': [ + '7cafac7ec5adaebf62257a4c', + '7cafac7ec5adaebf62257a4d', + '7cafac7ec5adaebf62257a4e', + '7cafac7ec5adaebf62257a4f' + ] + } + self.assertEqual(expected, actual) + + @patch("requests.request", side_effect=Util.mock_request) + def test_get_alerts_success_with_params(self, make_request): + actual = self.action.run({ + Input.SEVERITY: "High" + }) + expected = { + 'alert_ids': [ + '7cafac7ec5adaebf62257a4c', + '7cafac7ec5adaebf62257a4d', + '7cafac7ec5adaebf62257a4e', + '7cafac7ec5adaebf62257a4f' + ] + } + self.assertEqual(expected, actual) + + @patch("requests.request", side_effect=Util.mock_request) + def test_get_alerts_success_with_empty_response_list(self, make_request): + actual = self.action.run({ + Input.ALERT_TYPE: "Phishing" + }) + expected = {'alert_ids': []} + self.assertEqual(expected, actual) diff --git a/plugins/intsights/unit_test/test_get_complete_alert_by_id.py b/plugins/intsights/unit_test/test_get_complete_alert_by_id.py new file mode 100644 index 0000000000..206f160ccb --- /dev/null +++ b/plugins/intsights/unit_test/test_get_complete_alert_by_id.py @@ -0,0 +1,48 @@ +import sys +import os + +sys.path.append(os.path.abspath('../')) + +from unittest import TestCase +from unittest.mock import patch +from unit_test.util import Util +from icon_intsights.actions.get_complete_alert_by_id import GetCompleteAlertById +from icon_intsights.actions.get_complete_alert_by_id.schema import Input + + +class TestAddManualAlert(TestCase): + @classmethod + @patch("requests.request", side_effect=Util.mock_request) + def setUpClass(cls, mock_request) -> None: + cls.action = Util.default_connector(GetCompleteAlertById()) + + @patch("requests.request", side_effect=Util.mock_request) + def test_get_complete_alert_by_id_should_success(self, make_request): + actual = self.action.run({ + Input.ALERT_ID: "123" + }) + expected = { + 'assets': [], + 'assignees': [], + 'details': { + 'Description': 'APIDescription', + 'Images': [], + 'Severity': 'High', + 'Source': { + 'NetworkType': 'ClearWeb', + 'Type': 'Application Store', + 'URL': 'http://www.rapid7.com' + }, + 'SubType': 'SuspiciousEmailAddress', + 'Tags': [], + 'Title': 'Alerttest3', + 'Type': 'Phishing' + }, + 'found_date': '2021-09-30T19:35:42.441Z', + 'id': '7cafac7ec5adaebf62257a4c', + 'is_closed': False, + 'is_flagged': False, + 'takedown_status': 'NotSent', + 'update_date': '2021-09-30T19:35:42.441Z' + } + self.assertEqual(expected, actual) diff --git a/plugins/intsights/unit_test/test_get_indicator_by_value.py b/plugins/intsights/unit_test/test_get_indicator_by_value.py index 6d5857fd18..a849a88533 100644 --- a/plugins/intsights/unit_test/test_get_indicator_by_value.py +++ b/plugins/intsights/unit_test/test_get_indicator_by_value.py @@ -18,7 +18,7 @@ def setUpClass(cls, mock_request) -> None: @patch("requests.request", side_effect=Util.mock_request) def test_get_indicator_by_value_should_success(self, make_request): - actual = self.action.run({Input.INDICATOR_VALUE: 'example.com'}) + actual = self.action.run({Input.INDICATOR_VALUE: 'rapid7.com'}) expected = { 'first_seen': '2020-01-01T20:01:27.344Z', 'geo_location': 'US', @@ -33,7 +33,7 @@ def test_get_indicator_by_value_should_success(self, make_request): 'system_tags': ['Phishing'], 'tags': ['MyTag_1'], 'type': 'Domains', - 'value': 'example.com', + 'value': 'rapid7.com', 'whitelist': 'false' } self.assertEqual(expected, actual) diff --git a/plugins/intsights/unit_test/test_get_indicator_scan_status.py b/plugins/intsights/unit_test/test_get_indicator_scan_status.py new file mode 100644 index 0000000000..938d952f78 --- /dev/null +++ b/plugins/intsights/unit_test/test_get_indicator_scan_status.py @@ -0,0 +1,39 @@ +import sys +import os + +sys.path.append(os.path.abspath('../')) + +from unittest import TestCase +from unittest.mock import patch +from unit_test.util import Util +from icon_intsights.actions.get_indicator_scan_status import GetIndicatorScanStatus +from icon_intsights.actions.get_indicator_scan_status.schema import Input +from insightconnect_plugin_runtime.exceptions import PluginException + + +class TestRescanIndicator(TestCase): + @classmethod + @patch("requests.request", side_effect=Util.mock_request) + def setUpClass(cls, mock_request) -> None: + cls.action = Util.default_connector(GetIndicatorScanStatus()) + + @patch("requests.request", side_effect=Util.mock_request) + def test_rescan_indicator_should_success(self, make_request): + actual = self.action.run({ + Input.TASK_ID: "abcdefg123456" + }) + expected = { + 'status': 'InProgress', + 'task_id': 'abcdefg123456' + } + self.assertEqual(expected, actual) + + @patch("requests.request", side_effect=Util.mock_request) + def test_rescan_indicator_should_failed(self, make_request): + with self.assertRaises(PluginException) as error: + self.action.run({ + Input.TASK_ID: "bad" + }) + + self.assertEqual("There is an error in response.", error.exception.cause) + self.assertEqual("Invalid task id.", error.exception.assistance) diff --git a/plugins/intsights/unit_test/test_rescan_indicator.py b/plugins/intsights/unit_test/test_rescan_indicator.py new file mode 100644 index 0000000000..aab3a8746a --- /dev/null +++ b/plugins/intsights/unit_test/test_rescan_indicator.py @@ -0,0 +1,39 @@ +import sys +import os + +sys.path.append(os.path.abspath('../')) + +from unittest import TestCase +from unittest.mock import patch +from unit_test.util import Util +from icon_intsights.actions.rescan_indicator import RescanIndicator +from icon_intsights.actions.rescan_indicator.schema import Input +from insightconnect_plugin_runtime.exceptions import PluginException + + +class TestRescanIndicator(TestCase): + @classmethod + @patch("requests.request", side_effect=Util.mock_request) + def setUpClass(cls, mock_request) -> None: + cls.action = Util.default_connector(RescanIndicator()) + + @patch("requests.request", side_effect=Util.mock_request) + def test_rescan_indicator_should_success(self, make_request): + actual = self.action.run({ + Input.INDICATOR_FILE_HASH: "000003a16a5a1c6ccddbe548e852614224891111" + }) + expected = { + 'status': 'Queued', + 'task_id': 'abcdefg123456' + } + self.assertEqual(expected, actual) + + @patch("requests.request", side_effect=Util.mock_request) + def test_rescan_indicator_should_failed(self, make_request): + with self.assertRaises(PluginException) as error: + self.action.run({ + Input.INDICATOR_FILE_HASH: "bad" + }) + + self.assertEqual("There is an error in response.", error.exception.cause) + self.assertEqual("Invalid IOC value. Supported IOC types: file hashes.", error.exception.assistance) diff --git a/plugins/intsights/unit_test/util.py b/plugins/intsights/unit_test/util.py index 5c71065da3..657f21f555 100644 --- a/plugins/intsights/unit_test/util.py +++ b/plugins/intsights/unit_test/util.py @@ -34,26 +34,46 @@ def mock_request(*args, **kwargs): class MockResponse: def __init__(self, status_code: int, filename: str = None): self.status_code = status_code - self.text = '' - self.filename = filename + if filename: + self.text = Util.read_file_to_string(f'payloads/{filename}.json.resp') + else: + self.text = '' def json(self): - return json.loads(Util.read_file_to_string(f'payloads/{self.filename}.json.resp')) + return json.loads(self.text) if kwargs.get('url') == 'https://api.intsights.com/public/v1/test-credentials' \ and kwargs.get('auth').username == 'wrong': return MockResponse(401) elif kwargs.get('url') == 'https://api.intsights.com/public/v1/test-credentials': return MockResponse(200) - elif kwargs.get('url') == 'https://api.intsights.com/public/v2/iocs/ioc-by-value?iocValue=example.com': + elif kwargs.get('url') == 'https://api.intsights.com/public/v2/iocs/ioc-by-value?iocValue=rapid7.com': return MockResponse(200, 'iocs_ioc-by-value') - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/enrich/example.com' \ + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/enrich/rapid7.com' \ and Util.request_count == 0: Util.request_count = Util.request_count + 1 return MockResponse(200, 'enrich_indicator-in_progress') - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/enrich/example.com': + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/enrich/rapid7.com': return MockResponse(200, 'enrich_indicator') elif kwargs.get('url') == 'https://api.intsights.com/public/v2/iocs/ioc-by-value?iocValue=empty': return MockResponse(204) + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/data/alerts/add-alert': + return MockResponse(200, 'add_manual_alert') + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/data/alerts/alerts-list'\ + and kwargs.get('params', {}).get('alertType') == 'Phishing': + return MockResponse(200, 'get_alerts_empty_list') + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/data/alerts/alerts-list': + return MockResponse(200, 'get_alerts') + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/data/alerts/get-complete-alert/123': + return MockResponse(200, 'get_complete_alert_by_id') + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/rescan'\ + and kwargs.get('json', {}).get('IocValue') == 'bad': + return MockResponse(200, 'rescan_indicator.bad') + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/rescan/status/abcdefg123456': + return MockResponse(200, 'get_indicator_scan_status') + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/rescan/status/bad': + return MockResponse(200, 'get_indicator_scan_status.bad') + elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/rescan': + return MockResponse(200, 'rescan_indicator') else: - raise NotImplementedError('Not implemented') + raise NotImplementedError('Not implemented', kwargs) From b9bbc7d9470ecd7204462cbdeb78da8d2176a357 Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Fri, 1 Oct 2021 03:36:16 +0200 Subject: [PATCH 05/60] [MC-717][MC-718][MC-719][MC-720][MC-721][MC-722][MC-723][MC-725] Update help.md --- plugins/intsights/.CHECKSUM | 20 +- plugins/intsights/bin/icon_intsights | 2 - plugins/intsights/help.md | 199 +++++++++++++----- .../actions/add_manual_alert/schema.py | 5 +- .../actions/get_alerts/schema.py | 53 +++++ .../actions/get_indicator_by_value/schema.py | 1 + .../actions/takedown_request/schema.py | 12 +- .../icon_intsights/triggers/__init__.py | 1 - .../triggers/new_alert/__init__.py | 2 - .../triggers/new_alert/schema.py | 51 ----- .../triggers/new_alert/trigger.py | 21 -- plugins/intsights/plugin.spec.yaml | 122 +++-------- 12 files changed, 248 insertions(+), 241 deletions(-) mode change 100755 => 100644 plugins/intsights/help.md delete mode 100755 plugins/intsights/icon_intsights/triggers/new_alert/__init__.py delete mode 100755 plugins/intsights/icon_intsights/triggers/new_alert/schema.py delete mode 100755 plugins/intsights/icon_intsights/triggers/new_alert/trigger.py diff --git a/plugins/intsights/.CHECKSUM b/plugins/intsights/.CHECKSUM index 3bef03d265..4dc96c656e 100644 --- a/plugins/intsights/.CHECKSUM +++ b/plugins/intsights/.CHECKSUM @@ -1,15 +1,19 @@ { - "spec": "a820b26f2d06d061efd629ceb33890e0", - "manifest": "908ff295279c09826a062779c0912477", + "spec": "35d879856781246448ca75279a085f79", + "manifest": "c7a13778c7e5ccc8cf2e73ccc060ff04", "setup": "ea830b2af5f13706b38c5e288f0b6944", "schemas": [ + { + "identifier": "add_manual_alert/schema.py", + "hash": "66fe76d79131cfff95fd23f003539a3d" + }, { "identifier": "enrich_indicator/schema.py", "hash": "2f448ecb5acfe3083dbbfa71da28a785" }, { "identifier": "get_alerts/schema.py", - "hash": "09bb15b0d4612960fd2f9f24ce567e39" + "hash": "fcdda7f063170df1273ce18cd6206fa8" }, { "identifier": "get_complete_alert_by_id/schema.py", @@ -17,7 +21,7 @@ }, { "identifier": "get_indicator_by_value/schema.py", - "hash": "3bc77481896bc956c08c47ead9d243b2" + "hash": "6b4fc5e2ffb1217a4140607e6de6124b" }, { "identifier": "get_indicator_scan_status/schema.py", @@ -25,19 +29,15 @@ }, { "identifier": "rescan_indicator/schema.py", - "hash": "dfe65b33ee30ec56a07c489d9f9c12a3" + "hash": "5ff0acaac7454bf1f96d11b94dcad3e2" }, { "identifier": "takedown_request/schema.py", - "hash": "3337b1c3fec8889cfdde0d62e7adda08" + "hash": "e08d8b5e9f591e686637ff50114a2ba2" }, { "identifier": "connection/schema.py", "hash": "12bbf6684d6ecd35418685136b4437bd" - }, - { - "identifier": "new_alert/schema.py", - "hash": "ca5ffccc3606a5dde993f3c9688290c9" } ] } \ No newline at end of file diff --git a/plugins/intsights/bin/icon_intsights b/plugins/intsights/bin/icon_intsights index 088922f049..7d1b20dcd6 100755 --- a/plugins/intsights/bin/icon_intsights +++ b/plugins/intsights/bin/icon_intsights @@ -34,8 +34,6 @@ def main(): description=Description, connection=connection.Connection() ) - self.add_trigger(triggers.NewAlert()) - self.add_action(actions.AddManualAlert()) self.add_action(actions.EnrichIndicator()) diff --git a/plugins/intsights/help.md b/plugins/intsights/help.md old mode 100755 new mode 100644 index 1b75f68b0e..ba7393c17c --- a/plugins/intsights/help.md +++ b/plugins/intsights/help.md @@ -4,16 +4,23 @@ # Key Features -Identify key features of plugin. +* Get Indicator by Value +* Enrich Indicator +* Rescan Indicator +* Get Indicator Scan Status +* Get Alerts +* Get Complete Alert by ID +* Takedown Request +* Add Manual Alert # Requirements -* Example: Requires an API Key from the product -* Example: API must be enabled on the Settings page in the product's user interface +* Requires an Account ID for IntSights +* Requires API key for IntSights # Supported Product Versions -_There are no supported product versions listed._ +* 2.4.0 # Documentation @@ -41,27 +48,45 @@ Example input: #### Add Manual Alert -This action this action will create a manual alert with the provided parameters. +This action will create a manual alert with the provided parameters. ##### Input |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|description|string|None|True|Alert description|None|None| -|found_date|string|None|False|Alert found date|None|None| -|images|[]image|None|False|Alert images|None|None| -|severity|string|None|True|Alert severity|['High', 'Medium', 'Low']|None| -|source_date|string|None|False|Alert source date|None|None| -|source_network_type|string|None|True|Source network type|['ClearWeb', 'DarkWeb']|None| -|source_type|string|None|True|Source type|['Application Store', 'Cyber Security Blog', 'Hacking News', 'Cyber Crime Forum', 'Hacktivism Forum', 'Social Media', 'Facebook', 'Twitter', 'LinkedIn', 'Google Plus', 'VK', 'Vimeo', 'YouTube', 'IRC Channel', 'IOC Block List', 'Credit Card Black Market', 'Paste Site', 'Data Leakage Website', 'Leaked Database', 'File Sharing Website', 'Gray Hat Website', 'Black Market', 'WHOIS servers', 'Company Website', 'Wikileaks', 'Pinterest', 'Tumblr', 'Instagram', 'Telegram', 'Webmail', 'Malware Analysis', 'Firehol', 'VRA', 'Other']|None| -|source_url|string|None|True|Source URL|None|None| -|sub_type|string|None|True|Alert sub type, needs to correlate with the selected "Type"|None|None| -|title|string|None|True|Alert title|None|None| -|type|string|None|True|Alert type|['AttackIndication', 'DataLeakage', 'Phishing', 'BrandSecurity', 'ExploitableData', 'vip']|None| +|description|string|None|True|Alert description|None|Suspicious addresses| +|found_date|string|None|False|Alert found date|None|2020-01-01| +|images|[]image|None|False|Alert images|None|[{"Type": "jpeg","Data": "UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg=="}]| +|severity|string|None|True|Alert severity|['High', 'Medium', 'Low']|Medium| +|source_date|string|None|False|Alert source date|None|2020-02-01| +|source_network_type|string|None|True|Source network type|['ClearWeb', 'DarkWeb']|DarkWeb| +|source_type|string|None|True|Source type|['Application Store', 'Cyber Security Blog', 'Hacking News', 'Cyber Crime Forum', 'Hacktivism Forum', 'Social Media', 'Facebook', 'Twitter', 'LinkedIn', 'Google Plus', 'VK', 'Vimeo', 'YouTube', 'IRC Channel', 'IOC Block List', 'Credit Card Black Market', 'Paste Site', 'Data Leakage Website', 'Leaked Database', 'File Sharing Website', 'Gray Hat Website', 'Black Market', 'WHOIS servers', 'Company Website', 'Wikileaks', 'Pinterest', 'Tumblr', 'Instagram', 'Telegram', 'Webmail', 'Malware Analysis', 'Firehol', 'VRA']|Webmail| +|source_url|string|None|True|Source URL|None|https://example.com"| +|sub_type|string|None|True|Alert sub type, needs to correlate with the selected "Type"|None|SuspiciousEmailAddress| +|title|string|None|True|Alert title|None|New Alert| +|type|string|None|True|Alert type|['AttackIndication', 'DataLeakage', 'Phishing', 'BrandSecurity', 'ExploitableData', 'vip']|Phishing| Example input: ``` +{ + "description": "Suspicious addresses", + "found_date": "2020-01-01", + "images": [ + { + "Type": "jpeg", + "Data": "UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==" + } + ], + "severity": "Medium", + "source_date": "2020-02-01", + "source_network_type": "DarkWeb", + "source_type": "Webmail", + "source_url": "https://example.com", + "sub_type": "SuspiciousEmailAddress", + "title": "New Alert", + "type": "Phishing" +} ``` ##### Output @@ -73,7 +98,9 @@ Example input: Example output: ``` - +{ + "alert_id": "6156586e8eadf90008176450" +} ``` #### Takedown Request @@ -84,13 +111,14 @@ This action is used to request a takedown for a given alert in Intsights. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|alert_id|string|None|True|Alert's unique ID|None|None| +|alert_id|string|None|True|Alert's unique ID|None|44d88612fea8a8f36de82e12| |target|string|Domain|True|Target|['Website', 'Domain']|Domain| Example input: ``` { + "alert_id": "44d88612fea8a8f36de82e12", "target": "Domain" } ``` @@ -99,11 +127,12 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|response|object|True|Response from IntSights| +|status|boolean|True|Status from IntSights| Example output: ``` + ``` #### Get Complete Alert by ID @@ -114,11 +143,14 @@ This action is used to get an alert's complete details for a given alert ID. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|alert_id|string|None|True|Alert's unique ID|None|None| +|alert_id|string|None|True|Alert's unique ID|None|44d88612fea8a8f36de82e12| Example input: ``` +{ + "alert_id": "44d88612fea8a8f36de82e12" +} ``` ##### Output @@ -139,6 +171,30 @@ Example input: Example output: ``` +{ + "assets": [], + "assignees": [], + "details": { + "Description": "APIDescription", + "Images": [], + "Severity": "High", + "Source": { + "NetworkType": "ClearWeb", + "Type": "Application Store", + "URL": "https://example.com" + }, + "SubType": "SuspiciousEmailAddress", + "Tags": [], + "Title": "Alerttest3", + "Type": "Phishing" + }, + "found_date": "https://example.com", + "id": "6156118e186a05000774ee46", + "is_closed": false, + "is_flagged": false, + "takedown_status": "NotSent", + "update_date": "https://example.com" +} ``` #### Rescan Indicator @@ -149,11 +205,14 @@ This action is used to force an indicator scan in Intsights TIP system. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_file_hash|string|None|True|IOC value in type file hash|None|None| +|indicator_file_hash|string|None|True|IOC value in type file hash|None|30f800f97aeaa8d62bdf3a6fb2b0681179a360c12e127f07038f8521461e5050| Example input: ``` +{ + "indicator_file_hash": "275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f" +} ``` ##### Output @@ -166,7 +225,10 @@ Example input: Example output: ``` - +{ + "status": "Queued", + "task_id": "615658811baf672bdaeb8e5c" +} ``` #### Get Indicator Scan Status @@ -177,11 +239,14 @@ This action is used to get the scan status of an indicator in Insights TIP syste |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|task_id|string|None|True|A string representing the request ID|None|None| +|task_id|string|None|True|A string representing the request ID|None|123| Example input: ``` +{ + "task_id": 123 +} ``` ##### Output @@ -194,6 +259,10 @@ Example input: Example output: ``` +{ + "status": "Done", + "task_id": "61563eb2118b97e8e388e9db" +} ``` #### Get Alerts @@ -204,30 +273,39 @@ This action is used to search Alerts based on criteria. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|alert_type|string|None|False|Comma separated list of alert types. Allowed values - AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip|None|None| +|alert_type|string|None|False|Comma separated list of alert types. Allowed values - AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip|['AttackIndication', 'DataLeakage', 'Phishing', 'BrandSecurity', 'ExploitableData', 'vip']|Phishing| |assigned|boolean|None|False|Show assigned/unAssigned alerts|None|True| |found_date_from|number|None|False|Start date to fetch from in Unix Millisecond Timestamp|None|0| -|found_date_to|number|None|False|End date to fetch to in Unix Millisecond Timestamp|None|None| +|found_date_to|number|None|False|End date to fetch to in Unix Millisecond Timestamp|None|1633047102456| |has_indicators|boolean|None|False|Show alerts with IOCs results|None|False| |is_closed|boolean|None|False|Is closed/open alerts|None|False| |is_flagged|boolean|None|False|Show flagged/unflagged alerts|None|True| -|matched_asset_value|string|None|False|Comma separated list|None|None| -|network_type|string|None|False|Comma separated list of network type. Allowed values - ClearWeb, DarkWeb|None|None| -|remediation_status|string|None|False|Comma separated list of remediation status. Allowed values - InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed|None|None| -|severity|string|None|False|Comma separated list of alerts severity. Allowed values - High, Medium, Low|None|None| -|source_date_from|number|None|False|Start date to fetch from in Unix Millisecond Timestamp|None|None| -|source_date_to|number|None|False|End date to fetch to in Unix Millisecond Timestamp|None|None| -|source_type|string|None|False|Comma separated list of alerts source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others|None|None| +|matched_asset_value|string|None|False|Comma separated list|None|https://example.com| +|network_type|string|None|False|Comma separated list of network type. Allowed values - ClearWeb, DarkWeb|['ClearWeb', 'DarkWeb']|DarkWeb| +|remediation_status|string|None|False|Comma separated list of remediation status. Allowed values - InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed|None|InProggres, Pending| +|severity|string|None|False|Comma separated list of alerts severity. Allowed values - High, Medium, Low|['High', 'Medium', 'Low']|Low| +|source_date_from|number|None|False|Start date to fetch from in Unix Millisecond Timestamp|None|1633047083142| +|source_date_to|number|None|False|End date to fetch to in Unix Millisecond Timestamp|None|1633047102456| +|source_type|string|None|False|Comma separated list of alerts source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others|['Application Store', 'Cyber Security Blog', 'Hacking News', 'Cyber Crime Forum', 'Hacktivism Forum', 'Social Media', 'Facebook', 'Twitter', 'LinkedIn', 'Google Plus', 'VK', 'Vimeo', 'YouTube', 'IRC Channel', 'IOC Block List', 'Credit Card Black Market', 'Paste Site', 'Data Leakage Website', 'Leaked Database', 'File Sharing Website', 'Gray Hat Website', 'Black Market', 'WHOIS servers', 'Company Website', 'Wikileaks', 'Pinterest', 'Tumblr', 'Instagram', 'Telegram', 'Webmail', 'Malware Analysis', 'Firehol', 'VRA', 'Other']|Application Store| Example input: ``` { + "alert_type": "Phishing", "assigned": true, "found_date_from": 0, + "found_date_to": 1633047102456, "has_indicators": false, "is_closed": false, - "is_flagged": true + "is_flagged": true, + "matched_asset_value": "example.com", + "network_type": "DarkWeb", + "remediation_status": "InProggres, Pending", + "severity": "Low", + "source_date_from": 1633047083142, + "source_date_to": 1633047102456, + "source_type": "Application Store" } ``` @@ -240,6 +318,12 @@ Example input: Example output: ``` +{ + "alert_ids": [ + "6155f7b7c6e9d40008b4bb0d", + "6155f801186a050007745d29" + ] +} ``` #### Enrich Indicator @@ -473,7 +557,7 @@ Example output: #### Get Indicator by Value -This action this action will search indicators in Intsights TIP. +This action will search indicators in IntSights TIP. ##### Input @@ -512,32 +596,48 @@ Example input: Example output: ``` +{ + "first_seen": "https://example.com", + "last_seen": "https://example.com", + "last_update": "https://example.com", + "related_campaigns": [], + "related_malware": [], + "related_threat_actors": [], + "score": 10, + "severity": "Low", + "sources": [ + { + "ConfidenceLevel": 2, + "Name": "Cyber Threat Alliance" + } + ], + "system_tags": [], + "tags": [], + "type": "Domains", + "value": "https://example.com", + "whitelist": true +} ``` ### Triggers -#### New Alert - -This trigger is used to run when a new alert that matches the given criteria is created in IntSights. +_This plugin does not contain any triggers._ -##### Input +### Custom Output Types -_This trigger does not contain any inputs._ - -##### Output +#### image |Name|Type|Required|Description| |----|----|--------|-----------| -|response|[]string|True|Response| - -Example output: - -``` -``` +|Data|string|True|Data| +|Type|string|True|Type| -### Custom Output Types +#### source -_This plugin does not contain any custom output types._ +|Name|Type|Required|Description| +|----|----|--------|-----------| +|Confidence Level|integer|True|Level of confidence| +|Name|string|True|Name| ## Troubleshooting @@ -552,4 +652,3 @@ _This plugin does not contain any troubleshooting information._ ## References * [IntSights](https://intsights.com/) - diff --git a/plugins/intsights/icon_intsights/actions/add_manual_alert/schema.py b/plugins/intsights/icon_intsights/actions/add_manual_alert/schema.py index 5a886dcae9..4b907741b4 100755 --- a/plugins/intsights/icon_intsights/actions/add_manual_alert/schema.py +++ b/plugins/intsights/icon_intsights/actions/add_manual_alert/schema.py @@ -4,7 +4,7 @@ class Component: - DESCRIPTION = "This action will create a manual alert with the provided parameters" + DESCRIPTION = "Create a manual alert with the provided parameters" class Input: @@ -116,8 +116,7 @@ class AddManualAlertInput(insightconnect_plugin_runtime.Input): "Webmail", "Malware Analysis", "Firehol", - "VRA", - "Other" + "VRA" ], "order": 6 }, diff --git a/plugins/intsights/icon_intsights/actions/get_alerts/schema.py b/plugins/intsights/icon_intsights/actions/get_alerts/schema.py index b27fb41129..2a3e5ddc37 100755 --- a/plugins/intsights/icon_intsights/actions/get_alerts/schema.py +++ b/plugins/intsights/icon_intsights/actions/get_alerts/schema.py @@ -38,6 +38,14 @@ class GetAlertsInput(insightconnect_plugin_runtime.Input): "type": "string", "title": "Alert Type", "description": "Comma separated list of alert types. Allowed values - AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip", + "enum": [ + "AttackIndication", + "DataLeakage", + "Phishing", + "BrandSecurity", + "ExploitableData", + "vip" + ], "order": 1 }, "assigned": { @@ -86,6 +94,10 @@ class GetAlertsInput(insightconnect_plugin_runtime.Input): "type": "string", "title": "Network Type", "description": "Comma separated list of network type. Allowed values - ClearWeb, DarkWeb", + "enum": [ + "ClearWeb", + "DarkWeb" + ], "order": 4 }, "remediation_status": { @@ -98,6 +110,11 @@ class GetAlertsInput(insightconnect_plugin_runtime.Input): "type": "string", "title": "Severity", "description": "Comma separated list of alerts severity. Allowed values - High, Medium, Low", + "enum": [ + "High", + "Medium", + "Low" + ], "order": 2 }, "source_date_from": { @@ -116,6 +133,42 @@ class GetAlertsInput(insightconnect_plugin_runtime.Input): "type": "string", "title": "Source Type", "description": "Comma separated list of alerts source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others", + "enum": [ + "Application Store", + "Cyber Security Blog", + "Hacking News", + "Cyber Crime Forum", + "Hacktivism Forum", + "Social Media", + "Facebook", + "Twitter", + "LinkedIn", + "Google Plus", + "VK", + "Vimeo", + "YouTube", + "IRC Channel", + "IOC Block List", + "Credit Card Black Market", + "Paste Site", + "Data Leakage Website", + "Leaked Database", + "File Sharing Website", + "Gray Hat Website", + "Black Market", + "WHOIS servers", + "Company Website", + "Wikileaks", + "Pinterest", + "Tumblr", + "Instagram", + "Telegram", + "Webmail", + "Malware Analysis", + "Firehol", + "VRA", + "Other" + ], "order": 3 } } diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py index e11d5e2e37..fd9c5cddae 100755 --- a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py +++ b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py @@ -191,6 +191,7 @@ class GetIndicatorByValueOutput(insightconnect_plugin_runtime.Output): "Name": { "type": "string", "title": "Name", + "description": "Name", "order": 1 } }, diff --git a/plugins/intsights/icon_intsights/actions/takedown_request/schema.py b/plugins/intsights/icon_intsights/actions/takedown_request/schema.py index aa60164206..b00cec8ac0 100755 --- a/plugins/intsights/icon_intsights/actions/takedown_request/schema.py +++ b/plugins/intsights/icon_intsights/actions/takedown_request/schema.py @@ -13,7 +13,7 @@ class Input: class Output: - RESPONSE = "response" + STATUS = "status" class TakedownRequestInput(insightconnect_plugin_runtime.Input): @@ -57,15 +57,15 @@ class TakedownRequestOutput(insightconnect_plugin_runtime.Output): "type": "object", "title": "Variables", "properties": { - "response": { - "type": "object", - "title": "Response", - "description": "Response from IntSights", + "status": { + "type": "boolean", + "title": "Status", + "description": "Status from IntSights", "order": 1 } }, "required": [ - "response" + "status" ] } """) diff --git a/plugins/intsights/icon_intsights/triggers/__init__.py b/plugins/intsights/icon_intsights/triggers/__init__.py index 9fb0d5a464..bace8db897 100755 --- a/plugins/intsights/icon_intsights/triggers/__init__.py +++ b/plugins/intsights/icon_intsights/triggers/__init__.py @@ -1,2 +1 @@ # GENERATED BY KOMAND SDK - DO NOT EDIT -from .new_alert.trigger import NewAlert diff --git a/plugins/intsights/icon_intsights/triggers/new_alert/__init__.py b/plugins/intsights/icon_intsights/triggers/new_alert/__init__.py deleted file mode 100755 index 8d0f48bfdb..0000000000 --- a/plugins/intsights/icon_intsights/triggers/new_alert/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -from .trigger import NewAlert diff --git a/plugins/intsights/icon_intsights/triggers/new_alert/schema.py b/plugins/intsights/icon_intsights/triggers/new_alert/schema.py deleted file mode 100755 index 0a6446b042..0000000000 --- a/plugins/intsights/icon_intsights/triggers/new_alert/schema.py +++ /dev/null @@ -1,51 +0,0 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -import insightconnect_plugin_runtime -import json - - -class Component: - DESCRIPTION = "Run when a new alert that matches the given criteria is created in IntSights" - - -class Input: - pass - - -class Output: - - RESPONSE = "response" - - -class NewAlertInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" - {} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) - - -class NewAlertOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" - { - "type": "object", - "title": "Variables", - "properties": { - "response": { - "type": "array", - "title": "Response", - "description": "Response", - "items": { - "type": "string" - }, - "order": 1 - } - }, - "required": [ - "response" - ] -} - """) - - def __init__(self): - super(self.__class__, self).__init__(self.schema) diff --git a/plugins/intsights/icon_intsights/triggers/new_alert/trigger.py b/plugins/intsights/icon_intsights/triggers/new_alert/trigger.py deleted file mode 100755 index 6ca40aad2d..0000000000 --- a/plugins/intsights/icon_intsights/triggers/new_alert/trigger.py +++ /dev/null @@ -1,21 +0,0 @@ -import insightconnect_plugin_runtime -import time -from .schema import NewAlertInput, NewAlertOutput, Input, Output, Component -# Custom imports below - - -class NewAlert(insightconnect_plugin_runtime.Trigger): - - def __init__(self): - super(self.__class__, self).__init__( - name='new_alert', - description=Component.DESCRIPTION, - input=NewAlertInput(), - output=NewAlertOutput()) - - def run(self, params={}): - """Run the trigger""" - while True: - # TODO: Implement trigger functionality - self.send({}) - time.sleep(params.get("interval", 5)) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 17114894d3..89c06986b1 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -5,7 +5,7 @@ name: intsights title: IntSights description: IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy version: 1.0.0 -supported_versions: [] +supported_versions: ["2.4.0"] vendor: rapid7 support: rapid7 status: [] @@ -25,7 +25,7 @@ types: source: Name: title: Name - descirption: Name + description: Name type: string required: true ConfidenceLevel: @@ -179,6 +179,7 @@ actions: description: IOC value in type file hash type: string required: true + example: 275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f output: task_id: title: Task ID @@ -199,6 +200,7 @@ actions: description: A string representing the request ID type: string required: true + example: 123 output: task_id: title: Task ID @@ -226,6 +228,7 @@ actions: - BrandSecurity - ExploitableData - vip + example: Phishing severity: title: Severity description: Comma separated list of alerts severity. Allowed values - High, Medium, Low @@ -235,6 +238,7 @@ actions: - High - Medium - Low + example: Low source_type: title: Source Type description: Comma separated list of alerts source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others @@ -275,6 +279,7 @@ actions: - Firehol - VRA - Other + example: Application Store network_type: title: Network Type description: Comma separated list of network type. Allowed values - ClearWeb, DarkWeb @@ -283,26 +288,31 @@ actions: enum: - ClearWeb - DarkWeb + example: DarkWeb matched_asset_value: title: Matched Asset Value description: Comma separated list type: string required: false + example: example.com remediation_status: title: Remediation Status description: Comma separated list of remediation status. Allowed values - InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed type: string required: false + example: InProggres, Pending source_date_from: title: Source Date From description: Start date to fetch from in Unix Millisecond Timestamp type: number required: false + example: 1633047083142 source_date_to: title: Source Date To description: End date to fetch to in Unix Millisecond Timestamp type: number required: false + example: 1633047102456 found_date_from: title: Found Date From description: Start date to fetch from in Unix Millisecond Timestamp @@ -314,6 +324,7 @@ actions: description: End date to fetch to in Unix Millisecond Timestamp type: number required: false + example: 1633047102456 assigned: title: Assigned description: Show assigned/unAssigned alerts @@ -353,6 +364,7 @@ actions: description: Alert's unique ID type: string required: true + example: 44d88612fea8a8f36de82e12 output: id: title: ID @@ -413,6 +425,7 @@ actions: description: Alert's unique ID type: string required: true + example: 44d88612fea8a8f36de82e12 target: title: Target description: Target @@ -431,18 +444,20 @@ actions: required: true add_manual_alert: title: Add Manual Alert - description: This action will create a manual alert with the provided parameters + description: Create a manual alert with the provided parameters input: title: title: Title description: Alert title type: string required: true + example: New Alert description: title: Description description: Alert description type: string required: true + example: Suspicious addresses type: title: Type description: Alert type @@ -455,11 +470,13 @@ actions: - BrandSecurity - ExploitableData - vip + example: Phishing sub_type: title: Sub Type description: Alert sub type, needs to correlate with the selected "Type" type: string required: true + example: SuspiciousEmailAddress severity: title: Severity description: Alert severity @@ -469,6 +486,7 @@ actions: - High - Medium - Low + example: Medium source_type: title: Source Type description: Source type @@ -508,7 +526,7 @@ actions: - Malware Analysis - Firehol - VRA - - Other + example: Webmail source_network_type: title: Source Network Type description: Source network type @@ -517,120 +535,34 @@ actions: enum: - ClearWeb - DarkWeb + example: DarkWeb source_url: title: Source URL description: Source URL type: string required: true + example: https://example.com" found_date: title: Found Date description: Alert found date type: string required: false + example: 2020-01-01 source_date: title: Source Date description: Alert source date type: string required: false + example: 2020-02-01 images: title: Images description: Alert images type: "[]image" required: false + example: '[{"Type": "jpeg","Data": "UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg=="}]' output: alert_id: title: Alert ID description: New created alert ID type: string required: true - -triggers: - new_alert: - title: New Alert - description: Run when a new alert that matches the given criteria is created in IntSights - inputs: - alert_type: - title: Alert Type - description: Coma separated list of alerts type. Allowed values - AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip - type: string - required: false - example: AttackIndication, DataLeakage - severity: - title: Severity - description: Coma separated list of severity. Allowed values - High, Medium, Low - type: string - required: false - example: High - source_type: - title: Source Type - description: Coma separated list of source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others - type: string - required: false - example: ApplicationStores, BlackMarkets - network_type: - title: Network Type - description: Coma separated list of network type. Allowed values - ClearWeb, DarkWeb - type: string - required: false - example: ClearWeb - matched_asset_value: - title: Matched Asset Value - description: Coma separated list of network matched asset value - type: string - required: false - remediation_status: - title: Remediation Status - description: Coma separated list of alert's remediation status. Allowed values - InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed - type: string - required: false - source_date_from: - title: Source Date From - description: Start date to fetch from in Unix Millisecond Timestamp - type: number - required: false - end_date_to: - title: End Date To - description: End date to fetch to in Unix Millisecond Timestam - type: number - required: false - found_date_from: - title: Found Date From - description: Start date to fetch from in Unix Millisecond Timestamp - type: number - required: false - example: 0 - found_date_to: - title: Found Date To - description: End date to fetch to in Unix Millisecond Timestamp - type: number - required: false - assigned: - title: Assigned - description: Show assigned/unAssigned alerts - type: boolean - required: false - example: true - is_flagged: - title: Is Flagged - description: Show flagged/unflagged alerts - type: boolean - required: false - example: true - is_closed: - title: Is Closed - description: Is closed/open alerts - type: boolean - required: false - example: false - has_indicators: - title: Has Indicators - description: Show alerts with IOCs results - type: boolean - required: false - example: false - output: - response: - title: Response - description: Response - type: "[]string" - required: true \ No newline at end of file From d63344c2e33e7ab4aca6ef2a1495b008d61e9402 Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Fri, 1 Oct 2021 03:48:10 +0200 Subject: [PATCH 06/60] Revert: Add microsoft ATP Black reformat --- .../actions/add_manual_alert/action.py | 39 ++--- .../actions/enrich_indicator/action.py | 17 +-- .../actions/get_alerts/action.py | 12 +- .../get_complete_alert_by_id/action.py | 37 ++--- .../actions/get_indicator_by_value/action.py | 47 +++--- .../get_indicator_scan_status/action.py | 16 +-- .../actions/rescan_indicator/action.py | 16 +-- .../actions/takedown_request/action.py | 20 ++- .../icon_intsights/connection/connection.py | 13 +- plugins/intsights/icon_intsights/util/api.py | 134 ++++++++---------- .../unit_test/test_add_manual_alert.py | 36 ++--- .../intsights/unit_test/test_connection.py | 20 +-- .../unit_test/test_enrich_indicator.py | 12 +- .../intsights/unit_test/test_get_alerts.py | 32 ++--- .../test_get_complete_alert_by_id.py | 44 +++--- .../unit_test/test_get_indicator_by_value.py | 52 +++---- .../test_get_indicator_scan_status.py | 15 +- .../unit_test/test_rescan_indicator.py | 15 +- plugins/intsights/unit_test/util.py | 77 +++++----- plugins/microsoft_atp/.CHECKSUM | 2 +- plugins/microsoft_atp/help.md | 44 +++--- 21 files changed, 327 insertions(+), 373 deletions(-) diff --git a/plugins/intsights/icon_intsights/actions/add_manual_alert/action.py b/plugins/intsights/icon_intsights/actions/add_manual_alert/action.py index 318c1526ce..a5f205c5bc 100755 --- a/plugins/intsights/icon_intsights/actions/add_manual_alert/action.py +++ b/plugins/intsights/icon_intsights/actions/add_manual_alert/action.py @@ -1,31 +1,34 @@ import insightconnect_plugin_runtime from .schema import AddManualAlertInput, AddManualAlertOutput, Input, Output, Component + # Custom imports below from icon_intsights.util.api import ManualAlertParams class AddManualAlert(insightconnect_plugin_runtime.Action): - def __init__(self): super(self.__class__, self).__init__( - name='add_manual_alert', - description=Component.DESCRIPTION, - input=AddManualAlertInput(), - output=AddManualAlertOutput()) + name="add_manual_alert", + description=Component.DESCRIPTION, + input=AddManualAlertInput(), + output=AddManualAlertOutput(), + ) def run(self, params={}): return { - Output.ALERT_ID: self.connection.client.add_manual_alert(ManualAlertParams( - title=params.get(Input.TITLE), - found_date=params.get(Input.FOUND_DATE), - description=params.get(Input.DESCRIPTION), - type=params.get(Input.TYPE), - sub_type=params.get(Input.SUB_TYPE), - severity=params.get(Input.SEVERITY), - source_type=params.get(Input.SOURCE_TYPE), - source_network_type=params.get(Input.SOURCE_NETWORK_TYPE), - source_url=params.get(Input.SOURCE_URL), - source_date=params.get(Input.SOURCE_DATE), - images=params.get(Input.IMAGES) - )) + Output.ALERT_ID: self.connection.client.add_manual_alert( + ManualAlertParams( + title=params.get(Input.TITLE), + found_date=params.get(Input.FOUND_DATE), + description=params.get(Input.DESCRIPTION), + type=params.get(Input.TYPE), + sub_type=params.get(Input.SUB_TYPE), + severity=params.get(Input.SEVERITY), + source_type=params.get(Input.SOURCE_TYPE), + source_network_type=params.get(Input.SOURCE_NETWORK_TYPE), + source_url=params.get(Input.SOURCE_URL), + source_date=params.get(Input.SOURCE_DATE), + images=params.get(Input.IMAGES), + ) + ) } diff --git a/plugins/intsights/icon_intsights/actions/enrich_indicator/action.py b/plugins/intsights/icon_intsights/actions/enrich_indicator/action.py index 604117e776..28468ed45e 100755 --- a/plugins/intsights/icon_intsights/actions/enrich_indicator/action.py +++ b/plugins/intsights/icon_intsights/actions/enrich_indicator/action.py @@ -1,21 +1,22 @@ import insightconnect_plugin_runtime from .schema import EnrichIndicatorInput, EnrichIndicatorOutput, Input, Output, Component + # Custom imports below class EnrichIndicator(insightconnect_plugin_runtime.Action): - def __init__(self): super(self.__class__, self).__init__( - name='enrich_indicator', - description=Component.DESCRIPTION, - input=EnrichIndicatorInput(), - output=EnrichIndicatorOutput()) + name="enrich_indicator", + description=Component.DESCRIPTION, + input=EnrichIndicatorInput(), + output=EnrichIndicatorOutput(), + ) def run(self, params={}): response = self.connection.client.enrich_indicator(params.get(Input.INDICATOR_VALUE)) return { - Output.ORIGINAL_VALUE: response.get('OriginalValue'), - Output.STATUS: response.get('Status'), - Output.DATA: response.get('Data', {}) + Output.ORIGINAL_VALUE: response.get("OriginalValue"), + Output.STATUS: response.get("Status"), + Output.DATA: response.get("Data", {}), } diff --git a/plugins/intsights/icon_intsights/actions/get_alerts/action.py b/plugins/intsights/icon_intsights/actions/get_alerts/action.py index 9a6ef84cc1..ae46ef37dc 100755 --- a/plugins/intsights/icon_intsights/actions/get_alerts/action.py +++ b/plugins/intsights/icon_intsights/actions/get_alerts/action.py @@ -1,17 +1,15 @@ import insightconnect_plugin_runtime from .schema import GetAlertsInput, GetAlertsOutput, Input, Output, Component + # Custom imports below from icon_intsights.util.api import AlertParams class GetAlerts(insightconnect_plugin_runtime.Action): - def __init__(self): super(self.__class__, self).__init__( - name='get_alerts', - description=Component.DESCRIPTION, - input=GetAlertsInput(), - output=GetAlertsOutput()) + name="get_alerts", description=Component.DESCRIPTION, input=GetAlertsInput(), output=GetAlertsOutput() + ) def run(self, params={}): alert_params = AlertParams( @@ -31,6 +29,4 @@ def run(self, params={}): has_ioc=params.get(Input.HAS_INDICATORS), ) response = self.connection.client.get_alerts(alert_params) - return { - Output.ALERT_IDS: response - } + return {Output.ALERT_IDS: response} diff --git a/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py b/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py index 75bfc43580..91d07775bb 100755 --- a/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py +++ b/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py @@ -1,29 +1,32 @@ import insightconnect_plugin_runtime from .schema import GetCompleteAlertByIdInput, GetCompleteAlertByIdOutput, Input, Output, Component + # Custom imports below from insightconnect_plugin_runtime.helper import clean class GetCompleteAlertById(insightconnect_plugin_runtime.Action): - def __init__(self): super(self.__class__, self).__init__( - name='get_complete_alert_by_id', - description=Component.DESCRIPTION, - input=GetCompleteAlertByIdInput(), - output=GetCompleteAlertByIdOutput()) + name="get_complete_alert_by_id", + description=Component.DESCRIPTION, + input=GetCompleteAlertByIdInput(), + output=GetCompleteAlertByIdOutput(), + ) def run(self, params={}): response = self.connection.client.get_complete_alert_by_id(params.get(Input.ALERT_ID)) - return clean({ - Output.ID: response.get('_id'), - Output.ASSETS: response.get('Assets', []), - Output.ASSIGNEES: response.get('Assignees', []), - Output.DETAILS: response.get('Details', {}), - Output.FOUND_DATE: response.get('FoundDate'), - Output.UPDATE_DATE: response.get('UpdateDate'), - Output.TAKEDOWN_STATUS: response.get('TakedownStatus'), - Output.IS_CLOSED: response.get('IsClosed', False), - Output.IS_FLAGGED: response.get('IsFlagged', False), - Output.LEAK_NAME: response.get('LeakName'), - }) + return clean( + { + Output.ID: response.get("_id"), + Output.ASSETS: response.get("Assets", []), + Output.ASSIGNEES: response.get("Assignees", []), + Output.DETAILS: response.get("Details", {}), + Output.FOUND_DATE: response.get("FoundDate"), + Output.UPDATE_DATE: response.get("UpdateDate"), + Output.TAKEDOWN_STATUS: response.get("TakedownStatus"), + Output.IS_CLOSED: response.get("IsClosed", False), + Output.IS_FLAGGED: response.get("IsFlagged", False), + Output.LEAK_NAME: response.get("LeakName"), + } + ) diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py index 728c5612de..56bf730c27 100755 --- a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py +++ b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py @@ -1,34 +1,37 @@ import insightconnect_plugin_runtime from .schema import GetIndicatorByValueInput, GetIndicatorByValueOutput, Input, Output, Component + # Custom imports below from insightconnect_plugin_runtime.helper import clean class GetIndicatorByValue(insightconnect_plugin_runtime.Action): - def __init__(self): super(self.__class__, self).__init__( - name='get_indicator_by_value', - description=Component.DESCRIPTION, - input=GetIndicatorByValueInput(), - output=GetIndicatorByValueOutput()) + name="get_indicator_by_value", + description=Component.DESCRIPTION, + input=GetIndicatorByValueInput(), + output=GetIndicatorByValueOutput(), + ) def run(self, params={}): response = self.connection.client.get_indicator_by_value(params.get(Input.INDICATOR_VALUE)) - return clean({ - Output.VALUE: response.get('Value'), - Output.TYPE: response.get('Type'), - Output.SEVERITY: response.get('Severity'), - Output.SCORE: response.get('Score', 0), - Output.WHITELIST: response.get('Whitelist', False), - Output.FIRST_SEEN: response.get('FirstSeen'), - Output.LAST_SEEN: response.get('LastSeen'), - Output.LAST_UPDATE: response.get('LastUpdate'), - Output.GEO_LOCATION: response.get('Geolocation'), - Output.SOURCES: response.get('Sources', []), - Output.TAGS: response.get('Tags', []), - Output.SYSTEM_TAGS: response.get('SystemTags', []), - Output.RELATED_MALWARE: response.get('RelatedMalware', []), - Output.RELATED_CAMPAIGNS: response.get('RelatedCampaigns', []), - Output.RELATED_THREAT_ACTORS: response.get('RelatedThreatActors', []), - }) + return clean( + { + Output.VALUE: response.get("Value"), + Output.TYPE: response.get("Type"), + Output.SEVERITY: response.get("Severity"), + Output.SCORE: response.get("Score", 0), + Output.WHITELIST: response.get("Whitelist", False), + Output.FIRST_SEEN: response.get("FirstSeen"), + Output.LAST_SEEN: response.get("LastSeen"), + Output.LAST_UPDATE: response.get("LastUpdate"), + Output.GEO_LOCATION: response.get("Geolocation"), + Output.SOURCES: response.get("Sources", []), + Output.TAGS: response.get("Tags", []), + Output.SYSTEM_TAGS: response.get("SystemTags", []), + Output.RELATED_MALWARE: response.get("RelatedMalware", []), + Output.RELATED_CAMPAIGNS: response.get("RelatedCampaigns", []), + Output.RELATED_THREAT_ACTORS: response.get("RelatedThreatActors", []), + } + ) diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py b/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py index 6528a1b5ae..3650030dce 100755 --- a/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py +++ b/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py @@ -1,20 +1,18 @@ import insightconnect_plugin_runtime from .schema import GetIndicatorScanStatusInput, GetIndicatorScanStatusOutput, Input, Output, Component + # Custom imports below class GetIndicatorScanStatus(insightconnect_plugin_runtime.Action): - def __init__(self): super(self.__class__, self).__init__( - name='get_indicator_scan_status', - description=Component.DESCRIPTION, - input=GetIndicatorScanStatusInput(), - output=GetIndicatorScanStatusOutput()) + name="get_indicator_scan_status", + description=Component.DESCRIPTION, + input=GetIndicatorScanStatusInput(), + output=GetIndicatorScanStatusOutput(), + ) def run(self, params={}): response = self.connection.client.get_scan_status(params.get(Input.TASK_ID)) - return { - Output.TASK_ID: response.get('TaskId'), - Output.STATUS: response.get('Status') - } + return {Output.TASK_ID: response.get("TaskId"), Output.STATUS: response.get("Status")} diff --git a/plugins/intsights/icon_intsights/actions/rescan_indicator/action.py b/plugins/intsights/icon_intsights/actions/rescan_indicator/action.py index 3b4f148991..d9444a8a2e 100755 --- a/plugins/intsights/icon_intsights/actions/rescan_indicator/action.py +++ b/plugins/intsights/icon_intsights/actions/rescan_indicator/action.py @@ -1,21 +1,19 @@ import insightconnect_plugin_runtime from .schema import RescanIndicatorInput, RescanIndicatorOutput, Input, Output, Component + # Custom imports below from insightconnect_plugin_runtime.helper import clean class RescanIndicator(insightconnect_plugin_runtime.Action): - def __init__(self): super(self.__class__, self).__init__( - name='rescan_indicator', - description=Component.DESCRIPTION, - input=RescanIndicatorInput(), - output=RescanIndicatorOutput()) + name="rescan_indicator", + description=Component.DESCRIPTION, + input=RescanIndicatorInput(), + output=RescanIndicatorOutput(), + ) def run(self, params={}): response = self.connection.client.rescan_indicator(params.get(Input.INDICATOR_FILE_HASH)) - return clean({ - Output.TASK_ID: response.get('TaskId'), - Output.STATUS: response.get('Status') - }) + return clean({Output.TASK_ID: response.get("TaskId"), Output.STATUS: response.get("Status")}) diff --git a/plugins/intsights/icon_intsights/actions/takedown_request/action.py b/plugins/intsights/icon_intsights/actions/takedown_request/action.py index e0a703bb4c..c74866a544 100755 --- a/plugins/intsights/icon_intsights/actions/takedown_request/action.py +++ b/plugins/intsights/icon_intsights/actions/takedown_request/action.py @@ -1,23 +1,19 @@ import insightconnect_plugin_runtime from .schema import TakedownRequestInput, TakedownRequestOutput, Input, Output, Component + # Custom imports below from insightconnect_plugin_runtime.helper import clean class TakedownRequest(insightconnect_plugin_runtime.Action): - def __init__(self): super(self.__class__, self).__init__( - name='takedown_request', - description=Component.DESCRIPTION, - input=TakedownRequestInput(), - output=TakedownRequestOutput()) + name="takedown_request", + description=Component.DESCRIPTION, + input=TakedownRequestInput(), + output=TakedownRequestOutput(), + ) def run(self, params={}): - self.connection.client.takedown_request( - params.get(Input.ALERT_ID), - params.get(Input.TARGET) - ) - return clean({ - Output.STATUS: True - }) + self.connection.client.takedown_request(params.get(Input.ALERT_ID), params.get(Input.TARGET)) + return clean({Output.STATUS: True}) diff --git a/plugins/intsights/icon_intsights/connection/connection.py b/plugins/intsights/icon_intsights/connection/connection.py index cccd8ce7c2..f78d5b5a8d 100755 --- a/plugins/intsights/icon_intsights/connection/connection.py +++ b/plugins/intsights/icon_intsights/connection/connection.py @@ -1,22 +1,22 @@ import insightconnect_plugin_runtime from typing import Optional from .schema import ConnectionSchema, Input + # Custom imports below from icon_intsights.util.api import IntSightAPI from insightconnect_plugin_runtime.exceptions import PluginException, ConnectionTestException class Connection(insightconnect_plugin_runtime.Connection): - def __init__(self): super(self.__class__, self).__init__(input=ConnectionSchema()) self.client: Optional[IntSightAPI] = None def connect(self, params={}): self.client = IntSightAPI( - params.get(Input.ACCOUNT_ID, {}).get('secretKey'), - params.get(Input.API_KEY, {}).get('secretKey'), - self.logger + params.get(Input.ACCOUNT_ID, {}).get("secretKey"), + params.get(Input.API_KEY, {}).get("secretKey"), + self.logger, ) self.logger.info("Connect: Connecting...") @@ -24,7 +24,4 @@ def test(self): try: return {"success": self.client.test_credentials()} except PluginException as e: - raise ConnectionTestException( - cause=e.cause, - assistance=e.assistance - ) + raise ConnectionTestException(cause=e.cause, assistance=e.assistance) diff --git a/plugins/intsights/icon_intsights/util/api.py b/plugins/intsights/icon_intsights/util/api.py index 5e48feec7a..c1d825f5da 100644 --- a/plugins/intsights/icon_intsights/util/api.py +++ b/plugins/intsights/icon_intsights/util/api.py @@ -26,22 +26,24 @@ class AlertParams: has_ioc: bool def to_dict(self) -> dict: - return clean({ - 'alertType': self.alert_type, - 'severity': self.severity, - 'sourceType': self.source_type, - 'networkType': self.network_type, - 'matchedAssetValue': self.matched_asset_value, - 'remediationStatus': self.remediation_status, - 'sourceDateFrom': self.source_date_from, - 'sourceDateTo': self.source_date_to, - 'foundDateFrom': self.found_date_from, - 'foundDateTo': self.found_date_to, - 'assigned': self.assigned, - 'isFlagged': self.is_flagged, - 'isClosed': self.is_closed, - 'hasIoc': self.has_ioc, - }) + return clean( + { + "alertType": self.alert_type, + "severity": self.severity, + "sourceType": self.source_type, + "networkType": self.network_type, + "matchedAssetValue": self.matched_asset_value, + "remediationStatus": self.remediation_status, + "sourceDateFrom": self.source_date_from, + "sourceDateTo": self.source_date_to, + "foundDateFrom": self.found_date_from, + "foundDateTo": self.found_date_to, + "assigned": self.assigned, + "isFlagged": self.is_flagged, + "isClosed": self.is_closed, + "hasIoc": self.has_ioc, + } + ) @dataclass @@ -71,93 +73,76 @@ def to_dict(self) -> dict: if not image: continue try: - images.append({ - "Type": image["type"], - "Data": image["data"] - }) + images.append({"Type": image["type"], "Data": image["data"]}) except KeyError as e: - raise PluginException( - cause="Wrong input parameter.", - assistance=f"Wrong image: {e}." - ) - - return clean({ - 'FoundDate': self.found_date, - 'Details': { - "Title": self.title, - "Description": self.description, - "Type": self.type, - "SubType": self.sub_type, - "Severity": self.severity, - "Source": { - "Type": self.source_type, - "NetworkType": self.source_network_type, - "URL": self.source_url, - "Date": self.source_date + raise PluginException(cause="Wrong input parameter.", assistance=f"Wrong image: {e}.") + + return clean( + { + "FoundDate": self.found_date, + "Details": { + "Title": self.title, + "Description": self.description, + "Type": self.type, + "SubType": self.sub_type, + "Severity": self.severity, + "Source": { + "Type": self.source_type, + "NetworkType": self.source_network_type, + "URL": self.source_url, + "Date": self.source_date, + }, + "Images": images, }, - "Images": images } - }) + ) class IntSightAPI: def __init__(self, account_id: str, api_key: str, logger: Logger): self.account_id = account_id self.api_key = api_key - self.url = 'https://api.intsights.com' + self.url = "https://api.intsights.com" self.logger = logger def get_indicator_by_value(self, ioc_value: str) -> dict: - return self.make_json_request('GET', f'public/v2/iocs/ioc-by-value?iocValue={ioc_value}') + return self.make_json_request("GET", f"public/v2/iocs/ioc-by-value?iocValue={ioc_value}") def enrich_indicator(self, ioc_value: str) -> dict: while True: - response = self.make_json_request('GET', f'public/v1/iocs/enrich/{ioc_value}') - if response.get('Status', 'InProgress') in ['Done', 'Failed']: + response = self.make_json_request("GET", f"public/v1/iocs/enrich/{ioc_value}") + if response.get("Status", "InProgress") in ["Done", "Failed"]: break time.sleep(5) return response def rescan_indicator(self, indicator_file_hash: str) -> dict: - return self.make_json_request('POST', 'public/v1/iocs/rescan', json_data={ - "IocValue": indicator_file_hash - }) + return self.make_json_request("POST", "public/v1/iocs/rescan", json_data={"IocValue": indicator_file_hash}) def get_scan_status(self, task_id: str) -> dict: - return self.make_json_request('GET', f'public/v1/iocs/rescan/status/{task_id}') + return self.make_json_request("GET", f"public/v1/iocs/rescan/status/{task_id}") def get_complete_alert_by_id(self, alert_id: str) -> dict: - return self.make_json_request('GET', f'public/v1/data/alerts/get-complete-alert/{alert_id}') + return self.make_json_request("GET", f"public/v1/data/alerts/get-complete-alert/{alert_id}") def takedown_request(self, alert_id: str, target: str) -> dict: - return self.make_json_request('PATCH', f'public/v1/data/alerts/takedown-request/{alert_id}', json_data={ - "Target": target - }) + return self.make_json_request( + "PATCH", f"public/v1/data/alerts/takedown-request/{alert_id}", json_data={"Target": target} + ) def get_alerts(self, alert_params: AlertParams) -> list: - return self.make_request('GET', 'public/v1/data/alerts/alerts-list', params=alert_params.to_dict()).json() + return self.make_request("GET", "public/v1/data/alerts/alerts-list", params=alert_params.to_dict()).json() def add_manual_alert(self, manual_alert_params: ManualAlertParams) -> str: - return self.make_request('PUT', 'public/v1/data/alerts/add-alert', json_data=manual_alert_params.to_dict()).text + return self.make_request("PUT", "public/v1/data/alerts/add-alert", json_data=manual_alert_params.to_dict()).text def test_credentials(self) -> bool: - return self.make_request('HEAD', 'public/v1/test-credentials').status_code == 200 - - def make_json_request( - self, - method: str, - path: str, - json_data: dict = None, - params: dict = None - ) -> dict: + return self.make_request("HEAD", "public/v1/test-credentials").status_code == 200 + + def make_json_request(self, method: str, path: str, json_data: dict = None, params: dict = None) -> dict: try: - response = self.make_request( - method=method, - path=path, - json_data=json_data, - params=params - ) + response = self.make_request(method=method, path=path, json_data=json_data, params=params) if response.status_code == 204: return {} @@ -165,8 +150,7 @@ def make_json_request( if json_response.get("Status") == "Invalid": raise PluginException( - cause="There is an error in response.", - assistance=f"{json_response.get('FailedReason')}." + cause="There is an error in response.", assistance=f"{json_response.get('FailedReason')}." ) self.logger.info(f"response: {response.json()}") @@ -174,13 +158,7 @@ def make_json_request( except json.decoder.JSONDecodeError as e: raise PluginException(preset=PluginException.Preset.INVALID_JSON, data=e) - def make_request( - self, - method: str, - path: str, - json_data: dict = None, - params: dict = None - ) -> requests.Response: + def make_request(self, method: str, path: str, json_data: dict = None, params: dict = None) -> requests.Response: try: response = requests.request( method=method, diff --git a/plugins/intsights/unit_test/test_add_manual_alert.py b/plugins/intsights/unit_test/test_add_manual_alert.py index ca24dd5836..4513735d89 100644 --- a/plugins/intsights/unit_test/test_add_manual_alert.py +++ b/plugins/intsights/unit_test/test_add_manual_alert.py @@ -1,7 +1,7 @@ import sys import os -sys.path.append(os.path.abspath('../')) +sys.path.append(os.path.abspath("../")) from unittest import TestCase from unittest.mock import patch @@ -19,22 +19,22 @@ def setUpClass(cls, mock_request) -> None: @patch("requests.request", side_effect=Util.mock_request) def test_add_manual_alert_should_success(self, make_request): - actual = self.action.run({ - Input.TITLE: "Test Alert", - Input.DESCRIPTION: "Test description", - Input.TYPE: "Phishing", - Input.SUB_TYPE: "SuspiciousEmailAddress", - Input.SEVERITY: "High", - Input.SOURCE_TYPE: "Application Store", - Input.SOURCE_NETWORK_TYPE: "ClearWeb", - Input.SOURCE_URL: "http://www.rapid7.com", - Input.SOURCE_DATE: "2020-01-01T20:01:27.344Z", - Input.FOUND_DATE: "2020-01-01T20:01:27.344Z", - Input.IMAGES: [{"type": "gif", "data": "R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="}] - }) - expected = { - 'alert_id': '7cafac7ec5adaebf62257a4c' - } + actual = self.action.run( + { + Input.TITLE: "Test Alert", + Input.DESCRIPTION: "Test description", + Input.TYPE: "Phishing", + Input.SUB_TYPE: "SuspiciousEmailAddress", + Input.SEVERITY: "High", + Input.SOURCE_TYPE: "Application Store", + Input.SOURCE_NETWORK_TYPE: "ClearWeb", + Input.SOURCE_URL: "http://www.rapid7.com", + Input.SOURCE_DATE: "2020-01-01T20:01:27.344Z", + Input.FOUND_DATE: "2020-01-01T20:01:27.344Z", + Input.IMAGES: [{"type": "gif", "data": "R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="}], + } + ) + expected = {"alert_id": "7cafac7ec5adaebf62257a4c"} self.assertEqual(expected, actual) @patch("requests.request", side_effect=Util.mock_request) @@ -50,7 +50,7 @@ def test_add_manual_alert_should_fail_when_wrong_image(self, make_request): Input.SOURCE_URL: "http://www.example.com", Input.SOURCE_DATE: "2020-01-01T20:01:27.344Z", Input.FOUND_DATE: "2020-01-01T20:01:27.344Z", - Input.IMAGES: [{"type": "gif"}] + Input.IMAGES: [{"type": "gif"}], } with self.assertRaises(PluginException) as error: self.action.run(params) diff --git a/plugins/intsights/unit_test/test_connection.py b/plugins/intsights/unit_test/test_connection.py index 4da6ccb56a..6e60db251f 100644 --- a/plugins/intsights/unit_test/test_connection.py +++ b/plugins/intsights/unit_test/test_connection.py @@ -1,6 +1,7 @@ import sys import os -sys.path.append(os.path.abspath('../')) + +sys.path.append(os.path.abspath("../")) from unittest import TestCase from unittest.mock import patch @@ -14,14 +15,14 @@ class TestConnection(TestCase): @patch("requests.request", side_effect=Util.mock_request) def test_connection_should_success_when_good_credentials(self, mock_request) -> None: action = Util.default_connector(GetIndicatorByValue()) - self.assertEqual(action.connection.test(), {'success': True}) + self.assertEqual(action.connection.test(), {"success": True}) @patch("requests.request", side_effect=Util.mock_request) def test_connection_should_success_when_credentials(self, mock_request) -> None: - action = Util.default_connector(GetIndicatorByValue(), { - Input.API_KEY: {'secretKey': 'api_key'}, - Input.ACCOUNT_ID: {'secretKey': 'account_id'} - }) + action = Util.default_connector( + GetIndicatorByValue(), + {Input.API_KEY: {"secretKey": "api_key"}, Input.ACCOUNT_ID: {"secretKey": "account_id"}}, + ) self.assertEqual("https://api.intsights.com", action.connection.client.url) self.assertEqual("api_key", action.connection.client.api_key) @@ -29,10 +30,9 @@ def test_connection_should_success_when_credentials(self, mock_request) -> None: @patch("requests.request", side_effect=Util.mock_request) def test_connection_should_fail_when_wrong_credentials(self, mock_request) -> None: - action = Util.default_connector(GetIndicatorByValue(), { - Input.API_KEY: {'secretKey': 'wrong'}, - Input.ACCOUNT_ID: {'secretKey': 'wrong'} - }) + action = Util.default_connector( + GetIndicatorByValue(), {Input.API_KEY: {"secretKey": "wrong"}, Input.ACCOUNT_ID: {"secretKey": "wrong"}} + ) with self.assertRaises(ConnectionTestException) as error: action.connection.test() diff --git a/plugins/intsights/unit_test/test_enrich_indicator.py b/plugins/intsights/unit_test/test_enrich_indicator.py index 2c6fd3487d..78e74e7b74 100644 --- a/plugins/intsights/unit_test/test_enrich_indicator.py +++ b/plugins/intsights/unit_test/test_enrich_indicator.py @@ -2,7 +2,7 @@ import os import time -sys.path.append(os.path.abspath('../')) +sys.path.append(os.path.abspath("../")) from unittest import TestCase from unittest.mock import patch @@ -21,20 +21,16 @@ def setUpClass(cls, mock_request) -> None: @patch("requests.request", side_effect=Util.mock_request) def test_enrich_indicator_should_success(self, make_request): Util.request_count = 1 - actual = self.action.run({Input.INDICATOR_VALUE: 'rapid7.com'}) + actual = self.action.run({Input.INDICATOR_VALUE: "rapid7.com"}) Util.request_count = 0 - expected = { - 'data': {}, - 'original_value': 'rapid7.com', - 'status': 'Done' - } + expected = {"data": {}, "original_value": "rapid7.com", "status": "Done"} self.assertEqual(expected, actual) @patch("requests.request", side_effect=Util.mock_request) def test_enrich_indicator_should_success_when_in_progress(self, make_request): Util.request_count = 0 time_start = time.time() - self.action.run({Input.INDICATOR_VALUE: 'rapid7.com'}) + self.action.run({Input.INDICATOR_VALUE: "rapid7.com"}) expected = 1 expected_time_elapsed = time.time() - time_start self.assertEqual(expected, Util.request_count) diff --git a/plugins/intsights/unit_test/test_get_alerts.py b/plugins/intsights/unit_test/test_get_alerts.py index 4a5cc1933c..ff8fb7dfc0 100644 --- a/plugins/intsights/unit_test/test_get_alerts.py +++ b/plugins/intsights/unit_test/test_get_alerts.py @@ -1,7 +1,7 @@ import sys import os -sys.path.append(os.path.abspath('../')) +sys.path.append(os.path.abspath("../")) from unittest import TestCase from unittest.mock import patch @@ -20,34 +20,30 @@ def setUpClass(cls, mock_request) -> None: def test_get_alerts_success_with_empty_params(self, make_request): actual = self.action.run({}) expected = { - 'alert_ids': [ - '7cafac7ec5adaebf62257a4c', - '7cafac7ec5adaebf62257a4d', - '7cafac7ec5adaebf62257a4e', - '7cafac7ec5adaebf62257a4f' + "alert_ids": [ + "7cafac7ec5adaebf62257a4c", + "7cafac7ec5adaebf62257a4d", + "7cafac7ec5adaebf62257a4e", + "7cafac7ec5adaebf62257a4f", ] } self.assertEqual(expected, actual) @patch("requests.request", side_effect=Util.mock_request) def test_get_alerts_success_with_params(self, make_request): - actual = self.action.run({ - Input.SEVERITY: "High" - }) + actual = self.action.run({Input.SEVERITY: "High"}) expected = { - 'alert_ids': [ - '7cafac7ec5adaebf62257a4c', - '7cafac7ec5adaebf62257a4d', - '7cafac7ec5adaebf62257a4e', - '7cafac7ec5adaebf62257a4f' + "alert_ids": [ + "7cafac7ec5adaebf62257a4c", + "7cafac7ec5adaebf62257a4d", + "7cafac7ec5adaebf62257a4e", + "7cafac7ec5adaebf62257a4f", ] } self.assertEqual(expected, actual) @patch("requests.request", side_effect=Util.mock_request) def test_get_alerts_success_with_empty_response_list(self, make_request): - actual = self.action.run({ - Input.ALERT_TYPE: "Phishing" - }) - expected = {'alert_ids': []} + actual = self.action.run({Input.ALERT_TYPE: "Phishing"}) + expected = {"alert_ids": []} self.assertEqual(expected, actual) diff --git a/plugins/intsights/unit_test/test_get_complete_alert_by_id.py b/plugins/intsights/unit_test/test_get_complete_alert_by_id.py index 206f160ccb..39348e555c 100644 --- a/plugins/intsights/unit_test/test_get_complete_alert_by_id.py +++ b/plugins/intsights/unit_test/test_get_complete_alert_by_id.py @@ -1,7 +1,7 @@ import sys import os -sys.path.append(os.path.abspath('../')) +sys.path.append(os.path.abspath("../")) from unittest import TestCase from unittest.mock import patch @@ -18,31 +18,25 @@ def setUpClass(cls, mock_request) -> None: @patch("requests.request", side_effect=Util.mock_request) def test_get_complete_alert_by_id_should_success(self, make_request): - actual = self.action.run({ - Input.ALERT_ID: "123" - }) + actual = self.action.run({Input.ALERT_ID: "123"}) expected = { - 'assets': [], - 'assignees': [], - 'details': { - 'Description': 'APIDescription', - 'Images': [], - 'Severity': 'High', - 'Source': { - 'NetworkType': 'ClearWeb', - 'Type': 'Application Store', - 'URL': 'http://www.rapid7.com' - }, - 'SubType': 'SuspiciousEmailAddress', - 'Tags': [], - 'Title': 'Alerttest3', - 'Type': 'Phishing' + "assets": [], + "assignees": [], + "details": { + "Description": "APIDescription", + "Images": [], + "Severity": "High", + "Source": {"NetworkType": "ClearWeb", "Type": "Application Store", "URL": "http://www.rapid7.com"}, + "SubType": "SuspiciousEmailAddress", + "Tags": [], + "Title": "Alerttest3", + "Type": "Phishing", }, - 'found_date': '2021-09-30T19:35:42.441Z', - 'id': '7cafac7ec5adaebf62257a4c', - 'is_closed': False, - 'is_flagged': False, - 'takedown_status': 'NotSent', - 'update_date': '2021-09-30T19:35:42.441Z' + "found_date": "2021-09-30T19:35:42.441Z", + "id": "7cafac7ec5adaebf62257a4c", + "is_closed": False, + "is_flagged": False, + "takedown_status": "NotSent", + "update_date": "2021-09-30T19:35:42.441Z", } self.assertEqual(expected, actual) diff --git a/plugins/intsights/unit_test/test_get_indicator_by_value.py b/plugins/intsights/unit_test/test_get_indicator_by_value.py index a849a88533..85205f0550 100644 --- a/plugins/intsights/unit_test/test_get_indicator_by_value.py +++ b/plugins/intsights/unit_test/test_get_indicator_by_value.py @@ -1,7 +1,7 @@ import sys import os -sys.path.append(os.path.abspath('../')) +sys.path.append(os.path.abspath("../")) from unittest import TestCase from unittest.mock import patch @@ -18,37 +18,37 @@ def setUpClass(cls, mock_request) -> None: @patch("requests.request", side_effect=Util.mock_request) def test_get_indicator_by_value_should_success(self, make_request): - actual = self.action.run({Input.INDICATOR_VALUE: 'rapid7.com'}) + actual = self.action.run({Input.INDICATOR_VALUE: "rapid7.com"}) expected = { - 'first_seen': '2020-01-01T20:01:27.344Z', - 'geo_location': 'US', - 'last_seen': '2020-01-30T16:18:51.148Z', - 'last_update': '2020-02-21T23:00:51.268Z', - 'related_campaigns': ['SolarWinds'], - 'related_malware': ['doppeldridex', 'dridex'], - 'related_threat_actors': ['doppelspider'], - 'score': 100, - 'severity': 'High', - 'sources': [{'ConfidenceLevel': 3, 'Name': 'AlienVault OTX'}], - 'system_tags': ['Phishing'], - 'tags': ['MyTag_1'], - 'type': 'Domains', - 'value': 'rapid7.com', - 'whitelist': 'false' + "first_seen": "2020-01-01T20:01:27.344Z", + "geo_location": "US", + "last_seen": "2020-01-30T16:18:51.148Z", + "last_update": "2020-02-21T23:00:51.268Z", + "related_campaigns": ["SolarWinds"], + "related_malware": ["doppeldridex", "dridex"], + "related_threat_actors": ["doppelspider"], + "score": 100, + "severity": "High", + "sources": [{"ConfidenceLevel": 3, "Name": "AlienVault OTX"}], + "system_tags": ["Phishing"], + "tags": ["MyTag_1"], + "type": "Domains", + "value": "rapid7.com", + "whitelist": "false", } self.assertEqual(expected, actual) @patch("requests.request", side_effect=Util.mock_request) def test_get_indicator_by_value_should_success_when_empty(self, make_request): - actual = self.action.run({Input.INDICATOR_VALUE: 'empty'}) + actual = self.action.run({Input.INDICATOR_VALUE: "empty"}) expected = { - 'related_campaigns': [], - 'related_malware': [], - 'related_threat_actors': [], - 'score': 0, - 'sources': [], - 'system_tags': [], - 'tags': [], - 'whitelist': False + "related_campaigns": [], + "related_malware": [], + "related_threat_actors": [], + "score": 0, + "sources": [], + "system_tags": [], + "tags": [], + "whitelist": False, } self.assertEqual(expected, actual) diff --git a/plugins/intsights/unit_test/test_get_indicator_scan_status.py b/plugins/intsights/unit_test/test_get_indicator_scan_status.py index 938d952f78..f97330aeb0 100644 --- a/plugins/intsights/unit_test/test_get_indicator_scan_status.py +++ b/plugins/intsights/unit_test/test_get_indicator_scan_status.py @@ -1,7 +1,7 @@ import sys import os -sys.path.append(os.path.abspath('../')) +sys.path.append(os.path.abspath("../")) from unittest import TestCase from unittest.mock import patch @@ -19,21 +19,14 @@ def setUpClass(cls, mock_request) -> None: @patch("requests.request", side_effect=Util.mock_request) def test_rescan_indicator_should_success(self, make_request): - actual = self.action.run({ - Input.TASK_ID: "abcdefg123456" - }) - expected = { - 'status': 'InProgress', - 'task_id': 'abcdefg123456' - } + actual = self.action.run({Input.TASK_ID: "abcdefg123456"}) + expected = {"status": "InProgress", "task_id": "abcdefg123456"} self.assertEqual(expected, actual) @patch("requests.request", side_effect=Util.mock_request) def test_rescan_indicator_should_failed(self, make_request): with self.assertRaises(PluginException) as error: - self.action.run({ - Input.TASK_ID: "bad" - }) + self.action.run({Input.TASK_ID: "bad"}) self.assertEqual("There is an error in response.", error.exception.cause) self.assertEqual("Invalid task id.", error.exception.assistance) diff --git a/plugins/intsights/unit_test/test_rescan_indicator.py b/plugins/intsights/unit_test/test_rescan_indicator.py index aab3a8746a..2036d89f2a 100644 --- a/plugins/intsights/unit_test/test_rescan_indicator.py +++ b/plugins/intsights/unit_test/test_rescan_indicator.py @@ -1,7 +1,7 @@ import sys import os -sys.path.append(os.path.abspath('../')) +sys.path.append(os.path.abspath("../")) from unittest import TestCase from unittest.mock import patch @@ -19,21 +19,14 @@ def setUpClass(cls, mock_request) -> None: @patch("requests.request", side_effect=Util.mock_request) def test_rescan_indicator_should_success(self, make_request): - actual = self.action.run({ - Input.INDICATOR_FILE_HASH: "000003a16a5a1c6ccddbe548e852614224891111" - }) - expected = { - 'status': 'Queued', - 'task_id': 'abcdefg123456' - } + actual = self.action.run({Input.INDICATOR_FILE_HASH: "000003a16a5a1c6ccddbe548e852614224891111"}) + expected = {"status": "Queued", "task_id": "abcdefg123456"} self.assertEqual(expected, actual) @patch("requests.request", side_effect=Util.mock_request) def test_rescan_indicator_should_failed(self, make_request): with self.assertRaises(PluginException) as error: - self.action.run({ - Input.INDICATOR_FILE_HASH: "bad" - }) + self.action.run({Input.INDICATOR_FILE_HASH: "bad"}) self.assertEqual("There is an error in response.", error.exception.cause) self.assertEqual("Invalid IOC value. Supported IOC types: file hashes.", error.exception.assistance) diff --git a/plugins/intsights/unit_test/util.py b/plugins/intsights/unit_test/util.py index 657f21f555..90c922f641 100644 --- a/plugins/intsights/unit_test/util.py +++ b/plugins/intsights/unit_test/util.py @@ -15,10 +15,7 @@ def default_connector(action, connect_params: object = None): if connect_params: params = connect_params else: - params = { - Input.ACCOUNT_ID: {'secretKey': 'account_id'}, - Input.API_KEY: {'secretKey': 'api_key'} - } + params = {Input.ACCOUNT_ID: {"secretKey": "account_id"}, Input.API_KEY: {"secretKey": "api_key"}} default_connection.connect(params) action.connection = default_connection action.logger = logging.getLogger("action logger") @@ -35,45 +32,53 @@ class MockResponse: def __init__(self, status_code: int, filename: str = None): self.status_code = status_code if filename: - self.text = Util.read_file_to_string(f'payloads/{filename}.json.resp') + self.text = Util.read_file_to_string(f"payloads/{filename}.json.resp") else: - self.text = '' + self.text = "" def json(self): return json.loads(self.text) - if kwargs.get('url') == 'https://api.intsights.com/public/v1/test-credentials' \ - and kwargs.get('auth').username == 'wrong': + if ( + kwargs.get("url") == "https://api.intsights.com/public/v1/test-credentials" + and kwargs.get("auth").username == "wrong" + ): return MockResponse(401) - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/test-credentials': + elif kwargs.get("url") == "https://api.intsights.com/public/v1/test-credentials": return MockResponse(200) - elif kwargs.get('url') == 'https://api.intsights.com/public/v2/iocs/ioc-by-value?iocValue=rapid7.com': - return MockResponse(200, 'iocs_ioc-by-value') - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/enrich/rapid7.com' \ - and Util.request_count == 0: + elif kwargs.get("url") == "https://api.intsights.com/public/v2/iocs/ioc-by-value?iocValue=rapid7.com": + return MockResponse(200, "iocs_ioc-by-value") + elif ( + kwargs.get("url") == "https://api.intsights.com/public/v1/iocs/enrich/rapid7.com" + and Util.request_count == 0 + ): Util.request_count = Util.request_count + 1 - return MockResponse(200, 'enrich_indicator-in_progress') - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/enrich/rapid7.com': - return MockResponse(200, 'enrich_indicator') - elif kwargs.get('url') == 'https://api.intsights.com/public/v2/iocs/ioc-by-value?iocValue=empty': + return MockResponse(200, "enrich_indicator-in_progress") + elif kwargs.get("url") == "https://api.intsights.com/public/v1/iocs/enrich/rapid7.com": + return MockResponse(200, "enrich_indicator") + elif kwargs.get("url") == "https://api.intsights.com/public/v2/iocs/ioc-by-value?iocValue=empty": return MockResponse(204) - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/data/alerts/add-alert': - return MockResponse(200, 'add_manual_alert') - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/data/alerts/alerts-list'\ - and kwargs.get('params', {}).get('alertType') == 'Phishing': - return MockResponse(200, 'get_alerts_empty_list') - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/data/alerts/alerts-list': - return MockResponse(200, 'get_alerts') - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/data/alerts/get-complete-alert/123': - return MockResponse(200, 'get_complete_alert_by_id') - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/rescan'\ - and kwargs.get('json', {}).get('IocValue') == 'bad': - return MockResponse(200, 'rescan_indicator.bad') - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/rescan/status/abcdefg123456': - return MockResponse(200, 'get_indicator_scan_status') - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/rescan/status/bad': - return MockResponse(200, 'get_indicator_scan_status.bad') - elif kwargs.get('url') == 'https://api.intsights.com/public/v1/iocs/rescan': - return MockResponse(200, 'rescan_indicator') + elif kwargs.get("url") == "https://api.intsights.com/public/v1/data/alerts/add-alert": + return MockResponse(200, "add_manual_alert") + elif ( + kwargs.get("url") == "https://api.intsights.com/public/v1/data/alerts/alerts-list" + and kwargs.get("params", {}).get("alertType") == "Phishing" + ): + return MockResponse(200, "get_alerts_empty_list") + elif kwargs.get("url") == "https://api.intsights.com/public/v1/data/alerts/alerts-list": + return MockResponse(200, "get_alerts") + elif kwargs.get("url") == "https://api.intsights.com/public/v1/data/alerts/get-complete-alert/123": + return MockResponse(200, "get_complete_alert_by_id") + elif ( + kwargs.get("url") == "https://api.intsights.com/public/v1/iocs/rescan" + and kwargs.get("json", {}).get("IocValue") == "bad" + ): + return MockResponse(200, "rescan_indicator.bad") + elif kwargs.get("url") == "https://api.intsights.com/public/v1/iocs/rescan/status/abcdefg123456": + return MockResponse(200, "get_indicator_scan_status") + elif kwargs.get("url") == "https://api.intsights.com/public/v1/iocs/rescan/status/bad": + return MockResponse(200, "get_indicator_scan_status.bad") + elif kwargs.get("url") == "https://api.intsights.com/public/v1/iocs/rescan": + return MockResponse(200, "rescan_indicator") else: - raise NotImplementedError('Not implemented', kwargs) + raise NotImplementedError("Not implemented", kwargs) diff --git a/plugins/microsoft_atp/.CHECKSUM b/plugins/microsoft_atp/.CHECKSUM index f898684e59..42ed99bb8b 100644 --- a/plugins/microsoft_atp/.CHECKSUM +++ b/plugins/microsoft_atp/.CHECKSUM @@ -1,5 +1,5 @@ { - "spec": "02ab4b32669fc75b47f89f41108efc88", + "spec": "973667a57579262af1678d0236ae8c9a", "manifest": "d046d7ea8bb7e5e0d7555d28f5588dda", "setup": "273e654e5089823d8aa45a3acd2c1306", "schemas": [ diff --git a/plugins/microsoft_atp/help.md b/plugins/microsoft_atp/help.md index a019a268d3..9c4da5b956 100644 --- a/plugins/microsoft_atp/help.md +++ b/plugins/microsoft_atp/help.md @@ -15,14 +15,15 @@ This plugin utilizes the [Microsoft ATP API](https://docs.microsoft.com/en-us/wi * Windows Defender Advanced Threat Protection application credentials -# Supported Product Versions - -_There are no supported product versions listed._ - # Documentation ## Setup +This plugin uses the Windows Defender ATP API. It will use an Azure application to connect to the API and run actions from InsightConnect. + +For information on how to setup your application and assign permissions go here: +https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/exposed-apis-create-app-webapp + The connection configuration accepts the following parameters: |Name|Type|Default|Required|Description|Enum|Example| @@ -54,7 +55,7 @@ This action collects investigation package from a machine. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| |comment|string|Investigation package collected via InsightConnect|False|Comment to associate with the action|None|Investigation package collected via InsightConnect| -|machine|string|None|True|Machine IP address, hostname, or machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| +|machine|string|None|True|Machine IP address, hostname, or machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| Example input: @@ -101,7 +102,7 @@ This action is used to get machines related to an file hash(SHA1), domain or use |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator|string|None|True|File hash(SHA1), domain or username indicator|None|https://example.com| +|indicator|string|None|True|File hash(SHA1), domain or username indicator|None|example.com| Example input: @@ -157,7 +158,7 @@ This action is used to add or remove machine tags. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|machine|string|None|True|Machine IP address, hostname, or machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| +|machine|string|None|True|Machine IP address, hostname, or machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| |tag|string|None|True|The tag value|None|example tag| |type|boolean|True|True|True to add tag, false to remove it|None|True| @@ -213,7 +214,7 @@ This action retrieves a collection of installed software related to a given mach |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|machine|string|None|True|Machine IP address, hostname, or machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| +|machine|string|None|True|Machine IP address, hostname, or machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| Example input: @@ -266,7 +267,7 @@ This action is used to retrieve a list of software updates. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|machine|string|None|True|Machine IP address, hostname or machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| +|machine|string|None|True|Machine IP address, hostname or machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| Example input: @@ -311,7 +312,7 @@ This action is used to retrieve a list of security recommendations. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|machine|string|None|True|Machine IP address, hostname or machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| +|machine|string|None|True|Machine IP address, hostname or machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| Example input: @@ -368,7 +369,7 @@ This action is used to submit or update new indicator. |application|string|None|False|The application associated with the indicator|None|demo-test| |description|string|Indicator Blacklisted from InsightConnect|False|Description of the indicator|None|Indicator Blacklisted from InsightConnect| |expiration_time|string|None|False|The expiration time of the indicator, default value is one year from now|None|2020-12-12T00:00:00Z| -|indicator|string|None|True|A supported indicator to blacklist or unblacklist. Supported indicators are IP addresses, URLs, domains, and SHA1 and SHA256 hashes|None|02699626f388ed830012e5b787640e71c56d42d8| +|indicator|string|None|True|A supported indicator to blacklist or unblacklist. Supported indicators are IP addresses, URLs, domains, and SHA1 and SHA256 hashes|None|220e7d15b011d7fac48f2bd61114db1022197f7f| |indicator_state|boolean|False|False|True to add indicator, false to remove it from the list|None|True| |rbac_group_names|[]string|None|False|List of RBAC group names the indicator would be applied to|None|["group1","group2"]| |recommended_actions|string|None|False|TI indicator alert recommended actions|None|nothing| @@ -385,7 +386,10 @@ Example input: "expiration_time": "2020-12-12T00:00:00Z", "indicator": "220e7d15b011d7fac48f2bd61114db1022197f7f", "indicator_state": true, - "rbac_group_names": "[\"group1\",\"group2\"]", + "rbac_group_names": [ + "group1", + "group2" + ], "recommended_actions": "nothing", "severity": "High", "title": "test" @@ -440,7 +444,7 @@ This action retrieves a collection of discovered vulnerabilities related to a gi |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|machine|string|None|True|Machine IP address, hostname or machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| +|machine|string|None|True|Machine IP address, hostname or machine ID|None|9de5069c5afe602b2ea0a04b66beb2c0cef77fdf| Example input: @@ -528,7 +532,7 @@ This action is used to get details about a machine from its ID. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|machine|string|None|True|Machine IP address, hostname and machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| +|machine|string|None|True|Machine IP address, hostname and machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| Example input: @@ -627,7 +631,7 @@ This action is used to isolate a machine from the network, but keep the connecti |----|----|-------|--------|-----------|----|-------| |comment|string|None|True|Comment to associate with the isolation action|None|Isolated by InsightConnect| |isolation_type|string|None|True|Type of isolation to perform on target machine|['Full', 'Selective']|Full| -|machine|string|None|True|Machine IP address, hostname and machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| +|machine|string|None|True|Machine IP address, hostname and machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| Example input: @@ -671,7 +675,7 @@ This action is used to restore network connectivity to a machine. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| |comment|string|None|True|Comment to associate with the unisolate action|None|Unisolated by InsightConnect| -|machine|string|None|True|Machine IP address, hostname and machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| +|machine|string|None|True|Machine IP address, hostname and machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| Example input: @@ -714,8 +718,8 @@ This action is used to stop the execution of a file on a machine and delete it. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| |comment|string|None|True|Comment to associate with the stop and quarantine action|None|InsightConnect has stopped a file.| -|machine|string|None|True|Machine IP address, hostname and machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| -|sha1|string|None|True|SHA1 hash of the file to stop and quarantine on the machine|None|02699626f388ed830012e5b787640e71c56d42d8| +|machine|string|None|True|Machine IP address, hostname and machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| +|sha1|string|None|True|SHA1 hash of the file to stop and quarantine on the machine|None|ad0c0f2fa80411788e81a4567d1d8758b83cd76e| Example input: @@ -762,7 +766,7 @@ This action is used to initiate a Windows Defender antivirus scan on a machine. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| |comment|string|None|True|Comment to associate with the antivirus scan action|None|InsightConnect has started an antivirus scan.| -|machine|string|None|True|Machine IP address, hostname and machine ID|None|02699626f388ed830012e5b787640e71c56d42d8| +|machine|string|None|True|Machine IP address, hostname and machine ID|None|2df36d707c1ee5084cef77f3dbfc95db65bc4a73| |scan_type|string|None|True|The type of antivirus scan to run|['Full', 'Quick']|Full| Example input: @@ -854,7 +858,7 @@ looking for a match. |----|----|-------|--------|-----------|----|-------| |frequency|integer|10|False|Poll frequency in seconds|None|10| |key|string|None|True|The key to look for in the alert. This key must match the case shown in the example output section in help|None|assignedTo| -|value|string|None|True|The value to look for in the alert. The value must match the case of the value returned|None|https://example.com| +|value|string|None|True|The value to look for in the alert. The value must match the case of the value returned|None|user@example.com| Example input: From 658d42137b527f35646126459b77c18c62e00a6b Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:40:23 +0200 Subject: [PATCH 07/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 89c06986b1..2a3f90cd35 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -3,7 +3,7 @@ extension: plugin products: [insightconnect] name: intsights title: IntSights -description: IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy +description: Rapid7 IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy version: 1.0.0 supported_versions: ["2.4.0"] vendor: rapid7 From 7b79c3d3496e8c7697b17841933a6ffa7b688669 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:40:58 +0200 Subject: [PATCH 08/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 2a3f90cd35..43d1d7828c 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -96,7 +96,7 @@ actions: required: true first_seen: title: First Seen - description: First Seen + description: First seen type: string required: false last_seen: From a280af030511bb5d0ec143cec13c1a1922d821df Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:41:11 +0200 Subject: [PATCH 09/60] Update plugins/intsights/icon_intsights/actions/takedown_request/action.py Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- .../intsights/icon_intsights/actions/takedown_request/action.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/icon_intsights/actions/takedown_request/action.py b/plugins/intsights/icon_intsights/actions/takedown_request/action.py index c74866a544..1040077bf7 100755 --- a/plugins/intsights/icon_intsights/actions/takedown_request/action.py +++ b/plugins/intsights/icon_intsights/actions/takedown_request/action.py @@ -16,4 +16,4 @@ def __init__(self): def run(self, params={}): self.connection.client.takedown_request(params.get(Input.ALERT_ID), params.get(Input.TARGET)) - return clean({Output.STATUS: True}) + return {Output.STATUS: True} From 0d130dd00178a05779d7c46e61a7a73e2638a211 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:41:37 +0200 Subject: [PATCH 10/60] Update plugins/intsights/icon_intsights/connection/connection.py Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/icon_intsights/connection/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/icon_intsights/connection/connection.py b/plugins/intsights/icon_intsights/connection/connection.py index f78d5b5a8d..09deb1303a 100755 --- a/plugins/intsights/icon_intsights/connection/connection.py +++ b/plugins/intsights/icon_intsights/connection/connection.py @@ -1,8 +1,8 @@ import insightconnect_plugin_runtime -from typing import Optional from .schema import ConnectionSchema, Input # Custom imports below +from typing import Optional from icon_intsights.util.api import IntSightAPI from insightconnect_plugin_runtime.exceptions import PluginException, ConnectionTestException From 35048b60068f87826db92de9e359ee92ef2d65a9 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:41:52 +0200 Subject: [PATCH 11/60] Update plugins/intsights/icon_intsights/util/api.py Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/icon_intsights/util/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/icon_intsights/util/api.py b/plugins/intsights/icon_intsights/util/api.py index c1d825f5da..e15afd837e 100644 --- a/plugins/intsights/icon_intsights/util/api.py +++ b/plugins/intsights/icon_intsights/util/api.py @@ -150,7 +150,7 @@ def make_json_request(self, method: str, path: str, json_data: dict = None, para if json_response.get("Status") == "Invalid": raise PluginException( - cause="There is an error in response.", assistance=f"{json_response.get('FailedReason')}." + cause="IntSights returned an error response: ", assistance=f"{json_response.get('FailedReason')}." ) self.logger.info(f"response: {response.json()}") From 0bc83b5b38aa50045a07711ff96a863f3230492d Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:50:02 +0200 Subject: [PATCH 12/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 43d1d7828c..78a202dad5 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -101,7 +101,7 @@ actions: required: false last_seen: title: Last Seen - description: Last Seen + description: Last seen type: string required: false last_update: From 15459fd48697f12e53968dc39f71dce2dbf71efd Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:50:15 +0200 Subject: [PATCH 13/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 78a202dad5..c4df89bd3f 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -106,7 +106,7 @@ actions: required: false last_update: title: Last Update - description: Last Update + description: Last update type: string required: false geo_location: From 848ad4f4c77881c3702cfb469f14d5876734aacc Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:50:31 +0200 Subject: [PATCH 14/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index c4df89bd3f..0cb9b9600b 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -111,7 +111,7 @@ actions: required: false geo_location: title: GEO Location - description: GEO Location + description: Geographic location type: string required: false sources: From ec213848a1ce2061a98258d15d7942a97c65fdf0 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:50:44 +0200 Subject: [PATCH 15/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 0cb9b9600b..434d8e856e 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -110,7 +110,7 @@ actions: type: string required: false geo_location: - title: GEO Location + title: Geographic Location description: Geographic location type: string required: false From d301da0eb97cee9a2a9bd5a4bd9d00517e4f38b3 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:51:10 +0200 Subject: [PATCH 16/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 434d8e856e..ae46819279 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -126,7 +126,7 @@ actions: required: true system_tags: title: System Tags - description: System Tags + description: System tags type: '[]string' required: true related_malware: From a7f551827da03be899000b4648aed53a1ade5b37 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:51:42 +0200 Subject: [PATCH 17/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index ae46819279..2652e1b4eb 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -131,7 +131,7 @@ actions: required: true related_malware: title: Related Malware - description: Related Malware + description: Related malware type: '[]string' required: true related_campaigns: From 1180a25e2b4d17beedb31d302426d09dd2a5a431 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:52:15 +0200 Subject: [PATCH 18/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 2652e1b4eb..2789d6e33d 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -136,7 +136,7 @@ actions: required: true related_campaigns: title: Related Campaigns - description: Related Campaigns + description: Related campaigns type: '[]string' required: true related_threat_actors: From 1104392a0d29efe4a6fb0db7f01cf36669cd89a7 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:52:33 +0200 Subject: [PATCH 19/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 2789d6e33d..17f8f2ffd4 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -141,7 +141,7 @@ actions: required: true related_threat_actors: title: Related Threat Actors - description: Related Threat Actors + description: Related threat actors type: '[]string' required: true enrich_indicator: From 57e61c9d8d295c4a7e70f9a3b69c3ffccf8b1bb0 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:52:52 +0200 Subject: [PATCH 20/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 17f8f2ffd4..2a7f942c75 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -172,7 +172,7 @@ actions: required: true rescan_indicator: title: Rescan Indicator - description: Force an indicator scan in Intsights TIP system + description: Force an indicator scan in IntSights TIP system input: indicator_file_hash: title: Indicator File Hash From 74dbc2cb043ac69e671fe2044734b57a0887a41f Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:53:21 +0200 Subject: [PATCH 21/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 2a7f942c75..0dca48a820 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -193,7 +193,7 @@ actions: required: true get_indicator_scan_status: title: Get Indicator Scan Status - description: Get the scan status of an indicator in Insights TIP system + description: Get the scan status of an indicator in the IntSights TIP system input: task_id: title: Task ID From d52bdb0f9e69ae661eaab6edc297945cbaf98bb1 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:53:41 +0200 Subject: [PATCH 22/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 0dca48a820..5f3bde2739 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -214,7 +214,7 @@ actions: required: true get_alerts: title: Get Alerts - description: Search Alerts based on criteria + description: Search alerts based on criteria input: alert_type: title: Alert Type From 884ee1cf62971348a8a8ca142f4158413ffac67c Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:53:57 +0200 Subject: [PATCH 23/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 5f3bde2739..f209fc04ae 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -218,7 +218,7 @@ actions: input: alert_type: title: Alert Type - description: Comma separated list of alert types. Allowed values - AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip + description: Comma-separated list of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip type: string required: false enum: From 93e184cd89d318142a4d91e6eacc684b822a03f1 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:54:28 +0200 Subject: [PATCH 24/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index f209fc04ae..a40f37cc9f 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -231,7 +231,7 @@ actions: example: Phishing severity: title: Severity - description: Comma separated list of alerts severity. Allowed values - High, Medium, Low + description: Comma-separated list of alerts severity. Allowed values: High, Medium, Low type: string required: false enum: From c441d46b6ef4b8fcb8bf6d725f1276bc4af1abbd Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:54:56 +0200 Subject: [PATCH 25/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index a40f37cc9f..2325d90cb6 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -241,7 +241,7 @@ actions: example: Low source_type: title: Source Type - description: Comma separated list of alerts source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others + description: Comma-separated list of alerts source type. Allowed values: ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others type: string required: false enum: From fb591ac4eea20c5ea6df5d331c5b554d054309d2 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:55:23 +0200 Subject: [PATCH 26/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 2325d90cb6..09e1f6a5c5 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -282,7 +282,7 @@ actions: example: Application Store network_type: title: Network Type - description: Comma separated list of network type. Allowed values - ClearWeb, DarkWeb + description: Comma-separated list of network type. Allowed values: ClearWeb, DarkWeb type: string required: false enum: From 23b18989710ae9c54524a7dcbca9e2dd69ccbf94 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:55:51 +0200 Subject: [PATCH 27/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 09e1f6a5c5..10368b06a5 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -291,7 +291,7 @@ actions: example: DarkWeb matched_asset_value: title: Matched Asset Value - description: Comma separated list + description: Comma-separated list type: string required: false example: example.com From 52be92375e3a3d247c088f0d7e99f39095d484bf Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:56:13 +0200 Subject: [PATCH 28/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 10368b06a5..aa2b3b43c1 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -297,7 +297,7 @@ actions: example: example.com remediation_status: title: Remediation Status - description: Comma separated list of remediation status. Allowed values - InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed + description: Comma-separated list of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed type: string required: false example: InProggres, Pending From d91763993c37092fd407764f36ee482f188b1e89 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:56:39 +0200 Subject: [PATCH 29/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index aa2b3b43c1..5c559f818b 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -300,7 +300,7 @@ actions: description: Comma-separated list of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed type: string required: false - example: InProggres, Pending + example: InProgress, Pending source_date_from: title: Source Date From description: Start date to fetch from in Unix Millisecond Timestamp From fbb497715d4440744f3dd05faa8dac02926dda4a Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:57:10 +0200 Subject: [PATCH 30/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 5c559f818b..d750b126f6 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -327,7 +327,7 @@ actions: example: 1633047102456 assigned: title: Assigned - description: Show assigned/unAssigned alerts + description: Show assigned/unassigned alerts type: boolean required: false example: true From 47462d355693286dd9ab1afe3c2c04d75279e3e4 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:57:49 +0200 Subject: [PATCH 31/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index d750b126f6..5bcea0ce04 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -326,7 +326,7 @@ actions: required: false example: 1633047102456 assigned: - title: Assigned + title: Alert Assignment description: Show assigned/unassigned alerts type: boolean required: false From bfa254a6faf37b9ece0c8c41057f4a8ed8b7552f Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:58:26 +0200 Subject: [PATCH 32/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 5bcea0ce04..027b5dc5e8 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -332,7 +332,7 @@ actions: required: false example: true is_flagged: - title: Is Flagged + title: Alert Flag Status description: Show flagged/unflagged alerts type: boolean required: false From 72ca31e3d7ee4e662257128ee03ad931d3458ea7 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:59:10 +0200 Subject: [PATCH 33/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 027b5dc5e8..48b1af60ad 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -338,7 +338,7 @@ actions: required: false example: true is_closed: - title: Is Closed + title: Closed Status description: Is closed/open alerts type: boolean required: false From f80095bcba336ba28735495ea1764167773a6505 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:59:43 +0200 Subject: [PATCH 34/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 48b1af60ad..c3ad083555 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -383,7 +383,7 @@ actions: required: true details: title: Details - description: Alert Details + description: Alert details type: object required: true found_date: From baf884a5cb3a98f07d60f81a90fad65c012c1c23 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 21:00:33 +0200 Subject: [PATCH 35/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index c3ad083555..bd0cd2427f 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -418,7 +418,7 @@ actions: required: false takedown_request: title: Takedown Request - description: Request a takedown for a given alert in Intsights + description: Request a takedown for a given alert in IntSights input: alert_id: title: Alert ID From 1421402d7ae609e36d4cd38833eb90e5ffe5d2c7 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Mon, 25 Oct 2021 21:01:54 +0200 Subject: [PATCH 36/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index bd0cd2427f..a108d0a5bc 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -541,7 +541,7 @@ actions: description: Source URL type: string required: true - example: https://example.com" + example: https://example.com found_date: title: Found Date description: Alert found date From 7b6aebd9e07b58eb4aea70b88e41eba2174c7888 Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Mon, 25 Oct 2021 23:23:40 +0200 Subject: [PATCH 37/60] [MC-683] Fix help --- plugins/intsights/.CHECKSUM | 18 +++---- plugins/intsights/bin/icon_intsights | 2 +- plugins/intsights/help.md | 53 +++++++++---------- .../actions/get_alerts/schema.py | 22 ++++---- .../get_complete_alert_by_id/schema.py | 2 +- .../actions/get_indicator_by_value/schema.py | 18 +++---- .../get_indicator_scan_status/schema.py | 2 +- .../actions/rescan_indicator/schema.py | 2 +- .../actions/takedown_request/schema.py | 2 +- .../icon_intsights/connection/connection.py | 6 +-- plugins/intsights/icon_intsights/util/api.py | 2 +- plugins/intsights/plugin.spec.yaml | 10 ++-- plugins/intsights/setup.py | 2 +- 13 files changed, 68 insertions(+), 73 deletions(-) diff --git a/plugins/intsights/.CHECKSUM b/plugins/intsights/.CHECKSUM index 4dc96c656e..ccf91bd7bf 100644 --- a/plugins/intsights/.CHECKSUM +++ b/plugins/intsights/.CHECKSUM @@ -1,7 +1,7 @@ { - "spec": "35d879856781246448ca75279a085f79", - "manifest": "c7a13778c7e5ccc8cf2e73ccc060ff04", - "setup": "ea830b2af5f13706b38c5e288f0b6944", + "spec": "666b3a1ce78eb048de5e49ee1c26ce45", + "manifest": "9ee7bbc03de21a7f9edefdef3218148a", + "setup": "418f9067c4ef247786d7bacadcb3dceb", "schemas": [ { "identifier": "add_manual_alert/schema.py", @@ -13,27 +13,27 @@ }, { "identifier": "get_alerts/schema.py", - "hash": "fcdda7f063170df1273ce18cd6206fa8" + "hash": "8fb0ed7bda2a9abc7a070b022d5acd37" }, { "identifier": "get_complete_alert_by_id/schema.py", - "hash": "fa71f1afe4b7a259160df71668a64e32" + "hash": "b5f55ac2937665123aeb3c557ff0a180" }, { "identifier": "get_indicator_by_value/schema.py", - "hash": "6b4fc5e2ffb1217a4140607e6de6124b" + "hash": "f7ddc06620e844c3a4d9aed186daab5e" }, { "identifier": "get_indicator_scan_status/schema.py", - "hash": "59446e651fbae06f439478b26ab45d3c" + "hash": "8dee800f2700228a0ed251111785a228" }, { "identifier": "rescan_indicator/schema.py", - "hash": "5ff0acaac7454bf1f96d11b94dcad3e2" + "hash": "957d18eff29b84ba706c867dddd14139" }, { "identifier": "takedown_request/schema.py", - "hash": "e08d8b5e9f591e686637ff50114a2ba2" + "hash": "623d2b1efc3739038015ed9904bea097" }, { "identifier": "connection/schema.py", diff --git a/plugins/intsights/bin/icon_intsights b/plugins/intsights/bin/icon_intsights index 7d1b20dcd6..1b50194885 100755 --- a/plugins/intsights/bin/icon_intsights +++ b/plugins/intsights/bin/icon_intsights @@ -7,7 +7,7 @@ from sys import argv Name = "IntSights" Vendor = "rapid7" Version = "1.0.0" -Description = "IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy" +Description = "Rapid7 IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy" def main(): diff --git a/plugins/intsights/help.md b/plugins/intsights/help.md index ba7393c17c..f860cc1443 100644 --- a/plugins/intsights/help.md +++ b/plugins/intsights/help.md @@ -61,7 +61,7 @@ This action will create a manual alert with the provided parameters. |source_date|string|None|False|Alert source date|None|2020-02-01| |source_network_type|string|None|True|Source network type|['ClearWeb', 'DarkWeb']|DarkWeb| |source_type|string|None|True|Source type|['Application Store', 'Cyber Security Blog', 'Hacking News', 'Cyber Crime Forum', 'Hacktivism Forum', 'Social Media', 'Facebook', 'Twitter', 'LinkedIn', 'Google Plus', 'VK', 'Vimeo', 'YouTube', 'IRC Channel', 'IOC Block List', 'Credit Card Black Market', 'Paste Site', 'Data Leakage Website', 'Leaked Database', 'File Sharing Website', 'Gray Hat Website', 'Black Market', 'WHOIS servers', 'Company Website', 'Wikileaks', 'Pinterest', 'Tumblr', 'Instagram', 'Telegram', 'Webmail', 'Malware Analysis', 'Firehol', 'VRA']|Webmail| -|source_url|string|None|True|Source URL|None|https://example.com"| +|source_url|string|None|True|Source URL|None|https://example.com| |sub_type|string|None|True|Alert sub type, needs to correlate with the selected "Type"|None|SuspiciousEmailAddress| |title|string|None|True|Alert title|None|New Alert| |type|string|None|True|Alert type|['AttackIndication', 'DataLeakage', 'Phishing', 'BrandSecurity', 'ExploitableData', 'vip']|Phishing| @@ -72,12 +72,7 @@ Example input: { "description": "Suspicious addresses", "found_date": "2020-01-01", - "images": [ - { - "Type": "jpeg", - "Data": "UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==" - } - ], + "images": "[{\"Type\": \"jpeg\",\"Data\": \"UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==\"}]", "severity": "Medium", "source_date": "2020-02-01", "source_network_type": "DarkWeb", @@ -105,7 +100,7 @@ Example output: #### Takedown Request -This action is used to request a takedown for a given alert in Intsights. +Request a takedown for a given alert in IntSights ##### Input @@ -159,7 +154,7 @@ Example input: |----|----|--------|-----------| |assets|[]string|True|List of assets| |assignees|[]string|True|List of assignees| -|details|object|True|Alert Details| +|details|object|True|Alert details| |found_date|date|True|Alert found date| |id|string|True|Alert ID| |is_closed|boolean|True|Is alert closed| @@ -205,7 +200,7 @@ This action is used to force an indicator scan in Intsights TIP system. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_file_hash|string|None|True|IOC value in type file hash|None|30f800f97aeaa8d62bdf3a6fb2b0681179a360c12e127f07038f8521461e5050| +|indicator_file_hash|string|None|True|IOC value in type file hash|None|275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f| Example input: @@ -273,20 +268,20 @@ This action is used to search Alerts based on criteria. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|alert_type|string|None|False|Comma separated list of alert types. Allowed values - AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip|['AttackIndication', 'DataLeakage', 'Phishing', 'BrandSecurity', 'ExploitableData', 'vip']|Phishing| -|assigned|boolean|None|False|Show assigned/unAssigned alerts|None|True| +|alert_type|string|None|False|Comma-separated list of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip|['AttackIndication', 'DataLeakage', 'Phishing', 'BrandSecurity', 'ExploitableData', 'vip']|Phishing| +|assigned|boolean|None|False|Show assigned/unassigned alerts|None|True| |found_date_from|number|None|False|Start date to fetch from in Unix Millisecond Timestamp|None|0| |found_date_to|number|None|False|End date to fetch to in Unix Millisecond Timestamp|None|1633047102456| |has_indicators|boolean|None|False|Show alerts with IOCs results|None|False| |is_closed|boolean|None|False|Is closed/open alerts|None|False| |is_flagged|boolean|None|False|Show flagged/unflagged alerts|None|True| -|matched_asset_value|string|None|False|Comma separated list|None|https://example.com| -|network_type|string|None|False|Comma separated list of network type. Allowed values - ClearWeb, DarkWeb|['ClearWeb', 'DarkWeb']|DarkWeb| -|remediation_status|string|None|False|Comma separated list of remediation status. Allowed values - InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed|None|InProggres, Pending| -|severity|string|None|False|Comma separated list of alerts severity. Allowed values - High, Medium, Low|['High', 'Medium', 'Low']|Low| +|matched_asset_value|string|None|False|Comma-separated list|None|example.com| +|network_type|string|None|False|Comma-separated list of network type. Allowed values: ClearWeb, DarkWeb|['ClearWeb', 'DarkWeb']|DarkWeb| +|remediation_status|string|None|False|Comma-separated list of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed|None|InProgress, Pending| +|severity|string|None|False|Comma-separated list of alerts severity. Allowed values: High, Medium, Low|['High', 'Medium', 'Low']|Low| |source_date_from|number|None|False|Start date to fetch from in Unix Millisecond Timestamp|None|1633047083142| |source_date_to|number|None|False|End date to fetch to in Unix Millisecond Timestamp|None|1633047102456| -|source_type|string|None|False|Comma separated list of alerts source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others|['Application Store', 'Cyber Security Blog', 'Hacking News', 'Cyber Crime Forum', 'Hacktivism Forum', 'Social Media', 'Facebook', 'Twitter', 'LinkedIn', 'Google Plus', 'VK', 'Vimeo', 'YouTube', 'IRC Channel', 'IOC Block List', 'Credit Card Black Market', 'Paste Site', 'Data Leakage Website', 'Leaked Database', 'File Sharing Website', 'Gray Hat Website', 'Black Market', 'WHOIS servers', 'Company Website', 'Wikileaks', 'Pinterest', 'Tumblr', 'Instagram', 'Telegram', 'Webmail', 'Malware Analysis', 'Firehol', 'VRA', 'Other']|Application Store| +|source_type|string|None|False|Comma-separated list of alerts source type. Allowed values: ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others|['Application Store', 'Cyber Security Blog', 'Hacking News', 'Cyber Crime Forum', 'Hacktivism Forum', 'Social Media', 'Facebook', 'Twitter', 'LinkedIn', 'Google Plus', 'VK', 'Vimeo', 'YouTube', 'IRC Channel', 'IOC Block List', 'Credit Card Black Market', 'Paste Site', 'Data Leakage Website', 'Leaked Database', 'File Sharing Website', 'Gray Hat Website', 'Black Market', 'WHOIS servers', 'Company Website', 'Wikileaks', 'Pinterest', 'Tumblr', 'Instagram', 'Telegram', 'Webmail', 'Malware Analysis', 'Firehol', 'VRA', 'Other']|Application Store| Example input: @@ -301,7 +296,7 @@ Example input: "is_flagged": true, "matched_asset_value": "example.com", "network_type": "DarkWeb", - "remediation_status": "InProggres, Pending", + "remediation_status": "InProgress, Pending", "severity": "Low", "source_date_from": 1633047083142, "source_date_to": 1633047102456, @@ -334,7 +329,7 @@ This action is used to submit an indicator to IntSights for investigation and re |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_value|string|None|True|Value of the indicator|None|https://example.com| +|indicator_value|string|None|True|Value of the indicator|None|example.com| Example input: @@ -563,7 +558,7 @@ This action will search indicators in IntSights TIP. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_value|string|None|True|Value of the indicator|None|https://example.com| +|indicator_value|string|None|True|Value of the indicator|None|example.com| Example input: @@ -577,17 +572,17 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|first_seen|string|False|First Seen| -|geo_location|string|False|GEO Location| -|last_seen|string|False|Last Seen| -|last_update|string|False|Last Update| -|related_campaigns|[]string|True|Related Campaigns| -|related_malware|[]string|True|Related Malware| -|related_threat_actors|[]string|True|Related Threat Actors| +|first_seen|string|False|First seen| +|geo_location|string|False|Geographic location| +|last_seen|string|False|Last seen| +|last_update|string|False|Last update| +|related_campaigns|[]string|True|Related campaigns| +|related_malware|[]string|True|Related malware| +|related_threat_actors|[]string|True|Related threat actors| |score|integer|True|Score| |severity|string|False|Severity| |sources|[]source|True|Sources| -|system_tags|[]string|True|System Tags| +|system_tags|[]string|True|System tags| |tags|[]string|True|Tags| |type|string|False|Type| |value|string|False|Value| @@ -614,7 +609,7 @@ Example output: "system_tags": [], "tags": [], "type": "Domains", - "value": "https://example.com", + "value": "example.com", "whitelist": true } ``` diff --git a/plugins/intsights/icon_intsights/actions/get_alerts/schema.py b/plugins/intsights/icon_intsights/actions/get_alerts/schema.py index 2a3e5ddc37..205e9e9b67 100755 --- a/plugins/intsights/icon_intsights/actions/get_alerts/schema.py +++ b/plugins/intsights/icon_intsights/actions/get_alerts/schema.py @@ -4,7 +4,7 @@ class Component: - DESCRIPTION = "Search Alerts based on criteria" + DESCRIPTION = "Search alerts based on criteria" class Input: @@ -37,7 +37,7 @@ class GetAlertsInput(insightconnect_plugin_runtime.Input): "alert_type": { "type": "string", "title": "Alert Type", - "description": "Comma separated list of alert types. Allowed values - AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip", + "description": "Comma-separated list of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip", "enum": [ "AttackIndication", "DataLeakage", @@ -50,8 +50,8 @@ class GetAlertsInput(insightconnect_plugin_runtime.Input): }, "assigned": { "type": "boolean", - "title": "Assigned", - "description": "Show assigned/unAssigned alerts", + "title": "Alert Assignment", + "description": "Show assigned/unassigned alerts", "order": 11 }, "found_date_from": { @@ -74,26 +74,26 @@ class GetAlertsInput(insightconnect_plugin_runtime.Input): }, "is_closed": { "type": "boolean", - "title": "Is Closed", + "title": "Closed Status", "description": "Is closed/open alerts", "order": 13 }, "is_flagged": { "type": "boolean", - "title": "Is Flagged", + "title": "Alert Flag Status", "description": "Show flagged/unflagged alerts", "order": 12 }, "matched_asset_value": { "type": "string", "title": "Matched Asset Value", - "description": "Comma separated list", + "description": "Comma-separated list", "order": 5 }, "network_type": { "type": "string", "title": "Network Type", - "description": "Comma separated list of network type. Allowed values - ClearWeb, DarkWeb", + "description": "Comma-separated list of network type. Allowed values: ClearWeb, DarkWeb", "enum": [ "ClearWeb", "DarkWeb" @@ -103,13 +103,13 @@ class GetAlertsInput(insightconnect_plugin_runtime.Input): "remediation_status": { "type": "string", "title": "Remediation Status", - "description": "Comma separated list of remediation status. Allowed values - InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed", + "description": "Comma-separated list of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed", "order": 6 }, "severity": { "type": "string", "title": "Severity", - "description": "Comma separated list of alerts severity. Allowed values - High, Medium, Low", + "description": "Comma-separated list of alerts severity. Allowed values: High, Medium, Low", "enum": [ "High", "Medium", @@ -132,7 +132,7 @@ class GetAlertsInput(insightconnect_plugin_runtime.Input): "source_type": { "type": "string", "title": "Source Type", - "description": "Comma separated list of alerts source type. Allowed values - ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others", + "description": "Comma-separated list of alerts source type. Allowed values: ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others", "enum": [ "Application Store", "Cyber Security Blog", diff --git a/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/schema.py b/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/schema.py index e0e8973a7c..b0e5ce1809 100755 --- a/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/schema.py +++ b/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/schema.py @@ -74,7 +74,7 @@ class GetCompleteAlertByIdOutput(insightconnect_plugin_runtime.Output): "details": { "type": "object", "title": "Details", - "description": "Alert Details", + "description": "Alert details", "order": 4 }, "found_date": { diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py index fd9c5cddae..92bb2782d3 100755 --- a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py +++ b/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py @@ -61,31 +61,31 @@ class GetIndicatorByValueOutput(insightconnect_plugin_runtime.Output): "first_seen": { "type": "string", "title": "First Seen", - "description": "First Seen", + "description": "First seen", "order": 6 }, "geo_location": { "type": "string", - "title": "GEO Location", - "description": "GEO Location", + "title": "Geographic Location", + "description": "Geographic location", "order": 9 }, "last_seen": { "type": "string", "title": "Last Seen", - "description": "Last Seen", + "description": "Last seen", "order": 7 }, "last_update": { "type": "string", "title": "Last Update", - "description": "Last Update", + "description": "Last update", "order": 8 }, "related_campaigns": { "type": "array", "title": "Related Campaigns", - "description": "Related Campaigns", + "description": "Related campaigns", "items": { "type": "string" }, @@ -94,7 +94,7 @@ class GetIndicatorByValueOutput(insightconnect_plugin_runtime.Output): "related_malware": { "type": "array", "title": "Related Malware", - "description": "Related Malware", + "description": "Related malware", "items": { "type": "string" }, @@ -103,7 +103,7 @@ class GetIndicatorByValueOutput(insightconnect_plugin_runtime.Output): "related_threat_actors": { "type": "array", "title": "Related Threat Actors", - "description": "Related Threat Actors", + "description": "Related threat actors", "items": { "type": "string" }, @@ -133,7 +133,7 @@ class GetIndicatorByValueOutput(insightconnect_plugin_runtime.Output): "system_tags": { "type": "array", "title": "System Tags", - "description": "System Tags", + "description": "System tags", "items": { "type": "string" }, diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/schema.py b/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/schema.py index 08da69a93a..47351fded0 100755 --- a/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/schema.py +++ b/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/schema.py @@ -4,7 +4,7 @@ class Component: - DESCRIPTION = "Get the scan status of an indicator in Insights TIP system" + DESCRIPTION = "Get the scan status of an indicator in the IntSights TIP system" class Input: diff --git a/plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py b/plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py index 847a38047c..c3b87523a7 100755 --- a/plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py +++ b/plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py @@ -4,7 +4,7 @@ class Component: - DESCRIPTION = "Force an indicator scan in Intsights TIP system" + DESCRIPTION = "Force an indicator scan in IntSights TIP system" class Input: diff --git a/plugins/intsights/icon_intsights/actions/takedown_request/schema.py b/plugins/intsights/icon_intsights/actions/takedown_request/schema.py index b00cec8ac0..f74da5d5ea 100755 --- a/plugins/intsights/icon_intsights/actions/takedown_request/schema.py +++ b/plugins/intsights/icon_intsights/actions/takedown_request/schema.py @@ -4,7 +4,7 @@ class Component: - DESCRIPTION = "Request a takedown for a given alert in Intsights" + DESCRIPTION = "Request a takedown for a given alert in IntSights" class Input: diff --git a/plugins/intsights/icon_intsights/connection/connection.py b/plugins/intsights/icon_intsights/connection/connection.py index 09deb1303a..c4dca024dd 100755 --- a/plugins/intsights/icon_intsights/connection/connection.py +++ b/plugins/intsights/icon_intsights/connection/connection.py @@ -3,17 +3,17 @@ # Custom imports below from typing import Optional -from icon_intsights.util.api import IntSightAPI +from icon_intsights.util.api import IntSightsAPI from insightconnect_plugin_runtime.exceptions import PluginException, ConnectionTestException class Connection(insightconnect_plugin_runtime.Connection): def __init__(self): super(self.__class__, self).__init__(input=ConnectionSchema()) - self.client: Optional[IntSightAPI] = None + self.client: Optional[IntSightsAPI] = None def connect(self, params={}): - self.client = IntSightAPI( + self.client = IntSightsAPI( params.get(Input.ACCOUNT_ID, {}).get("secretKey"), params.get(Input.API_KEY, {}).get("secretKey"), self.logger, diff --git a/plugins/intsights/icon_intsights/util/api.py b/plugins/intsights/icon_intsights/util/api.py index e15afd837e..d2694781d0 100644 --- a/plugins/intsights/icon_intsights/util/api.py +++ b/plugins/intsights/icon_intsights/util/api.py @@ -98,7 +98,7 @@ def to_dict(self) -> dict: ) -class IntSightAPI: +class IntSightsAPI: def __init__(self, account_id: str, api_key: str, logger: Logger): self.account_id = account_id self.api_key = api_key diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index a108d0a5bc..a98b8122d4 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -218,7 +218,7 @@ actions: input: alert_type: title: Alert Type - description: Comma-separated list of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip + description: 'Comma-separated list of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip' type: string required: false enum: @@ -231,7 +231,7 @@ actions: example: Phishing severity: title: Severity - description: Comma-separated list of alerts severity. Allowed values: High, Medium, Low + description: 'Comma-separated list of alerts severity. Allowed values: High, Medium, Low' type: string required: false enum: @@ -241,7 +241,7 @@ actions: example: Low source_type: title: Source Type - description: Comma-separated list of alerts source type. Allowed values: ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others + description: 'Comma-separated list of alerts source type. Allowed values: ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others' type: string required: false enum: @@ -282,7 +282,7 @@ actions: example: Application Store network_type: title: Network Type - description: Comma-separated list of network type. Allowed values: ClearWeb, DarkWeb + description: 'Comma-separated list of network type. Allowed values: ClearWeb, DarkWeb' type: string required: false enum: @@ -297,7 +297,7 @@ actions: example: example.com remediation_status: title: Remediation Status - description: Comma-separated list of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed + description: 'Comma-separated list of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed' type: string required: false example: InProgress, Pending diff --git a/plugins/intsights/setup.py b/plugins/intsights/setup.py index b4e1de0318..7b86ddf48e 100755 --- a/plugins/intsights/setup.py +++ b/plugins/intsights/setup.py @@ -4,7 +4,7 @@ setup(name="intsights-rapid7-plugin", version="1.0.0", - description="IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy", + description="Rapid7 IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy", author="rapid7", author_email="", url="", From 3dcd7bf100619078ac05c56bb79c011d154b2d42 Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Mon, 25 Oct 2021 23:24:33 +0200 Subject: [PATCH 38/60] [MC-683] Fix help --- plugins/intsights/help.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/intsights/help.md b/plugins/intsights/help.md index f860cc1443..8707807d2c 100644 --- a/plugins/intsights/help.md +++ b/plugins/intsights/help.md @@ -72,7 +72,10 @@ Example input: { "description": "Suspicious addresses", "found_date": "2020-01-01", - "images": "[{\"Type\": \"jpeg\",\"Data\": \"UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==\"}]", + "images": [{ + "Type": "jpeg", + "Data": "UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==" + }], "severity": "Medium", "source_date": "2020-02-01", "source_network_type": "DarkWeb", From 246b9f3f3f7ca5c5d2209203885f199a44ee2761 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Tue, 26 Oct 2021 00:05:07 +0200 Subject: [PATCH 39/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index a108d0a5bc..cf46146e12 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -334,7 +334,7 @@ actions: is_flagged: title: Alert Flag Status description: Show flagged/unflagged alerts - type: boolean + type: string required: false example: true is_closed: From 4d2f577904d20b3a9c3d539de8c5ae64d6ffd315 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Tue, 26 Oct 2021 00:05:28 +0200 Subject: [PATCH 40/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index cf46146e12..3c7a125cdd 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -285,9 +285,6 @@ actions: description: Comma-separated list of network type. Allowed values: ClearWeb, DarkWeb type: string required: false - enum: - - ClearWeb - - DarkWeb example: DarkWeb matched_asset_value: title: Matched Asset Value From 7d46a8d2b457ffb5accc9ff849f06689a31186aa Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Tue, 26 Oct 2021 00:05:55 +0200 Subject: [PATCH 41/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 3c7a125cdd..0df1d8d160 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -301,7 +301,7 @@ actions: source_date_from: title: Source Date From description: Start date to fetch from in Unix Millisecond Timestamp - type: number + type: string required: false example: 1633047083142 source_date_to: From f9a7eda90951932a5dbccdfed3e63e5d94744353 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Tue, 26 Oct 2021 00:06:15 +0200 Subject: [PATCH 42/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 0df1d8d160..5ffbdaa26f 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -307,7 +307,7 @@ actions: source_date_to: title: Source Date To description: End date to fetch to in Unix Millisecond Timestamp - type: number + type: string required: false example: 1633047102456 found_date_from: From 0c021cc23f3f0682328a4891a1bf743399c8179f Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Tue, 26 Oct 2021 00:06:39 +0200 Subject: [PATCH 43/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 5ffbdaa26f..82767db6c3 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -313,7 +313,7 @@ actions: found_date_from: title: Found Date From description: Start date to fetch from in Unix Millisecond Timestamp - type: number + type: string required: false example: 0 found_date_to: From d04cfe905e7e9d07260ca3c40ddbe89c4734d36c Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Tue, 26 Oct 2021 00:07:35 +0200 Subject: [PATCH 44/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 82767db6c3..f6e4ac9a77 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -319,7 +319,7 @@ actions: found_date_to: title: Found Date To description: End date to fetch to in Unix Millisecond Timestamp - type: number + type: string required: false example: 1633047102456 assigned: From 7fcdcdc9f0888e0d911b0e9a1910b138787fa018 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Tue, 26 Oct 2021 00:07:55 +0200 Subject: [PATCH 45/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index f6e4ac9a77..51fe6ae045 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -325,7 +325,7 @@ actions: assigned: title: Alert Assignment description: Show assigned/unassigned alerts - type: boolean + type: string required: false example: true is_flagged: From ba9187e6a028dec9d8aabccb14f19a312f71adb8 Mon Sep 17 00:00:00 2001 From: r7-mgorny <65253008+r7-mgorny@users.noreply.github.com> Date: Tue, 26 Oct 2021 00:08:17 +0200 Subject: [PATCH 46/60] Update plugins/intsights/plugin.spec.yaml Co-authored-by: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> --- plugins/intsights/plugin.spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/intsights/plugin.spec.yaml index 51fe6ae045..f299c497ae 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/intsights/plugin.spec.yaml @@ -336,7 +336,7 @@ actions: example: true is_closed: title: Closed Status - description: Is closed/open alerts + description: Status of the alert, either closed or open type: boolean required: false example: false From 55314a7394f4466e1b55730b61adf58c058c1ca7 Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Tue, 26 Oct 2021 00:10:27 +0200 Subject: [PATCH 47/60] [MC-683] Change plugin name to rapid7_intsights --- .../{intsights => rapid7_intsights}/.CHECKSUM | 12 +++--- .../.dockerignore | 0 .../Dockerfile | 2 +- .../{intsights => rapid7_intsights}/Makefile | 0 .../bin/icon_rapid7_intsights} | 8 ++-- .../{intsights => rapid7_intsights}/help.md | 19 ++++------ .../icon_rapid7_intsights}/__init__.py | 0 .../actions/__init__.py | 0 .../actions/add_manual_alert/__init__.py | 0 .../actions/add_manual_alert/action.py | 2 +- .../actions/add_manual_alert/schema.py | 0 .../actions/enrich_indicator/__init__.py | 0 .../actions/enrich_indicator/action.py | 0 .../actions/enrich_indicator/schema.py | 0 .../actions/get_alerts/__init__.py | 0 .../actions/get_alerts/action.py | 2 +- .../actions/get_alerts/schema.py | 13 ++----- .../get_complete_alert_by_id/__init__.py | 0 .../get_complete_alert_by_id/action.py | 0 .../get_complete_alert_by_id/schema.py | 0 .../get_indicator_by_value/__init__.py | 0 .../actions/get_indicator_by_value/action.py | 0 .../actions/get_indicator_by_value/schema.py | 4 +- .../get_indicator_scan_status/__init__.py | 0 .../get_indicator_scan_status/action.py | 0 .../get_indicator_scan_status/schema.py | 0 .../actions/rescan_indicator/__init__.py | 0 .../actions/rescan_indicator/action.py | 0 .../actions/rescan_indicator/schema.py | 0 .../actions/takedown_request/__init__.py | 0 .../actions/takedown_request/action.py | 0 .../actions/takedown_request/schema.py | 0 .../connection/__init__.py | 0 .../connection/connection.py | 4 +- .../connection/schema.py | 2 +- .../triggers/__init__.py | 0 .../icon_rapid7_intsights}/util/__init__.py | 0 .../icon_rapid7_intsights}/util/api.py | 38 +++++++++---------- .../plugin.spec.yaml | 7 ++-- .../requirements.txt | 0 .../{intsights => rapid7_intsights}/setup.py | 4 +- .../unit_test/__init__.py | 0 .../payloads/add_manual_alert.json.resp | 0 .../enrich_indicator-in_progress.json.resp | 0 .../payloads/enrich_indicator.json.resp | 0 .../unit_test/payloads/get_alerts.json.resp | 0 .../payloads/get_alerts_empty_list.json.resp | 0 .../get_complete_alert_by_id.json.resp | 0 .../get_indicator_scan_status.bad.json.resp | 0 .../get_indicator_scan_status.json.resp | 0 .../payloads/iocs_ioc-by-value.json.resp | 0 .../payloads/rescan_indicator.bad.json.resp | 0 .../payloads/rescan_indicator.json.resp | 0 .../unit_test/test_add_manual_alert.py | 4 +- .../unit_test/test_connection.py | 4 +- .../unit_test/test_enrich_indicator.py | 4 +- .../unit_test/test_get_alerts.py | 4 +- .../test_get_complete_alert_by_id.py | 4 +- .../unit_test/test_get_indicator_by_value.py | 4 +- .../test_get_indicator_scan_status.py | 4 +- .../unit_test/test_rescan_indicator.py | 4 +- .../unit_test/util.py | 4 +- 62 files changed, 73 insertions(+), 80 deletions(-) rename plugins/{intsights => rapid7_intsights}/.CHECKSUM (74%) rename plugins/{intsights => rapid7_intsights}/.dockerignore (100%) rename plugins/{intsights => rapid7_intsights}/Dockerfile (93%) rename plugins/{intsights => rapid7_intsights}/Makefile (100%) rename plugins/{intsights/bin/icon_intsights => rapid7_intsights/bin/icon_rapid7_intsights} (88%) rename plugins/{intsights => rapid7_intsights}/help.md (96%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/add_manual_alert/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/add_manual_alert/action.py (95%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/add_manual_alert/schema.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/enrich_indicator/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/enrich_indicator/action.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/enrich_indicator/schema.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/get_alerts/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/get_alerts/action.py (96%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/get_alerts/schema.py (96%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/get_complete_alert_by_id/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/get_complete_alert_by_id/action.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/get_complete_alert_by_id/schema.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/get_indicator_by_value/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/get_indicator_by_value/action.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/get_indicator_by_value/schema.py (98%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/get_indicator_scan_status/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/get_indicator_scan_status/action.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/get_indicator_scan_status/schema.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/rescan_indicator/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/rescan_indicator/action.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/rescan_indicator/schema.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/takedown_request/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/takedown_request/action.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/actions/takedown_request/schema.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/connection/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/connection/connection.py (88%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/connection/schema.py (95%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/triggers/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/util/__init__.py (100%) rename plugins/{intsights/icon_intsights => rapid7_intsights/icon_rapid7_intsights}/util/api.py (88%) rename plugins/{intsights => rapid7_intsights}/plugin.spec.yaml (99%) rename plugins/{intsights => rapid7_intsights}/requirements.txt (100%) rename plugins/{intsights => rapid7_intsights}/setup.py (87%) rename plugins/{intsights => rapid7_intsights}/unit_test/__init__.py (100%) rename plugins/{intsights => rapid7_intsights}/unit_test/payloads/add_manual_alert.json.resp (100%) rename plugins/{intsights => rapid7_intsights}/unit_test/payloads/enrich_indicator-in_progress.json.resp (100%) rename plugins/{intsights => rapid7_intsights}/unit_test/payloads/enrich_indicator.json.resp (100%) rename plugins/{intsights => rapid7_intsights}/unit_test/payloads/get_alerts.json.resp (100%) rename plugins/{intsights => rapid7_intsights}/unit_test/payloads/get_alerts_empty_list.json.resp (100%) rename plugins/{intsights => rapid7_intsights}/unit_test/payloads/get_complete_alert_by_id.json.resp (100%) rename plugins/{intsights => rapid7_intsights}/unit_test/payloads/get_indicator_scan_status.bad.json.resp (100%) rename plugins/{intsights => rapid7_intsights}/unit_test/payloads/get_indicator_scan_status.json.resp (100%) rename plugins/{intsights => rapid7_intsights}/unit_test/payloads/iocs_ioc-by-value.json.resp (100%) rename plugins/{intsights => rapid7_intsights}/unit_test/payloads/rescan_indicator.bad.json.resp (100%) rename plugins/{intsights => rapid7_intsights}/unit_test/payloads/rescan_indicator.json.resp (100%) rename plugins/{intsights => rapid7_intsights}/unit_test/test_add_manual_alert.py (94%) rename plugins/{intsights => rapid7_intsights}/unit_test/test_connection.py (92%) rename plugins/{intsights => rapid7_intsights}/unit_test/test_enrich_indicator.py (89%) rename plugins/{intsights => rapid7_intsights}/unit_test/test_get_alerts.py (92%) rename plugins/{intsights => rapid7_intsights}/unit_test/test_get_complete_alert_by_id.py (89%) rename plugins/{intsights => rapid7_intsights}/unit_test/test_get_indicator_by_value.py (92%) rename plugins/{intsights => rapid7_intsights}/unit_test/test_get_indicator_scan_status.py (87%) rename plugins/{intsights => rapid7_intsights}/unit_test/test_rescan_indicator.py (89%) rename plugins/{intsights => rapid7_intsights}/unit_test/util.py (97%) diff --git a/plugins/intsights/.CHECKSUM b/plugins/rapid7_intsights/.CHECKSUM similarity index 74% rename from plugins/intsights/.CHECKSUM rename to plugins/rapid7_intsights/.CHECKSUM index ccf91bd7bf..7f439bb222 100644 --- a/plugins/intsights/.CHECKSUM +++ b/plugins/rapid7_intsights/.CHECKSUM @@ -1,7 +1,7 @@ { - "spec": "666b3a1ce78eb048de5e49ee1c26ce45", - "manifest": "9ee7bbc03de21a7f9edefdef3218148a", - "setup": "418f9067c4ef247786d7bacadcb3dceb", + "spec": "b088c63ad80764cd577bef4c71444c1a", + "manifest": "9a1c0ed12f4a14563a7e6ee8431fcb56", + "setup": "03540fca0745c2f43e81830a80d402bb", "schemas": [ { "identifier": "add_manual_alert/schema.py", @@ -13,7 +13,7 @@ }, { "identifier": "get_alerts/schema.py", - "hash": "8fb0ed7bda2a9abc7a070b022d5acd37" + "hash": "e328ecc4099593ccaea2019fb603dea6" }, { "identifier": "get_complete_alert_by_id/schema.py", @@ -21,7 +21,7 @@ }, { "identifier": "get_indicator_by_value/schema.py", - "hash": "f7ddc06620e844c3a4d9aed186daab5e" + "hash": "1b8a24fd526eebcf1f7b818667c38ce2" }, { "identifier": "get_indicator_scan_status/schema.py", @@ -37,7 +37,7 @@ }, { "identifier": "connection/schema.py", - "hash": "12bbf6684d6ecd35418685136b4437bd" + "hash": "4d9563dcc56614543713c05f554ef869" } ] } \ No newline at end of file diff --git a/plugins/intsights/.dockerignore b/plugins/rapid7_intsights/.dockerignore similarity index 100% rename from plugins/intsights/.dockerignore rename to plugins/rapid7_intsights/.dockerignore diff --git a/plugins/intsights/Dockerfile b/plugins/rapid7_intsights/Dockerfile similarity index 93% rename from plugins/intsights/Dockerfile rename to plugins/rapid7_intsights/Dockerfile index c9514d3520..60c9615ce2 100755 --- a/plugins/intsights/Dockerfile +++ b/plugins/rapid7_intsights/Dockerfile @@ -23,4 +23,4 @@ RUN python setup.py build && python setup.py install # User to run plugin code. The two supported users are: root, nobody USER nobody -ENTRYPOINT ["/usr/local/bin/icon_intsights"] \ No newline at end of file +ENTRYPOINT ["/usr/local/bin/icon_rapid7_intsights"] \ No newline at end of file diff --git a/plugins/intsights/Makefile b/plugins/rapid7_intsights/Makefile similarity index 100% rename from plugins/intsights/Makefile rename to plugins/rapid7_intsights/Makefile diff --git a/plugins/intsights/bin/icon_intsights b/plugins/rapid7_intsights/bin/icon_rapid7_intsights similarity index 88% rename from plugins/intsights/bin/icon_intsights rename to plugins/rapid7_intsights/bin/icon_rapid7_intsights index 1b50194885..65c6cfe416 100755 --- a/plugins/intsights/bin/icon_intsights +++ b/plugins/rapid7_intsights/bin/icon_rapid7_intsights @@ -4,7 +4,7 @@ import os import json from sys import argv -Name = "IntSights" +Name = "Rapid7 IntSights" Vendor = "rapid7" Version = "1.0.0" Description = "Rapid7 IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy" @@ -23,9 +23,9 @@ def main(): monkey.patch_all() import insightconnect_plugin_runtime - from icon_intsights import connection, actions, triggers + from icon_rapid7_intsights import connection, actions, triggers - class ICONIntsights(insightconnect_plugin_runtime.Plugin): + class ICONRapid7Intsights(insightconnect_plugin_runtime.Plugin): def __init__(self): super(self.__class__, self).__init__( name=Name, @@ -52,7 +52,7 @@ def main(): """Run plugin""" - cli = insightconnect_plugin_runtime.CLI(ICONIntsights()) + cli = insightconnect_plugin_runtime.CLI(ICONRapid7Intsights()) cli.run() diff --git a/plugins/intsights/help.md b/plugins/rapid7_intsights/help.md similarity index 96% rename from plugins/intsights/help.md rename to plugins/rapid7_intsights/help.md index 8707807d2c..a6524a1113 100644 --- a/plugins/intsights/help.md +++ b/plugins/rapid7_intsights/help.md @@ -30,7 +30,7 @@ The connection configuration accepts the following parameters: |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|account_id|credential_secret_key|None|True|Account ID for IntSights|None|9de5069c5afe602b2ea0a04b| +|account_id|string|None|True|Account ID for IntSights|None|9de5069c5afe602b2ea0a04b| |api_key|credential_secret_key|None|True|API key for IntSights|None|bffce7a2e653eb3e499b69238c6ed672727a642e6f07c19fe19b4d59c7a2d2a61078d1601ded75bac3859fc5c204279402ccf141e1999edf9deb47951f96f4c1| Example input: @@ -72,10 +72,7 @@ Example input: { "description": "Suspicious addresses", "found_date": "2020-01-01", - "images": [{ - "Type": "jpeg", - "Data": "UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==" - }], + "images": "[{\"Type\": \"jpeg\",\"Data\": \"UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==\"}]", "severity": "Medium", "source_date": "2020-02-01", "source_network_type": "DarkWeb", @@ -203,7 +200,7 @@ This action is used to force an indicator scan in Intsights TIP system. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_file_hash|string|None|True|IOC value in type file hash|None|275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f| +|indicator_file_hash|string|None|True|IOC value in type file hash|None|30f800f97aeaa8d62bdf3a6fb2b0681179a360c12e127f07038f8521461e5050| Example input: @@ -271,14 +268,14 @@ This action is used to search Alerts based on criteria. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|alert_type|string|None|False|Comma-separated list of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip|['AttackIndication', 'DataLeakage', 'Phishing', 'BrandSecurity', 'ExploitableData', 'vip']|Phishing| +|alert_type|[]string|None|False|Comma-separated list of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip|None|Phishing| |assigned|boolean|None|False|Show assigned/unassigned alerts|None|True| |found_date_from|number|None|False|Start date to fetch from in Unix Millisecond Timestamp|None|0| |found_date_to|number|None|False|End date to fetch to in Unix Millisecond Timestamp|None|1633047102456| |has_indicators|boolean|None|False|Show alerts with IOCs results|None|False| |is_closed|boolean|None|False|Is closed/open alerts|None|False| |is_flagged|boolean|None|False|Show flagged/unflagged alerts|None|True| -|matched_asset_value|string|None|False|Comma-separated list|None|example.com| +|matched_asset_value|string|None|False|Comma-separated list|None|https://example.com| |network_type|string|None|False|Comma-separated list of network type. Allowed values: ClearWeb, DarkWeb|['ClearWeb', 'DarkWeb']|DarkWeb| |remediation_status|string|None|False|Comma-separated list of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed|None|InProgress, Pending| |severity|string|None|False|Comma-separated list of alerts severity. Allowed values: High, Medium, Low|['High', 'Medium', 'Low']|Low| @@ -332,7 +329,7 @@ This action is used to submit an indicator to IntSights for investigation and re |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_value|string|None|True|Value of the indicator|None|example.com| +|indicator_value|string|None|True|Value of the indicator|None|https://example.com| Example input: @@ -561,7 +558,7 @@ This action will search indicators in IntSights TIP. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_value|string|None|True|Value of the indicator|None|example.com| +|indicator_value|string|None|True|Value of the indicator|None|https://example.com| Example input: @@ -588,7 +585,7 @@ Example input: |system_tags|[]string|True|System tags| |tags|[]string|True|Tags| |type|string|False|Type| -|value|string|False|Value| +|value|string|False|Indicator value| |whitelist|boolean|True|Whitelist| Example output: diff --git a/plugins/intsights/icon_intsights/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/__init__.py diff --git a/plugins/intsights/icon_intsights/actions/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/__init__.py diff --git a/plugins/intsights/icon_intsights/actions/add_manual_alert/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/add_manual_alert/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/add_manual_alert/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/add_manual_alert/__init__.py diff --git a/plugins/intsights/icon_intsights/actions/add_manual_alert/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/add_manual_alert/action.py similarity index 95% rename from plugins/intsights/icon_intsights/actions/add_manual_alert/action.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/add_manual_alert/action.py index a5f205c5bc..faaf9ef63c 100755 --- a/plugins/intsights/icon_intsights/actions/add_manual_alert/action.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/add_manual_alert/action.py @@ -2,7 +2,7 @@ from .schema import AddManualAlertInput, AddManualAlertOutput, Input, Output, Component # Custom imports below -from icon_intsights.util.api import ManualAlertParams +from icon_rapid7_intsights.util.api import ManualAlertParams class AddManualAlert(insightconnect_plugin_runtime.Action): diff --git a/plugins/intsights/icon_intsights/actions/add_manual_alert/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/add_manual_alert/schema.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/add_manual_alert/schema.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/add_manual_alert/schema.py diff --git a/plugins/intsights/icon_intsights/actions/enrich_indicator/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/enrich_indicator/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/__init__.py diff --git a/plugins/intsights/icon_intsights/actions/enrich_indicator/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/enrich_indicator/action.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py diff --git a/plugins/intsights/icon_intsights/actions/enrich_indicator/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/schema.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/enrich_indicator/schema.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/schema.py diff --git a/plugins/intsights/icon_intsights/actions/get_alerts/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_alerts/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/get_alerts/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_alerts/__init__.py diff --git a/plugins/intsights/icon_intsights/actions/get_alerts/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_alerts/action.py similarity index 96% rename from plugins/intsights/icon_intsights/actions/get_alerts/action.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_alerts/action.py index ae46ef37dc..10181adfe6 100755 --- a/plugins/intsights/icon_intsights/actions/get_alerts/action.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_alerts/action.py @@ -2,7 +2,7 @@ from .schema import GetAlertsInput, GetAlertsOutput, Input, Output, Component # Custom imports below -from icon_intsights.util.api import AlertParams +from icon_rapid7_intsights.util.api import AlertParams class GetAlerts(insightconnect_plugin_runtime.Action): diff --git a/plugins/intsights/icon_intsights/actions/get_alerts/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_alerts/schema.py similarity index 96% rename from plugins/intsights/icon_intsights/actions/get_alerts/schema.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_alerts/schema.py index 205e9e9b67..e9eeb3e866 100755 --- a/plugins/intsights/icon_intsights/actions/get_alerts/schema.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_alerts/schema.py @@ -35,17 +35,12 @@ class GetAlertsInput(insightconnect_plugin_runtime.Input): "title": "Variables", "properties": { "alert_type": { - "type": "string", + "type": "array", "title": "Alert Type", "description": "Comma-separated list of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip", - "enum": [ - "AttackIndication", - "DataLeakage", - "Phishing", - "BrandSecurity", - "ExploitableData", - "vip" - ], + "items": { + "type": "string" + }, "order": 1 }, "assigned": { diff --git a/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/__init__.py diff --git a/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/action.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/action.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/action.py diff --git a/plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/get_complete_alert_by_id/schema.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_by_value/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/get_indicator_by_value/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_by_value/__init__.py diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_by_value/action.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/get_indicator_by_value/action.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_by_value/action.py diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_by_value/schema.py similarity index 98% rename from plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_by_value/schema.py index 92bb2782d3..0cc67fce1e 100755 --- a/plugins/intsights/icon_intsights/actions/get_indicator_by_value/schema.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_by_value/schema.py @@ -156,8 +156,8 @@ class GetIndicatorByValueOutput(insightconnect_plugin_runtime.Output): }, "value": { "type": "string", - "title": "Value", - "description": "Value", + "title": "Indicator Value", + "description": "Indicator value", "order": 1 }, "whitelist": { diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/get_indicator_scan_status/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/__init__.py diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/action.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/get_indicator_scan_status/action.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/action.py diff --git a/plugins/intsights/icon_intsights/actions/get_indicator_scan_status/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/schema.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/get_indicator_scan_status/schema.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/schema.py diff --git a/plugins/intsights/icon_intsights/actions/rescan_indicator/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/rescan_indicator/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/rescan_indicator/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/rescan_indicator/__init__.py diff --git a/plugins/intsights/icon_intsights/actions/rescan_indicator/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/rescan_indicator/action.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/rescan_indicator/action.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/rescan_indicator/action.py diff --git a/plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/rescan_indicator/schema.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/rescan_indicator/schema.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/rescan_indicator/schema.py diff --git a/plugins/intsights/icon_intsights/actions/takedown_request/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/takedown_request/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/takedown_request/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/takedown_request/__init__.py diff --git a/plugins/intsights/icon_intsights/actions/takedown_request/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/takedown_request/action.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/takedown_request/action.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/takedown_request/action.py diff --git a/plugins/intsights/icon_intsights/actions/takedown_request/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/takedown_request/schema.py similarity index 100% rename from plugins/intsights/icon_intsights/actions/takedown_request/schema.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/actions/takedown_request/schema.py diff --git a/plugins/intsights/icon_intsights/connection/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/connection/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/connection/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/connection/__init__.py diff --git a/plugins/intsights/icon_intsights/connection/connection.py b/plugins/rapid7_intsights/icon_rapid7_intsights/connection/connection.py similarity index 88% rename from plugins/intsights/icon_intsights/connection/connection.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/connection/connection.py index c4dca024dd..1261741b5f 100755 --- a/plugins/intsights/icon_intsights/connection/connection.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/connection/connection.py @@ -3,7 +3,7 @@ # Custom imports below from typing import Optional -from icon_intsights.util.api import IntSightsAPI +from icon_rapid7_intsights.util.api import IntSightsAPI from insightconnect_plugin_runtime.exceptions import PluginException, ConnectionTestException @@ -14,7 +14,7 @@ def __init__(self): def connect(self, params={}): self.client = IntSightsAPI( - params.get(Input.ACCOUNT_ID, {}).get("secretKey"), + params.get(Input.ACCOUNT_ID), params.get(Input.API_KEY, {}).get("secretKey"), self.logger, ) diff --git a/plugins/intsights/icon_intsights/connection/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/connection/schema.py similarity index 95% rename from plugins/intsights/icon_intsights/connection/schema.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/connection/schema.py index 108dc0d32e..0e8f3a2118 100755 --- a/plugins/intsights/icon_intsights/connection/schema.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/connection/schema.py @@ -15,7 +15,7 @@ class ConnectionSchema(insightconnect_plugin_runtime.Input): "title": "Variables", "properties": { "account_id": { - "$ref": "#/definitions/credential_secret_key", + "type": "string", "title": "Account ID", "description": "Account ID for IntSights", "order": 1 diff --git a/plugins/intsights/icon_intsights/triggers/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/triggers/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/triggers/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/triggers/__init__.py diff --git a/plugins/intsights/icon_intsights/util/__init__.py b/plugins/rapid7_intsights/icon_rapid7_intsights/util/__init__.py similarity index 100% rename from plugins/intsights/icon_intsights/util/__init__.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/util/__init__.py diff --git a/plugins/intsights/icon_intsights/util/api.py b/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py similarity index 88% rename from plugins/intsights/icon_intsights/util/api.py rename to plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py index d2694781d0..02f408d826 100644 --- a/plugins/intsights/icon_intsights/util/api.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py @@ -10,16 +10,16 @@ @dataclass class AlertParams: - alert_type: str - severity: str - source_type: str - network_type: str + alert_type: [str] + severity: [str] + source_type: [str] + network_type: [str] matched_asset_value: str - remediation_status: str - source_date_from: int - source_date_to: int - found_date_from: int - found_date_to: int + remediation_status: [str] + source_date_from: str + source_date_to: str + found_date_from: str + found_date_to: str assigned: bool is_flagged: bool is_closed: bool @@ -28,17 +28,17 @@ class AlertParams: def to_dict(self) -> dict: return clean( { - "alertType": self.alert_type, - "severity": self.severity, - "sourceType": self.source_type, - "networkType": self.network_type, + "alertType": ','.join(self.alert_type), + "severity": ','.join(self.severity), + "sourceType": ','.join(self.source_type), + "networkType": ','.join(self.network_type), "matchedAssetValue": self.matched_asset_value, - "remediationStatus": self.remediation_status, - "sourceDateFrom": self.source_date_from, - "sourceDateTo": self.source_date_to, - "foundDateFrom": self.found_date_from, - "foundDateTo": self.found_date_to, - "assigned": self.assigned, + "remediationStatus": ','.join(self.remediation_status), + "sourceDateFrom": int(self.source_date_from), + "sourceDateTo": int(self.source_date_to), + "foundDateFrom": int(self.found_date_from), + "foundDateTo": int(self.found_date_to), + "assigned": self.assigned == "Assigned", "isFlagged": self.is_flagged, "isClosed": self.is_closed, "hasIoc": self.has_ioc, diff --git a/plugins/intsights/plugin.spec.yaml b/plugins/rapid7_intsights/plugin.spec.yaml similarity index 99% rename from plugins/intsights/plugin.spec.yaml rename to plugins/rapid7_intsights/plugin.spec.yaml index a98b8122d4..d6c43a48a0 100644 --- a/plugins/intsights/plugin.spec.yaml +++ b/plugins/rapid7_intsights/plugin.spec.yaml @@ -1,8 +1,8 @@ plugin_spec_version: v2 extension: plugin products: [insightconnect] -name: intsights -title: IntSights +name: rapid7_intsights +title: Rapid7 IntSights description: Rapid7 IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy version: 1.0.0 supported_versions: ["2.4.0"] @@ -10,10 +10,11 @@ vendor: rapid7 support: rapid7 status: [] resources: - source_url: https://github.com/rapid7/insightconnect-plugins/tree/master/plugins/intsights + source_url: https://github.com/rapid7/insightconnect-plugins/tree/master/plugins/rapid7_intsights license_url: https://github.com/rapid7/insightconnect-plugins/blob/master/LICENSE vendor_url: https://intsights.com/ tags: +- rapid7 - intsights - darkweb - threatintelligence diff --git a/plugins/intsights/requirements.txt b/plugins/rapid7_intsights/requirements.txt similarity index 100% rename from plugins/intsights/requirements.txt rename to plugins/rapid7_intsights/requirements.txt diff --git a/plugins/intsights/setup.py b/plugins/rapid7_intsights/setup.py similarity index 87% rename from plugins/intsights/setup.py rename to plugins/rapid7_intsights/setup.py index 7b86ddf48e..0c32bb5951 100755 --- a/plugins/intsights/setup.py +++ b/plugins/rapid7_intsights/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages -setup(name="intsights-rapid7-plugin", +setup(name="rapid7_intsights-rapid7-plugin", version="1.0.0", description="Rapid7 IntSights is disrupting external threat intelligence with a combination of human and automated collection, intelligent analysis, and strategic threat hunting that turns the clear, deep, and dark webs into an intelligence resource that any company can deploy", author="rapid7", @@ -10,5 +10,5 @@ url="", packages=find_packages(), install_requires=['insightconnect-plugin-runtime'], # Add third-party dependencies to requirements.txt, not here! - scripts=['bin/icon_intsights'] + scripts=['bin/icon_rapid7_intsights'] ) diff --git a/plugins/intsights/unit_test/__init__.py b/plugins/rapid7_intsights/unit_test/__init__.py similarity index 100% rename from plugins/intsights/unit_test/__init__.py rename to plugins/rapid7_intsights/unit_test/__init__.py diff --git a/plugins/intsights/unit_test/payloads/add_manual_alert.json.resp b/plugins/rapid7_intsights/unit_test/payloads/add_manual_alert.json.resp similarity index 100% rename from plugins/intsights/unit_test/payloads/add_manual_alert.json.resp rename to plugins/rapid7_intsights/unit_test/payloads/add_manual_alert.json.resp diff --git a/plugins/intsights/unit_test/payloads/enrich_indicator-in_progress.json.resp b/plugins/rapid7_intsights/unit_test/payloads/enrich_indicator-in_progress.json.resp similarity index 100% rename from plugins/intsights/unit_test/payloads/enrich_indicator-in_progress.json.resp rename to plugins/rapid7_intsights/unit_test/payloads/enrich_indicator-in_progress.json.resp diff --git a/plugins/intsights/unit_test/payloads/enrich_indicator.json.resp b/plugins/rapid7_intsights/unit_test/payloads/enrich_indicator.json.resp similarity index 100% rename from plugins/intsights/unit_test/payloads/enrich_indicator.json.resp rename to plugins/rapid7_intsights/unit_test/payloads/enrich_indicator.json.resp diff --git a/plugins/intsights/unit_test/payloads/get_alerts.json.resp b/plugins/rapid7_intsights/unit_test/payloads/get_alerts.json.resp similarity index 100% rename from plugins/intsights/unit_test/payloads/get_alerts.json.resp rename to plugins/rapid7_intsights/unit_test/payloads/get_alerts.json.resp diff --git a/plugins/intsights/unit_test/payloads/get_alerts_empty_list.json.resp b/plugins/rapid7_intsights/unit_test/payloads/get_alerts_empty_list.json.resp similarity index 100% rename from plugins/intsights/unit_test/payloads/get_alerts_empty_list.json.resp rename to plugins/rapid7_intsights/unit_test/payloads/get_alerts_empty_list.json.resp diff --git a/plugins/intsights/unit_test/payloads/get_complete_alert_by_id.json.resp b/plugins/rapid7_intsights/unit_test/payloads/get_complete_alert_by_id.json.resp similarity index 100% rename from plugins/intsights/unit_test/payloads/get_complete_alert_by_id.json.resp rename to plugins/rapid7_intsights/unit_test/payloads/get_complete_alert_by_id.json.resp diff --git a/plugins/intsights/unit_test/payloads/get_indicator_scan_status.bad.json.resp b/plugins/rapid7_intsights/unit_test/payloads/get_indicator_scan_status.bad.json.resp similarity index 100% rename from plugins/intsights/unit_test/payloads/get_indicator_scan_status.bad.json.resp rename to plugins/rapid7_intsights/unit_test/payloads/get_indicator_scan_status.bad.json.resp diff --git a/plugins/intsights/unit_test/payloads/get_indicator_scan_status.json.resp b/plugins/rapid7_intsights/unit_test/payloads/get_indicator_scan_status.json.resp similarity index 100% rename from plugins/intsights/unit_test/payloads/get_indicator_scan_status.json.resp rename to plugins/rapid7_intsights/unit_test/payloads/get_indicator_scan_status.json.resp diff --git a/plugins/intsights/unit_test/payloads/iocs_ioc-by-value.json.resp b/plugins/rapid7_intsights/unit_test/payloads/iocs_ioc-by-value.json.resp similarity index 100% rename from plugins/intsights/unit_test/payloads/iocs_ioc-by-value.json.resp rename to plugins/rapid7_intsights/unit_test/payloads/iocs_ioc-by-value.json.resp diff --git a/plugins/intsights/unit_test/payloads/rescan_indicator.bad.json.resp b/plugins/rapid7_intsights/unit_test/payloads/rescan_indicator.bad.json.resp similarity index 100% rename from plugins/intsights/unit_test/payloads/rescan_indicator.bad.json.resp rename to plugins/rapid7_intsights/unit_test/payloads/rescan_indicator.bad.json.resp diff --git a/plugins/intsights/unit_test/payloads/rescan_indicator.json.resp b/plugins/rapid7_intsights/unit_test/payloads/rescan_indicator.json.resp similarity index 100% rename from plugins/intsights/unit_test/payloads/rescan_indicator.json.resp rename to plugins/rapid7_intsights/unit_test/payloads/rescan_indicator.json.resp diff --git a/plugins/intsights/unit_test/test_add_manual_alert.py b/plugins/rapid7_intsights/unit_test/test_add_manual_alert.py similarity index 94% rename from plugins/intsights/unit_test/test_add_manual_alert.py rename to plugins/rapid7_intsights/unit_test/test_add_manual_alert.py index 4513735d89..32facab3c5 100644 --- a/plugins/intsights/unit_test/test_add_manual_alert.py +++ b/plugins/rapid7_intsights/unit_test/test_add_manual_alert.py @@ -6,8 +6,8 @@ from unittest import TestCase from unittest.mock import patch from unit_test.util import Util -from icon_intsights.actions.add_manual_alert import AddManualAlert -from icon_intsights.actions.add_manual_alert.schema import Input +from icon_rapid7_intsights.actions.add_manual_alert import AddManualAlert +from icon_rapid7_intsights.actions.add_manual_alert.schema import Input from insightconnect_plugin_runtime.exceptions import PluginException diff --git a/plugins/intsights/unit_test/test_connection.py b/plugins/rapid7_intsights/unit_test/test_connection.py similarity index 92% rename from plugins/intsights/unit_test/test_connection.py rename to plugins/rapid7_intsights/unit_test/test_connection.py index 6e60db251f..959741e3d3 100644 --- a/plugins/intsights/unit_test/test_connection.py +++ b/plugins/rapid7_intsights/unit_test/test_connection.py @@ -6,8 +6,8 @@ from unittest import TestCase from unittest.mock import patch from unit_test.util import Util -from icon_intsights.actions.get_indicator_by_value.action import GetIndicatorByValue -from icon_intsights.connection.schema import Input +from icon_rapid7_intsights.actions.get_indicator_by_value.action import GetIndicatorByValue +from icon_rapid7_intsights.connection.schema import Input from insightconnect_plugin_runtime.exceptions import ConnectionTestException diff --git a/plugins/intsights/unit_test/test_enrich_indicator.py b/plugins/rapid7_intsights/unit_test/test_enrich_indicator.py similarity index 89% rename from plugins/intsights/unit_test/test_enrich_indicator.py rename to plugins/rapid7_intsights/unit_test/test_enrich_indicator.py index 78e74e7b74..22473fc293 100644 --- a/plugins/intsights/unit_test/test_enrich_indicator.py +++ b/plugins/rapid7_intsights/unit_test/test_enrich_indicator.py @@ -7,8 +7,8 @@ from unittest import TestCase from unittest.mock import patch from unit_test.util import Util -from icon_intsights.actions.enrich_indicator import EnrichIndicator -from icon_intsights.actions.enrich_indicator.schema import Input +from icon_rapid7_intsights.actions.enrich_indicator import EnrichIndicator +from icon_rapid7_intsights.actions.enrich_indicator.schema import Input class TestEnrichIndicator(TestCase): diff --git a/plugins/intsights/unit_test/test_get_alerts.py b/plugins/rapid7_intsights/unit_test/test_get_alerts.py similarity index 92% rename from plugins/intsights/unit_test/test_get_alerts.py rename to plugins/rapid7_intsights/unit_test/test_get_alerts.py index ff8fb7dfc0..4f5650010c 100644 --- a/plugins/intsights/unit_test/test_get_alerts.py +++ b/plugins/rapid7_intsights/unit_test/test_get_alerts.py @@ -6,8 +6,8 @@ from unittest import TestCase from unittest.mock import patch from unit_test.util import Util -from icon_intsights.actions.get_alerts import GetAlerts -from icon_intsights.actions.get_alerts.schema import Input +from icon_rapid7_intsights.actions.get_alerts import GetAlerts +from icon_rapid7_intsights.actions.get_alerts.schema import Input class TestAddManualAlert(TestCase): diff --git a/plugins/intsights/unit_test/test_get_complete_alert_by_id.py b/plugins/rapid7_intsights/unit_test/test_get_complete_alert_by_id.py similarity index 89% rename from plugins/intsights/unit_test/test_get_complete_alert_by_id.py rename to plugins/rapid7_intsights/unit_test/test_get_complete_alert_by_id.py index 39348e555c..da4e952999 100644 --- a/plugins/intsights/unit_test/test_get_complete_alert_by_id.py +++ b/plugins/rapid7_intsights/unit_test/test_get_complete_alert_by_id.py @@ -6,8 +6,8 @@ from unittest import TestCase from unittest.mock import patch from unit_test.util import Util -from icon_intsights.actions.get_complete_alert_by_id import GetCompleteAlertById -from icon_intsights.actions.get_complete_alert_by_id.schema import Input +from icon_rapid7_intsights.actions.get_complete_alert_by_id import GetCompleteAlertById +from icon_rapid7_intsights.actions.get_complete_alert_by_id.schema import Input class TestAddManualAlert(TestCase): diff --git a/plugins/intsights/unit_test/test_get_indicator_by_value.py b/plugins/rapid7_intsights/unit_test/test_get_indicator_by_value.py similarity index 92% rename from plugins/intsights/unit_test/test_get_indicator_by_value.py rename to plugins/rapid7_intsights/unit_test/test_get_indicator_by_value.py index 85205f0550..a52727c900 100644 --- a/plugins/intsights/unit_test/test_get_indicator_by_value.py +++ b/plugins/rapid7_intsights/unit_test/test_get_indicator_by_value.py @@ -6,8 +6,8 @@ from unittest import TestCase from unittest.mock import patch from unit_test.util import Util -from icon_intsights.actions.get_indicator_by_value import GetIndicatorByValue -from icon_intsights.actions.get_indicator_by_value.schema import Input +from icon_rapid7_intsights.actions.get_indicator_by_value import GetIndicatorByValue +from icon_rapid7_intsights.actions.get_indicator_by_value.schema import Input class TestGetIndicatorByValue(TestCase): diff --git a/plugins/intsights/unit_test/test_get_indicator_scan_status.py b/plugins/rapid7_intsights/unit_test/test_get_indicator_scan_status.py similarity index 87% rename from plugins/intsights/unit_test/test_get_indicator_scan_status.py rename to plugins/rapid7_intsights/unit_test/test_get_indicator_scan_status.py index f97330aeb0..c110383570 100644 --- a/plugins/intsights/unit_test/test_get_indicator_scan_status.py +++ b/plugins/rapid7_intsights/unit_test/test_get_indicator_scan_status.py @@ -6,8 +6,8 @@ from unittest import TestCase from unittest.mock import patch from unit_test.util import Util -from icon_intsights.actions.get_indicator_scan_status import GetIndicatorScanStatus -from icon_intsights.actions.get_indicator_scan_status.schema import Input +from icon_rapid7_intsights.actions.get_indicator_scan_status import GetIndicatorScanStatus +from icon_rapid7_intsights.actions.get_indicator_scan_status.schema import Input from insightconnect_plugin_runtime.exceptions import PluginException diff --git a/plugins/intsights/unit_test/test_rescan_indicator.py b/plugins/rapid7_intsights/unit_test/test_rescan_indicator.py similarity index 89% rename from plugins/intsights/unit_test/test_rescan_indicator.py rename to plugins/rapid7_intsights/unit_test/test_rescan_indicator.py index 2036d89f2a..a3cb083db6 100644 --- a/plugins/intsights/unit_test/test_rescan_indicator.py +++ b/plugins/rapid7_intsights/unit_test/test_rescan_indicator.py @@ -6,8 +6,8 @@ from unittest import TestCase from unittest.mock import patch from unit_test.util import Util -from icon_intsights.actions.rescan_indicator import RescanIndicator -from icon_intsights.actions.rescan_indicator.schema import Input +from icon_rapid7_intsights.actions.rescan_indicator import RescanIndicator +from icon_rapid7_intsights.actions.rescan_indicator.schema import Input from insightconnect_plugin_runtime.exceptions import PluginException diff --git a/plugins/intsights/unit_test/util.py b/plugins/rapid7_intsights/unit_test/util.py similarity index 97% rename from plugins/intsights/unit_test/util.py rename to plugins/rapid7_intsights/unit_test/util.py index 90c922f641..1ab72b2085 100644 --- a/plugins/intsights/unit_test/util.py +++ b/plugins/rapid7_intsights/unit_test/util.py @@ -1,8 +1,8 @@ import json import logging -from icon_intsights.connection import Connection -from icon_intsights.connection.schema import Input +from icon_rapid7_intsights.connection import Connection +from icon_rapid7_intsights.connection.schema import Input class Util: From 18679ef38ea6ab7b18ba8faae285c541c3c9f6a4 Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Tue, 26 Oct 2021 00:24:46 +0200 Subject: [PATCH 48/60] [MC-683] Change plugin name to rapid7_intsights --- plugins/rapid7_intsights/help.md | 37 ++++--- .../icon_rapid7_intsights/util/api.py | 12 +- plugins/rapid7_intsights/plugin.spec.yaml | 103 ++++++------------ 3 files changed, 59 insertions(+), 93 deletions(-) diff --git a/plugins/rapid7_intsights/help.md b/plugins/rapid7_intsights/help.md index a6524a1113..a896d11629 100644 --- a/plugins/rapid7_intsights/help.md +++ b/plugins/rapid7_intsights/help.md @@ -72,7 +72,10 @@ Example input: { "description": "Suspicious addresses", "found_date": "2020-01-01", - "images": "[{\"Type\": \"jpeg\",\"Data\": \"UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==\"}]", + "images": [{ + "Type": "jpeg", + "Data": "UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==" + }], "severity": "Medium", "source_date": "2020-02-01", "source_network_type": "DarkWeb", @@ -200,7 +203,7 @@ This action is used to force an indicator scan in Intsights TIP system. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_file_hash|string|None|True|IOC value in type file hash|None|30f800f97aeaa8d62bdf3a6fb2b0681179a360c12e127f07038f8521461e5050| +|indicator_file_hash|string|None|True|IOC value in type file hash|None|275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f| Example input: @@ -268,20 +271,20 @@ This action is used to search Alerts based on criteria. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|alert_type|[]string|None|False|Comma-separated list of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip|None|Phishing| -|assigned|boolean|None|False|Show assigned/unassigned alerts|None|True| -|found_date_from|number|None|False|Start date to fetch from in Unix Millisecond Timestamp|None|0| -|found_date_to|number|None|False|End date to fetch to in Unix Millisecond Timestamp|None|1633047102456| +|alert_type|[]string|None|False|List of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip|None|["Phishing"]| +|assigned|string|None|False|Show assigned/unassigned alerts|['Assigned', 'Unassigned']|Assigned| +|found_date_from|string|None|False|Start date to fetch from in Unix Millisecond Timestamp|None|0| +|found_date_to|string|None|False|End date to fetch to in Unix Millisecond Timestamp|None|1633047102456| |has_indicators|boolean|None|False|Show alerts with IOCs results|None|False| -|is_closed|boolean|None|False|Is closed/open alerts|None|False| -|is_flagged|boolean|None|False|Show flagged/unflagged alerts|None|True| -|matched_asset_value|string|None|False|Comma-separated list|None|https://example.com| -|network_type|string|None|False|Comma-separated list of network type. Allowed values: ClearWeb, DarkWeb|['ClearWeb', 'DarkWeb']|DarkWeb| -|remediation_status|string|None|False|Comma-separated list of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed|None|InProgress, Pending| -|severity|string|None|False|Comma-separated list of alerts severity. Allowed values: High, Medium, Low|['High', 'Medium', 'Low']|Low| -|source_date_from|number|None|False|Start date to fetch from in Unix Millisecond Timestamp|None|1633047083142| -|source_date_to|number|None|False|End date to fetch to in Unix Millisecond Timestamp|None|1633047102456| -|source_type|string|None|False|Comma-separated list of alerts source type. Allowed values: ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others|['Application Store', 'Cyber Security Blog', 'Hacking News', 'Cyber Crime Forum', 'Hacktivism Forum', 'Social Media', 'Facebook', 'Twitter', 'LinkedIn', 'Google Plus', 'VK', 'Vimeo', 'YouTube', 'IRC Channel', 'IOC Block List', 'Credit Card Black Market', 'Paste Site', 'Data Leakage Website', 'Leaked Database', 'File Sharing Website', 'Gray Hat Website', 'Black Market', 'WHOIS servers', 'Company Website', 'Wikileaks', 'Pinterest', 'Tumblr', 'Instagram', 'Telegram', 'Webmail', 'Malware Analysis', 'Firehol', 'VRA', 'Other']|Application Store| +|is_closed|boolean|None|False|Status of the alert, either closed or open|['Closed', 'Open']|Closed| +|is_flagged|string|None|False|Show flagged/unflagged alerts|['Flagged', 'Unflagged']|Flagged| +|matched_asset_value|[]string|None|False|List of matched asset values|None|["example.com"]| +|network_type|[]string|None|False|List of network type. Allowed values: ClearWeb, DarkWeb|None|["DarkWeb"]| +|remediation_status|[]string|None|False|List of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed|None|["InProgress", "Pending"]| +|severity|[]string|None|False|List of alerts severity. Allowed values: High, Medium, Low|None|["Low"]| +|source_date_from|string|None|False|Start date to fetch from in Unix Millisecond Timestamp|None|1633047083142| +|source_date_to|string|None|False|End date to fetch to in Unix Millisecond Timestamp|None|1633047102456| +|source_type|[]string|None|False|List of alerts source type. Allowed values: Application Store, Cyber Security Blog, Hacking News, Cyber Crime Forum, Hacktivism Forum, Social Media, Facebook, Twitter, LinkedIn, Google Plus, VK, Vimeo, YouTube, IRC Channel, IOC Block List, Credit Card Black Market, Paste Site, Data Leakage Website, Leaked Database, File Sharing Website, Gray Hat Website, Black Market, WHOIS servers, Company Website, Wikileaks, Pinterest, Tumblr, Instagram, Telegram, Webmail, Malware Analysis, Firehol, VRA, Other|None|["Application Store"]| Example input: @@ -329,7 +332,7 @@ This action is used to submit an indicator to IntSights for investigation and re |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_value|string|None|True|Value of the indicator|None|https://example.com| +|indicator_value|string|None|True|Value of the indicator|None|example.com| Example input: @@ -558,7 +561,7 @@ This action will search indicators in IntSights TIP. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_value|string|None|True|Value of the indicator|None|https://example.com| +|indicator_value|string|None|True|Value of the indicator|None|example.com| Example input: diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py b/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py index 02f408d826..38df4b3af7 100644 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py @@ -20,9 +20,9 @@ class AlertParams: source_date_to: str found_date_from: str found_date_to: str - assigned: bool - is_flagged: bool - is_closed: bool + assigned: str + is_flagged: str + is_closed: str has_ioc: bool def to_dict(self) -> dict: @@ -32,15 +32,15 @@ def to_dict(self) -> dict: "severity": ','.join(self.severity), "sourceType": ','.join(self.source_type), "networkType": ','.join(self.network_type), - "matchedAssetValue": self.matched_asset_value, + "matchedAssetValue": ','.join(self.matched_asset_value), "remediationStatus": ','.join(self.remediation_status), "sourceDateFrom": int(self.source_date_from), "sourceDateTo": int(self.source_date_to), "foundDateFrom": int(self.found_date_from), "foundDateTo": int(self.found_date_to), "assigned": self.assigned == "Assigned", - "isFlagged": self.is_flagged, - "isClosed": self.is_closed, + "isFlagged": self.is_flagged == "Flagged", + "isClosed": self.is_closed == "Closed", "hasIoc": self.has_ioc, } ) diff --git a/plugins/rapid7_intsights/plugin.spec.yaml b/plugins/rapid7_intsights/plugin.spec.yaml index 79e2c5eee1..23d66d7310 100644 --- a/plugins/rapid7_intsights/plugin.spec.yaml +++ b/plugins/rapid7_intsights/plugin.spec.yaml @@ -49,7 +49,7 @@ connection: account_id: title: Account ID description: Account ID for IntSights - type: credential_secret_key + type: string required: true example: 9de5069c5afe602b2ea0a04b api_key: @@ -71,8 +71,8 @@ actions: example: example.com output: value: - title: Value - description: Value + title: Indicator Value + description: Indicator value type: string required: false type: @@ -219,86 +219,40 @@ actions: input: alert_type: title: Alert Type - description: 'Comma-separated list of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip' - type: string + description: 'List of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip' + type: '[]string' required: false - enum: - - AttackIndication - - DataLeakage - - Phishing - - BrandSecurity - - ExploitableData - - vip - example: Phishing + example: ["Phishing"] severity: title: Severity - description: 'Comma-separated list of alerts severity. Allowed values: High, Medium, Low' - type: string + description: 'List of alerts severity. Allowed values: High, Medium, Low' + type: '[]string' required: false - enum: - - High - - Medium - - Low - example: Low + example: ["Low"] source_type: title: Source Type - description: 'Comma-separated list of alerts source type. Allowed values: ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others' - type: string + description: 'List of alerts source type. Allowed values: Application Store, Cyber Security Blog, Hacking News, Cyber Crime Forum, Hacktivism Forum, Social Media, Facebook, Twitter, LinkedIn, Google Plus, VK, Vimeo, YouTube, IRC Channel, IOC Block List, Credit Card Black Market, Paste Site, Data Leakage Website, Leaked Database, File Sharing Website, Gray Hat Website, Black Market, WHOIS servers, Company Website, Wikileaks, Pinterest, Tumblr, Instagram, Telegram, Webmail, Malware Analysis, Firehol, VRA, Other' + type: '[]string' required: false - enum: - - Application Store - - Cyber Security Blog - - Hacking News - - Cyber Crime Forum - - Hacktivism Forum - - Social Media - - Facebook - - Twitter - - LinkedIn - - Google Plus - - VK - - Vimeo - - YouTube - - IRC Channel - - IOC Block List - - Credit Card Black Market - - Paste Site - - Data Leakage Website - - Leaked Database - - File Sharing Website - - Gray Hat Website - - Black Market - - WHOIS servers - - Company Website - - Wikileaks - - Pinterest - - Tumblr - - Instagram - - Telegram - - Webmail - - Malware Analysis - - Firehol - - VRA - - Other - example: Application Store + example: ["Application Store"] network_type: title: Network Type - description: 'Comma-separated list of network type. Allowed values: ClearWeb, DarkWeb' - type: string + description: 'List of network type. Allowed values: ClearWeb, DarkWeb' + type: '[]string' required: false - example: DarkWeb + example: ["DarkWeb"] matched_asset_value: title: Matched Asset Value - description: Comma-separated list - type: string + description: List of matched asset values + type: '[]string' required: false - example: example.com + example: ["example.com"] remediation_status: title: Remediation Status - description: 'Comma-separated list of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed' - type: string + description: 'List of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed' + type: '[]string' required: false - example: InProgress, Pending + example: ["InProgress", "Pending"] source_date_from: title: Source Date From description: Start date to fetch from in Unix Millisecond Timestamp @@ -328,19 +282,28 @@ actions: description: Show assigned/unassigned alerts type: string required: false - example: true + example: Assigned + enum: + - Assigned + - Unassigned is_flagged: title: Alert Flag Status description: Show flagged/unflagged alerts type: string required: false - example: true + example: Flagged + enum: + - Flagged + - Unflagged is_closed: title: Closed Status description: Status of the alert, either closed or open type: boolean required: false - example: false + example: Closed + enum: + - Closed + - Open has_indicators: title: Has Indicators description: Show alerts with IOCs results From 4ce19042d3843b7de000d242db55d84664c0f04d Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Tue, 26 Oct 2021 00:54:51 +0200 Subject: [PATCH 49/60] [MC-683] Fix unit tests --- plugins/rapid7_intsights/.CHECKSUM | 6 +- plugins/rapid7_intsights/help.md | 37 ++++-- .../actions/get_alerts/schema.py | 108 ++++++++---------- .../get_complete_alert_by_id/schema.py | 5 +- .../get_indicator_scan_status/action.py | 6 +- .../icon_rapid7_intsights/util/api.py | 20 ++-- plugins/rapid7_intsights/plugin.spec.yaml | 6 +- .../get_alerts_with_types_list.json.resp | 4 + .../unit_test/test_connection.py | 4 +- .../unit_test/test_get_alerts.py | 13 ++- .../test_get_indicator_scan_status.py | 2 +- .../unit_test/test_rescan_indicator.py | 2 +- plugins/rapid7_intsights/unit_test/util.py | 5 + 13 files changed, 117 insertions(+), 101 deletions(-) create mode 100644 plugins/rapid7_intsights/unit_test/payloads/get_alerts_with_types_list.json.resp diff --git a/plugins/rapid7_intsights/.CHECKSUM b/plugins/rapid7_intsights/.CHECKSUM index 7f439bb222..4c3e1168f3 100644 --- a/plugins/rapid7_intsights/.CHECKSUM +++ b/plugins/rapid7_intsights/.CHECKSUM @@ -1,5 +1,5 @@ { - "spec": "b088c63ad80764cd577bef4c71444c1a", + "spec": "c325c9502fdf1364ed0d7a038355fb1a", "manifest": "9a1c0ed12f4a14563a7e6ee8431fcb56", "setup": "03540fca0745c2f43e81830a80d402bb", "schemas": [ @@ -13,11 +13,11 @@ }, { "identifier": "get_alerts/schema.py", - "hash": "e328ecc4099593ccaea2019fb603dea6" + "hash": "8bc5304d87461a5b72da0982032bb73a" }, { "identifier": "get_complete_alert_by_id/schema.py", - "hash": "b5f55ac2937665123aeb3c557ff0a180" + "hash": "2d0aced444d1c084e2e4bf94f62315ba" }, { "identifier": "get_indicator_by_value/schema.py", diff --git a/plugins/rapid7_intsights/help.md b/plugins/rapid7_intsights/help.md index a896d11629..07ce12628b 100644 --- a/plugins/rapid7_intsights/help.md +++ b/plugins/rapid7_intsights/help.md @@ -158,13 +158,13 @@ Example input: |assets|[]string|True|List of assets| |assignees|[]string|True|List of assignees| |details|object|True|Alert details| -|found_date|date|True|Alert found date| +|found_date|date|False|Alert found date| |id|string|True|Alert ID| |is_closed|boolean|True|Is alert closed| |is_flagged|boolean|True|Is alert flagged| |leak_name|string|False|Name of the leak DBs in data leakage alerts| -|takedown_status|string|True|Alert remediation status| -|update_date|date|True|Alert update date| +|takedown_status|string|False|Alert remediation status| +|update_date|date|False|Alert update date| Example output: @@ -290,20 +290,33 @@ Example input: ``` { - "alert_type": "Phishing", - "assigned": true, + "alert_type": [ + "Phishing" + ], + "assigned": "Assigned", "found_date_from": 0, "found_date_to": 1633047102456, "has_indicators": false, - "is_closed": false, - "is_flagged": true, - "matched_asset_value": "example.com", - "network_type": "DarkWeb", - "remediation_status": "InProgress, Pending", - "severity": "Low", + "is_closed": "Closed", + "is_flagged": "Flagged", + "matched_asset_value": [ + "example.com" + ], + "network_type": [ + "DarkWeb" + ], + "remediation_status": [ + "InProgress", + "Pending" + ], + "severity": [ + "Low" + ], "source_date_from": 1633047083142, "source_date_to": 1633047102456, - "source_type": "Application Store" + "source_type": [ + "Application Store" + ] } ``` diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_alerts/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_alerts/schema.py index e9eeb3e866..1c4adc3e14 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_alerts/schema.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_alerts/schema.py @@ -37,26 +37,30 @@ class GetAlertsInput(insightconnect_plugin_runtime.Input): "alert_type": { "type": "array", "title": "Alert Type", - "description": "Comma-separated list of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip", + "description": "List of alert types. Allowed values: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, vip", "items": { "type": "string" }, "order": 1 }, "assigned": { - "type": "boolean", + "type": "string", "title": "Alert Assignment", "description": "Show assigned/unassigned alerts", + "enum": [ + "Assigned", + "Unassigned" + ], "order": 11 }, "found_date_from": { - "type": "number", + "type": "string", "title": "Found Date From", "description": "Start date to fetch from in Unix Millisecond Timestamp", "order": 9 }, "found_date_to": { - "type": "number", + "type": "string", "title": "Found Date To", "description": "End date to fetch to in Unix Millisecond Timestamp", "order": 10 @@ -70,100 +74,78 @@ class GetAlertsInput(insightconnect_plugin_runtime.Input): "is_closed": { "type": "boolean", "title": "Closed Status", - "description": "Is closed/open alerts", + "description": "Status of the alert, either closed or open", + "enum": [ + "Closed", + "Open" + ], "order": 13 }, "is_flagged": { - "type": "boolean", + "type": "string", "title": "Alert Flag Status", "description": "Show flagged/unflagged alerts", + "enum": [ + "Flagged", + "Unflagged" + ], "order": 12 }, "matched_asset_value": { - "type": "string", + "type": "array", "title": "Matched Asset Value", - "description": "Comma-separated list", + "description": "List of matched asset values", + "items": { + "type": "string" + }, "order": 5 }, "network_type": { - "type": "string", + "type": "array", "title": "Network Type", - "description": "Comma-separated list of network type. Allowed values: ClearWeb, DarkWeb", - "enum": [ - "ClearWeb", - "DarkWeb" - ], + "description": "List of network type. Allowed values: ClearWeb, DarkWeb", + "items": { + "type": "string" + }, "order": 4 }, "remediation_status": { - "type": "string", + "type": "array", "title": "Remediation Status", - "description": "Comma-separated list of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed", + "description": "List of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed", + "items": { + "type": "string" + }, "order": 6 }, "severity": { - "type": "string", + "type": "array", "title": "Severity", - "description": "Comma-separated list of alerts severity. Allowed values: High, Medium, Low", - "enum": [ - "High", - "Medium", - "Low" - ], + "description": "List of alerts severity. Allowed values: High, Medium, Low", + "items": { + "type": "string" + }, "order": 2 }, "source_date_from": { - "type": "number", + "type": "string", "title": "Source Date From", "description": "Start date to fetch from in Unix Millisecond Timestamp", "order": 7 }, "source_date_to": { - "type": "number", + "type": "string", "title": "Source Date To", "description": "End date to fetch to in Unix Millisecond Timestamp", "order": 8 }, "source_type": { - "type": "string", + "type": "array", "title": "Source Type", - "description": "Comma-separated list of alerts source type. Allowed values: ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others", - "enum": [ - "Application Store", - "Cyber Security Blog", - "Hacking News", - "Cyber Crime Forum", - "Hacktivism Forum", - "Social Media", - "Facebook", - "Twitter", - "LinkedIn", - "Google Plus", - "VK", - "Vimeo", - "YouTube", - "IRC Channel", - "IOC Block List", - "Credit Card Black Market", - "Paste Site", - "Data Leakage Website", - "Leaked Database", - "File Sharing Website", - "Gray Hat Website", - "Black Market", - "WHOIS servers", - "Company Website", - "Wikileaks", - "Pinterest", - "Tumblr", - "Instagram", - "Telegram", - "Webmail", - "Malware Analysis", - "Firehol", - "VRA", - "Other" - ], + "description": "List of alerts source type. Allowed values: Application Store, Cyber Security Blog, Hacking News, Cyber Crime Forum, Hacktivism Forum, Social Media, Facebook, Twitter, LinkedIn, Google Plus, VK, Vimeo, YouTube, IRC Channel, IOC Block List, Credit Card Black Market, Paste Site, Data Leakage Website, Leaked Database, File Sharing Website, Gray Hat Website, Black Market, WHOIS servers, Company Website, Wikileaks, Pinterest, Tumblr, Instagram, Telegram, Webmail, Malware Analysis, Firehol, VRA, Other", + "items": { + "type": "string" + }, "order": 3 } } diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py index b0e5ce1809..3c70a0af75 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py @@ -128,12 +128,9 @@ class GetCompleteAlertByIdOutput(insightconnect_plugin_runtime.Output): "assets", "assignees", "details", - "found_date", "id", "is_closed", - "is_flagged", - "takedown_status", - "update_date" + "is_flagged" ] } """) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/action.py index 3650030dce..b28ce953cb 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/action.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/action.py @@ -2,6 +2,7 @@ from .schema import GetIndicatorScanStatusInput, GetIndicatorScanStatusOutput, Input, Output, Component # Custom imports below +from insightconnect_plugin_runtime.helper import clean class GetIndicatorScanStatus(insightconnect_plugin_runtime.Action): @@ -15,4 +16,7 @@ def __init__(self): def run(self, params={}): response = self.connection.client.get_scan_status(params.get(Input.TASK_ID)) - return {Output.TASK_ID: response.get("TaskId"), Output.STATUS: response.get("Status")} + return clean({ + Output.TASK_ID: response.get("TaskId"), + Output.STATUS: response.get("Status") + }) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py b/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py index 38df4b3af7..546aba3f11 100644 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py @@ -28,16 +28,16 @@ class AlertParams: def to_dict(self) -> dict: return clean( { - "alertType": ','.join(self.alert_type), - "severity": ','.join(self.severity), - "sourceType": ','.join(self.source_type), - "networkType": ','.join(self.network_type), - "matchedAssetValue": ','.join(self.matched_asset_value), - "remediationStatus": ','.join(self.remediation_status), - "sourceDateFrom": int(self.source_date_from), - "sourceDateTo": int(self.source_date_to), - "foundDateFrom": int(self.found_date_from), - "foundDateTo": int(self.found_date_to), + "alertType": ','.join(self.alert_type) if self.alert_type else None, + "severity": ','.join(self.severity) if self.severity else None, + "sourceType": ','.join(self.source_type) if self.source_type else None, + "networkType": ','.join(self.network_type) if self.network_type else None, + "matchedAssetValue": ','.join(self.matched_asset_value) if self.matched_asset_value else None, + "remediationStatus": ','.join(self.remediation_status) if self.remediation_status else None, + "sourceDateFrom": int(self.source_date_from) if self.source_date_from else None, + "sourceDateTo": int(self.source_date_to) if self.source_date_to else None, + "foundDateFrom": int(self.found_date_from) if self.found_date_from else None, + "foundDateTo": int(self.found_date_to) if self.found_date_to else None, "assigned": self.assigned == "Assigned", "isFlagged": self.is_flagged == "Flagged", "isClosed": self.is_closed == "Closed", diff --git a/plugins/rapid7_intsights/plugin.spec.yaml b/plugins/rapid7_intsights/plugin.spec.yaml index 23d66d7310..30fb86181a 100644 --- a/plugins/rapid7_intsights/plugin.spec.yaml +++ b/plugins/rapid7_intsights/plugin.spec.yaml @@ -351,17 +351,17 @@ actions: title: Found Date description: Alert found date type: date - required: true + required: false update_date: title: Found Date description: Alert update date type: date - required: true + required: false takedown_status: title: Takedown Status description: Alert remediation status type: string - required: true + required: false is_closed: title: Is Closed description: Is alert closed diff --git a/plugins/rapid7_intsights/unit_test/payloads/get_alerts_with_types_list.json.resp b/plugins/rapid7_intsights/unit_test/payloads/get_alerts_with_types_list.json.resp new file mode 100644 index 0000000000..215ee3bc76 --- /dev/null +++ b/plugins/rapid7_intsights/unit_test/payloads/get_alerts_with_types_list.json.resp @@ -0,0 +1,4 @@ +[ + "7cafac7ec5adaebf62257a4a", + "7cafac7ec5adaebf62257a4b" +] \ No newline at end of file diff --git a/plugins/rapid7_intsights/unit_test/test_connection.py b/plugins/rapid7_intsights/unit_test/test_connection.py index 959741e3d3..0398579048 100644 --- a/plugins/rapid7_intsights/unit_test/test_connection.py +++ b/plugins/rapid7_intsights/unit_test/test_connection.py @@ -21,7 +21,7 @@ def test_connection_should_success_when_good_credentials(self, mock_request) -> def test_connection_should_success_when_credentials(self, mock_request) -> None: action = Util.default_connector( GetIndicatorByValue(), - {Input.API_KEY: {"secretKey": "api_key"}, Input.ACCOUNT_ID: {"secretKey": "account_id"}}, + {Input.API_KEY: {"secretKey": "api_key"}, Input.ACCOUNT_ID: "account_id"}, ) self.assertEqual("https://api.intsights.com", action.connection.client.url) @@ -31,7 +31,7 @@ def test_connection_should_success_when_credentials(self, mock_request) -> None: @patch("requests.request", side_effect=Util.mock_request) def test_connection_should_fail_when_wrong_credentials(self, mock_request) -> None: action = Util.default_connector( - GetIndicatorByValue(), {Input.API_KEY: {"secretKey": "wrong"}, Input.ACCOUNT_ID: {"secretKey": "wrong"}} + GetIndicatorByValue(), {Input.API_KEY: {"secretKey": "wrong"}, Input.ACCOUNT_ID: "wrong"} ) with self.assertRaises(ConnectionTestException) as error: action.connection.test() diff --git a/plugins/rapid7_intsights/unit_test/test_get_alerts.py b/plugins/rapid7_intsights/unit_test/test_get_alerts.py index 4f5650010c..158c8aa7b2 100644 --- a/plugins/rapid7_intsights/unit_test/test_get_alerts.py +++ b/plugins/rapid7_intsights/unit_test/test_get_alerts.py @@ -44,6 +44,17 @@ def test_get_alerts_success_with_params(self, make_request): @patch("requests.request", side_effect=Util.mock_request) def test_get_alerts_success_with_empty_response_list(self, make_request): - actual = self.action.run({Input.ALERT_TYPE: "Phishing"}) + actual = self.action.run({Input.ALERT_TYPE: ["Phishing"]}) expected = {"alert_ids": []} self.assertEqual(expected, actual) + + @patch("requests.request", side_effect=Util.mock_request) + def test_get_alerts_success_with_list_of_alert_types(self, make_request): + actual = self.action.run({Input.ALERT_TYPE: ["Phishing", "AttackIndication"]}) + expected = { + 'alert_ids': [ + '7cafac7ec5adaebf62257a4a', + '7cafac7ec5adaebf62257a4b' + ] + } + self.assertEqual(expected, actual) diff --git a/plugins/rapid7_intsights/unit_test/test_get_indicator_scan_status.py b/plugins/rapid7_intsights/unit_test/test_get_indicator_scan_status.py index c110383570..a1b90c89f6 100644 --- a/plugins/rapid7_intsights/unit_test/test_get_indicator_scan_status.py +++ b/plugins/rapid7_intsights/unit_test/test_get_indicator_scan_status.py @@ -28,5 +28,5 @@ def test_rescan_indicator_should_failed(self, make_request): with self.assertRaises(PluginException) as error: self.action.run({Input.TASK_ID: "bad"}) - self.assertEqual("There is an error in response.", error.exception.cause) + self.assertEqual("IntSights returned an error response: ", error.exception.cause) self.assertEqual("Invalid task id.", error.exception.assistance) diff --git a/plugins/rapid7_intsights/unit_test/test_rescan_indicator.py b/plugins/rapid7_intsights/unit_test/test_rescan_indicator.py index a3cb083db6..0c36d998e2 100644 --- a/plugins/rapid7_intsights/unit_test/test_rescan_indicator.py +++ b/plugins/rapid7_intsights/unit_test/test_rescan_indicator.py @@ -28,5 +28,5 @@ def test_rescan_indicator_should_failed(self, make_request): with self.assertRaises(PluginException) as error: self.action.run({Input.INDICATOR_FILE_HASH: "bad"}) - self.assertEqual("There is an error in response.", error.exception.cause) + self.assertEqual("IntSights returned an error response: ", error.exception.cause) self.assertEqual("Invalid IOC value. Supported IOC types: file hashes.", error.exception.assistance) diff --git a/plugins/rapid7_intsights/unit_test/util.py b/plugins/rapid7_intsights/unit_test/util.py index 1ab72b2085..46b7756da4 100644 --- a/plugins/rapid7_intsights/unit_test/util.py +++ b/plugins/rapid7_intsights/unit_test/util.py @@ -65,6 +65,11 @@ def json(self): and kwargs.get("params", {}).get("alertType") == "Phishing" ): return MockResponse(200, "get_alerts_empty_list") + elif ( + kwargs.get("url") == "https://api.intsights.com/public/v1/data/alerts/alerts-list" + and kwargs.get("params", {}).get("alertType") == "Phishing,AttackIndication" + ): + return MockResponse(200, "get_alerts_with_types_list") elif kwargs.get("url") == "https://api.intsights.com/public/v1/data/alerts/alerts-list": return MockResponse(200, "get_alerts") elif kwargs.get("url") == "https://api.intsights.com/public/v1/data/alerts/get-complete-alert/123": From 349398a3df40810c9a8597ac60cec5f252b20fee Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Tue, 26 Oct 2021 01:19:52 +0200 Subject: [PATCH 50/60] [MC-683] Fix unit tests --- plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py b/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py index 546aba3f11..193137beb7 100644 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py @@ -38,9 +38,9 @@ def to_dict(self) -> dict: "sourceDateTo": int(self.source_date_to) if self.source_date_to else None, "foundDateFrom": int(self.found_date_from) if self.found_date_from else None, "foundDateTo": int(self.found_date_to) if self.found_date_to else None, - "assigned": self.assigned == "Assigned", - "isFlagged": self.is_flagged == "Flagged", - "isClosed": self.is_closed == "Closed", + "assigned": self.assigned == "Assigned" if self.assigned else None, + "isFlagged": self.is_flagged == "Flagged" if self.is_flagged else None, + "isClosed": self.is_closed == "Closed" if self.is_closed else None, "hasIoc": self.has_ioc, } ) @@ -153,7 +153,6 @@ def make_json_request(self, method: str, path: str, json_data: dict = None, para cause="IntSights returned an error response: ", assistance=f"{json_response.get('FailedReason')}." ) - self.logger.info(f"response: {response.json()}") return json_response except json.decoder.JSONDecodeError as e: raise PluginException(preset=PluginException.Preset.INVALID_JSON, data=e) From 04d95e5425bbca43ca2b21d6525050e63d66c27f Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Tue, 26 Oct 2021 01:26:12 +0200 Subject: [PATCH 51/60] [MC-683] Add clean to enrich_indicator output --- plugins/rapid7_intsights/.CHECKSUM | 4 ++-- plugins/rapid7_intsights/help.md | 4 ++-- .../icon_rapid7_intsights/actions/enrich_indicator/action.py | 5 +++-- .../icon_rapid7_intsights/actions/enrich_indicator/schema.py | 4 +--- plugins/rapid7_intsights/plugin.spec.yaml | 4 ++-- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/plugins/rapid7_intsights/.CHECKSUM b/plugins/rapid7_intsights/.CHECKSUM index 4c3e1168f3..4f928ebc7f 100644 --- a/plugins/rapid7_intsights/.CHECKSUM +++ b/plugins/rapid7_intsights/.CHECKSUM @@ -1,5 +1,5 @@ { - "spec": "c325c9502fdf1364ed0d7a038355fb1a", + "spec": "e96e8837a5cc1cfaa801b979ffafd9c1", "manifest": "9a1c0ed12f4a14563a7e6ee8431fcb56", "setup": "03540fca0745c2f43e81830a80d402bb", "schemas": [ @@ -9,7 +9,7 @@ }, { "identifier": "enrich_indicator/schema.py", - "hash": "2f448ecb5acfe3083dbbfa71da28a785" + "hash": "d47d2fcf15a04fbdb9ec87078294d506" }, { "identifier": "get_alerts/schema.py", diff --git a/plugins/rapid7_intsights/help.md b/plugins/rapid7_intsights/help.md index 07ce12628b..c5551cd865 100644 --- a/plugins/rapid7_intsights/help.md +++ b/plugins/rapid7_intsights/help.md @@ -360,8 +360,8 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| |data|object|True|Data| -|original_value|string|True|Original value| -|status|string|True|Status| +|original_value|string|False|Original value| +|status|string|False|Status| Example output: diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py index 28468ed45e..2674bd4f6e 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py @@ -2,6 +2,7 @@ from .schema import EnrichIndicatorInput, EnrichIndicatorOutput, Input, Output, Component # Custom imports below +from insightconnect_plugin_runtime.helper import clean class EnrichIndicator(insightconnect_plugin_runtime.Action): @@ -15,8 +16,8 @@ def __init__(self): def run(self, params={}): response = self.connection.client.enrich_indicator(params.get(Input.INDICATOR_VALUE)) - return { + return clean({ Output.ORIGINAL_VALUE: response.get("OriginalValue"), Output.STATUS: response.get("Status"), Output.DATA: response.get("Data", {}), - } + }) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/schema.py index 61e77e01a4..7fe44a2716 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/schema.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/schema.py @@ -66,9 +66,7 @@ class EnrichIndicatorOutput(insightconnect_plugin_runtime.Output): } }, "required": [ - "data", - "original_value", - "status" + "data" ] } """) diff --git a/plugins/rapid7_intsights/plugin.spec.yaml b/plugins/rapid7_intsights/plugin.spec.yaml index 30fb86181a..1f52766c98 100644 --- a/plugins/rapid7_intsights/plugin.spec.yaml +++ b/plugins/rapid7_intsights/plugin.spec.yaml @@ -160,12 +160,12 @@ actions: title: Original Value description: Original value type: string - required: true + required: false status: title: Status description: Status type: string - required: true + required: false data: title: Data description: Data From a0edfa60ba2296849062f915a0b7279255be1d82 Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Tue, 26 Oct 2021 03:09:33 +0200 Subject: [PATCH 52/60] [MC-683] Add clean to enrich_indicator output --- .../actions/enrich_indicator/action.py | 12 +++++++----- .../actions/get_indicator_scan_status/action.py | 5 +---- .../icon_rapid7_intsights/util/api.py | 12 ++++++------ .../rapid7_intsights/unit_test/test_get_alerts.py | 7 +------ 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py index 2674bd4f6e..40d72ae194 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py @@ -16,8 +16,10 @@ def __init__(self): def run(self, params={}): response = self.connection.client.enrich_indicator(params.get(Input.INDICATOR_VALUE)) - return clean({ - Output.ORIGINAL_VALUE: response.get("OriginalValue"), - Output.STATUS: response.get("Status"), - Output.DATA: response.get("Data", {}), - }) + return clean( + { + Output.ORIGINAL_VALUE: response.get("OriginalValue"), + Output.STATUS: response.get("Status"), + Output.DATA: response.get("Data", {}), + } + ) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/action.py index b28ce953cb..b4738c9c46 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/action.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/action.py @@ -16,7 +16,4 @@ def __init__(self): def run(self, params={}): response = self.connection.client.get_scan_status(params.get(Input.TASK_ID)) - return clean({ - Output.TASK_ID: response.get("TaskId"), - Output.STATUS: response.get("Status") - }) + return clean({Output.TASK_ID: response.get("TaskId"), Output.STATUS: response.get("Status")}) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py b/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py index 193137beb7..a45a665144 100644 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py @@ -28,12 +28,12 @@ class AlertParams: def to_dict(self) -> dict: return clean( { - "alertType": ','.join(self.alert_type) if self.alert_type else None, - "severity": ','.join(self.severity) if self.severity else None, - "sourceType": ','.join(self.source_type) if self.source_type else None, - "networkType": ','.join(self.network_type) if self.network_type else None, - "matchedAssetValue": ','.join(self.matched_asset_value) if self.matched_asset_value else None, - "remediationStatus": ','.join(self.remediation_status) if self.remediation_status else None, + "alertType": ",".join(self.alert_type) if self.alert_type else None, + "severity": ",".join(self.severity) if self.severity else None, + "sourceType": ",".join(self.source_type) if self.source_type else None, + "networkType": ",".join(self.network_type) if self.network_type else None, + "matchedAssetValue": ",".join(self.matched_asset_value) if self.matched_asset_value else None, + "remediationStatus": ",".join(self.remediation_status) if self.remediation_status else None, "sourceDateFrom": int(self.source_date_from) if self.source_date_from else None, "sourceDateTo": int(self.source_date_to) if self.source_date_to else None, "foundDateFrom": int(self.found_date_from) if self.found_date_from else None, diff --git a/plugins/rapid7_intsights/unit_test/test_get_alerts.py b/plugins/rapid7_intsights/unit_test/test_get_alerts.py index 158c8aa7b2..79e015ca04 100644 --- a/plugins/rapid7_intsights/unit_test/test_get_alerts.py +++ b/plugins/rapid7_intsights/unit_test/test_get_alerts.py @@ -51,10 +51,5 @@ def test_get_alerts_success_with_empty_response_list(self, make_request): @patch("requests.request", side_effect=Util.mock_request) def test_get_alerts_success_with_list_of_alert_types(self, make_request): actual = self.action.run({Input.ALERT_TYPE: ["Phishing", "AttackIndication"]}) - expected = { - 'alert_ids': [ - '7cafac7ec5adaebf62257a4a', - '7cafac7ec5adaebf62257a4b' - ] - } + expected = {"alert_ids": ["7cafac7ec5adaebf62257a4a", "7cafac7ec5adaebf62257a4b"]} self.assertEqual(expected, actual) From e06be203d4926dd566cd38f966c27c7327037d31 Mon Sep 17 00:00:00 2001 From: Mike Rinehart Date: Tue, 26 Oct 2021 14:58:12 -0500 Subject: [PATCH 53/60] Add icon --- plugins/rapid7_intsights/icon.png | Bin 0 -> 10963 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 plugins/rapid7_intsights/icon.png diff --git a/plugins/rapid7_intsights/icon.png b/plugins/rapid7_intsights/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4b1b3252c2d1c8cbd2f22b96a554ac1f02d378f1 GIT binary patch literal 10963 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 V)4mgXk6tr1)Hl Date: Wed, 27 Oct 2021 11:48:33 -0500 Subject: [PATCH 54/60] New graphics --- plugins/rapid7_intsights/extension.png | Bin 0 -> 31072 bytes plugins/rapid7_intsights/icon.png | Bin 10963 -> 5955 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 plugins/rapid7_intsights/extension.png diff --git a/plugins/rapid7_intsights/extension.png b/plugins/rapid7_intsights/extension.png new file mode 100644 index 0000000000000000000000000000000000000000..9650fd976be0eacb5e7f24f915c9f68f0614b81f GIT binary patch literal 31072 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.JH_T9;JAL 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 literal 0 HcmV?d00001 diff --git a/plugins/rapid7_intsights/icon.png b/plugins/rapid7_intsights/icon.png index 4b1b3252c2d1c8cbd2f22b96a554ac1f02d378f1..db4be921f5a1d2d2974df80a99537cd3a00e7be2 100644 GIT binary patch literal 5955 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 V)4mgXk6tr1)Hl Date: Thu, 28 Oct 2021 18:53:36 +0200 Subject: [PATCH 55/60] Fix unit_test path while getting payload --- plugins/rapid7_intsights/unit_test/util.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/rapid7_intsights/unit_test/util.py b/plugins/rapid7_intsights/unit_test/util.py index 46b7756da4..3acbd3bae3 100644 --- a/plugins/rapid7_intsights/unit_test/util.py +++ b/plugins/rapid7_intsights/unit_test/util.py @@ -1,9 +1,13 @@ import json import logging +import sys +import os from icon_rapid7_intsights.connection import Connection from icon_rapid7_intsights.connection.schema import Input +sys.path.append(os.path.abspath("../")) + class Util: request_count = 0 @@ -32,7 +36,9 @@ class MockResponse: def __init__(self, status_code: int, filename: str = None): self.status_code = status_code if filename: - self.text = Util.read_file_to_string(f"payloads/{filename}.json.resp") + self.text = Util.read_file_to_string( + os.path.join(os.path.dirname(os.path.realpath(__file__)), f"payloads/{filename}.json.resp") + ) else: self.text = "" From fc1ee56118af01b12c6c7ba6fa05a04b89cb1b45 Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Sun, 31 Oct 2021 19:15:47 +0100 Subject: [PATCH 56/60] Add cutom type --- .../actions/enrich_indicator/action.py | 15 ++- .../actions/takedown_request/action.py | 1 - .../icon_rapid7_intsights/util/api.py | 3 +- plugins/rapid7_intsights/plugin.spec.yaml | 110 ++++++++++++++++-- 4 files changed, 108 insertions(+), 21 deletions(-) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py index 40d72ae194..34f20dc497 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py @@ -15,11 +15,10 @@ def __init__(self): ) def run(self, params={}): - response = self.connection.client.enrich_indicator(params.get(Input.INDICATOR_VALUE)) - return clean( - { - Output.ORIGINAL_VALUE: response.get("OriginalValue"), - Output.STATUS: response.get("Status"), - Output.DATA: response.get("Data", {}), - } - ) + ioc_value = params.get(Input.INDICATOR_VALUE) + response = self.connection.client.enrich_indicator(ioc_value) + return clean({ + Output.ORIGINAL_VALUE: response.get("OriginalValue", ioc_value), + Output.STATUS: response.get("Status", "Failed"), + Output.DATA: response.get("Data", {}), + }) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/takedown_request/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/takedown_request/action.py index 1040077bf7..d6d9d8fbea 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/takedown_request/action.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/takedown_request/action.py @@ -2,7 +2,6 @@ from .schema import TakedownRequestInput, TakedownRequestOutput, Input, Output, Component # Custom imports below -from insightconnect_plugin_runtime.helper import clean class TakedownRequest(insightconnect_plugin_runtime.Action): diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py b/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py index a45a665144..790694b980 100644 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/util/api.py @@ -109,7 +109,8 @@ def get_indicator_by_value(self, ioc_value: str) -> dict: return self.make_json_request("GET", f"public/v2/iocs/ioc-by-value?iocValue={ioc_value}") def enrich_indicator(self, ioc_value: str) -> dict: - while True: + response = {} + for _ in range(0, 9999): response = self.make_json_request("GET", f"public/v1/iocs/enrich/{ioc_value}") if response.get("Status", "InProgress") in ["Done", "Failed"]: break diff --git a/plugins/rapid7_intsights/plugin.spec.yaml b/plugins/rapid7_intsights/plugin.spec.yaml index 1f52766c98..d400dec7de 100644 --- a/plugins/rapid7_intsights/plugin.spec.yaml +++ b/plugins/rapid7_intsights/plugin.spec.yaml @@ -45,6 +45,94 @@ types: description: Data type: string required: true + alert_source: + Type: + title: Type + description: Type + type: string + required: true + URL: + title: URL + description: URL + type: string + required: true + Email: + title: Email + description: Email + type: string + required: true + NetworkType: + title: Network Type + description: Network type + type: string + required: true + Date: + title: Date + description: Date + type: string + required: true + alert_tags: + _id: + title: ID + description: ID + type: string + required: true + Name: + title: Name + description: Name + type: string + required: true + CreatedBy: + title: Created By + description: Created by + type: string + required: true + alert_details: + Type: + title: Type + description: Type + type: string + required: true + SubType: + title: Sub Type + description: Sub type + type: string + required: true + Severity: + title: Severity + description: Severity + type: string + required: true + Source: + title: Source + description: Source + type: alert_source + required: true + Title: + title: Title + description: Title + type: string + required: true + Description: + title: Description + description: Description + type: string + required: true + Images: + title: Images + description: Images + type: "[]string" + required: true + Tags: + title: Tags + description: Tags + type: "[]alert_tags" + required: true + RelatedIocs: + title: Related IOCs + description: Related IOCs + type: "[]string" + required: true connection: account_id: title: Account ID @@ -65,7 +153,7 @@ actions: input: indicator_value: title: Indicator Value - description: Value of the indicator + description: "Value of the indicator, example: IP Address, URL, Domain, Hash" type: string required: true example: example.com @@ -151,7 +239,7 @@ actions: input: indicator_value: title: Indicator Value - description: Value of the indicator + description: "Value of the indicator example: IP Address, URL, Domain, Hash" type: string required: true example: example.com @@ -160,17 +248,17 @@ actions: title: Original Value description: Original value type: string - required: false + required: true status: title: Status description: Status type: string - required: false + required: true data: title: Data description: Data type: object - required: true + required: false rescan_indicator: title: Rescan Indicator description: Force an indicator scan in IntSights TIP system @@ -186,12 +274,12 @@ actions: title: Task ID description: Task ID type: string - required: true + required: false status: title: Status description: Status type: string - required: true + required: false get_indicator_scan_status: title: Get Indicator Scan Status description: Get the scan status of an indicator in the IntSights TIP system @@ -207,12 +295,12 @@ actions: title: Task ID description: Task ID type: string - required: true + required: false status: title: Status description: Status type: string - required: true + required: false get_alerts: title: Get Alerts description: Search alerts based on criteria @@ -331,7 +419,7 @@ actions: title: ID description: Alert ID type: string - required: true + required: false assets: title: Assets description: List of assets @@ -345,7 +433,7 @@ actions: details: title: Details description: Alert details - type: object + type: alert_details required: true found_date: title: Found Date From 56e4d819190f69f5db063bca479014e3e48ea180 Mon Sep 17 00:00:00 2001 From: Maxim Berezin Date: Mon, 1 Nov 2021 11:59:51 -0400 Subject: [PATCH 57/60] Regenerate plugin and Black format --- plugins/rapid7_intsights/.CHECKSUM | 12 +- plugins/rapid7_intsights/help.md | 31 ++- .../actions/enrich_indicator/action.py | 12 +- .../actions/enrich_indicator/schema.py | 5 +- .../get_complete_alert_by_id/schema.py | 233 +++++++++++++++++- .../actions/get_indicator_by_value/schema.py | 2 +- .../get_indicator_scan_status/schema.py | 6 +- .../actions/rescan_indicator/schema.py | 6 +- 8 files changed, 263 insertions(+), 44 deletions(-) diff --git a/plugins/rapid7_intsights/.CHECKSUM b/plugins/rapid7_intsights/.CHECKSUM index 4f928ebc7f..3932be6683 100644 --- a/plugins/rapid7_intsights/.CHECKSUM +++ b/plugins/rapid7_intsights/.CHECKSUM @@ -1,5 +1,5 @@ { - "spec": "e96e8837a5cc1cfaa801b979ffafd9c1", + "spec": "23fa055c61c44298f0bd3a8550f3edfa", "manifest": "9a1c0ed12f4a14563a7e6ee8431fcb56", "setup": "03540fca0745c2f43e81830a80d402bb", "schemas": [ @@ -9,7 +9,7 @@ }, { "identifier": "enrich_indicator/schema.py", - "hash": "d47d2fcf15a04fbdb9ec87078294d506" + "hash": "d65d91c1451a8e7de47b9e709590f5ea" }, { "identifier": "get_alerts/schema.py", @@ -17,19 +17,19 @@ }, { "identifier": "get_complete_alert_by_id/schema.py", - "hash": "2d0aced444d1c084e2e4bf94f62315ba" + "hash": "e1caf7b9e81e3e8ccff0dec44f5ec2b7" }, { "identifier": "get_indicator_by_value/schema.py", - "hash": "1b8a24fd526eebcf1f7b818667c38ce2" + "hash": "39a599120e9f7d02c34a36f607085ae5" }, { "identifier": "get_indicator_scan_status/schema.py", - "hash": "8dee800f2700228a0ed251111785a228" + "hash": "da46d94cb70a3ad32d719881a4fde656" }, { "identifier": "rescan_indicator/schema.py", - "hash": "957d18eff29b84ba706c867dddd14139" + "hash": "9d70900a799a50bafa5b1ba9245b8fe3" }, { "identifier": "takedown_request/schema.py", diff --git a/plugins/rapid7_intsights/help.md b/plugins/rapid7_intsights/help.md index c5551cd865..f3beb3f5d6 100644 --- a/plugins/rapid7_intsights/help.md +++ b/plugins/rapid7_intsights/help.md @@ -72,10 +72,7 @@ Example input: { "description": "Suspicious addresses", "found_date": "2020-01-01", - "images": [{ - "Type": "jpeg", - "Data": "UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==" - }], + "images": "[{\"Type\": \"jpeg\",\"Data\": \"UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==\"}]", "severity": "Medium", "source_date": "2020-02-01", "source_network_type": "DarkWeb", @@ -157,9 +154,9 @@ Example input: |----|----|--------|-----------| |assets|[]string|True|List of assets| |assignees|[]string|True|List of assignees| -|details|object|True|Alert details| +|details|alert_details|True|Alert details| |found_date|date|False|Alert found date| -|id|string|True|Alert ID| +|id|string|False|Alert ID| |is_closed|boolean|True|Is alert closed| |is_flagged|boolean|True|Is alert flagged| |leak_name|string|False|Name of the leak DBs in data leakage alerts| @@ -203,7 +200,7 @@ This action is used to force an indicator scan in Intsights TIP system. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_file_hash|string|None|True|IOC value in type file hash|None|275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f| +|indicator_file_hash|string|None|True|IOC value in type file hash|None|30f800f97aeaa8d62bdf3a6fb2b0681179a360c12e127f07038f8521461e5050| Example input: @@ -217,8 +214,8 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|status|string|True|Status| -|task_id|string|True|Task ID| +|status|string|False|Status| +|task_id|string|False|Task ID| Example output: @@ -251,8 +248,8 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|status|string|True|Status| -|task_id|string|True|Task ID| +|status|string|False|Status| +|task_id|string|False|Task ID| Example output: @@ -278,7 +275,7 @@ This action is used to search Alerts based on criteria. |has_indicators|boolean|None|False|Show alerts with IOCs results|None|False| |is_closed|boolean|None|False|Status of the alert, either closed or open|['Closed', 'Open']|Closed| |is_flagged|string|None|False|Show flagged/unflagged alerts|['Flagged', 'Unflagged']|Flagged| -|matched_asset_value|[]string|None|False|List of matched asset values|None|["example.com"]| +|matched_asset_value|[]string|None|False|List of matched asset values|None|["https://example.com"]| |network_type|[]string|None|False|List of network type. Allowed values: ClearWeb, DarkWeb|None|["DarkWeb"]| |remediation_status|[]string|None|False|List of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed|None|["InProgress", "Pending"]| |severity|[]string|None|False|List of alerts severity. Allowed values: High, Medium, Low|None|["Low"]| @@ -345,7 +342,7 @@ This action is used to submit an indicator to IntSights for investigation and re |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_value|string|None|True|Value of the indicator|None|example.com| +|indicator_value|string|None|True|Value of the indicator example: IP Address, URL, Domain, Hash|None|https://example.com| Example input: @@ -359,9 +356,9 @@ Example input: |Name|Type|Required|Description| |----|----|--------|-----------| -|data|object|True|Data| -|original_value|string|False|Original value| -|status|string|False|Status| +|data|object|False|Data| +|original_value|string|True|Original value| +|status|string|True|Status| Example output: @@ -574,7 +571,7 @@ This action will search indicators in IntSights TIP. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_value|string|None|True|Value of the indicator|None|example.com| +|indicator_value|string|None|True|Value of the indicator, example: IP Address, URL, Domain, Hash|None|https://example.com| Example input: diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py index 34f20dc497..ed751f777c 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/action.py @@ -17,8 +17,10 @@ def __init__(self): def run(self, params={}): ioc_value = params.get(Input.INDICATOR_VALUE) response = self.connection.client.enrich_indicator(ioc_value) - return clean({ - Output.ORIGINAL_VALUE: response.get("OriginalValue", ioc_value), - Output.STATUS: response.get("Status", "Failed"), - Output.DATA: response.get("Data", {}), - }) + return clean( + { + Output.ORIGINAL_VALUE: response.get("OriginalValue", ioc_value), + Output.STATUS: response.get("Status", "Failed"), + Output.DATA: response.get("Data", {}), + } + ) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/schema.py index 7fe44a2716..1fb99c2c66 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/schema.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/enrich_indicator/schema.py @@ -26,7 +26,7 @@ class EnrichIndicatorInput(insightconnect_plugin_runtime.Input): "indicator_value": { "type": "string", "title": "Indicator Value", - "description": "Value of the indicator", + "description": "Value of the indicator example: IP Address, URL, Domain, Hash", "order": 1 } }, @@ -66,7 +66,8 @@ class EnrichIndicatorOutput(insightconnect_plugin_runtime.Output): } }, "required": [ - "data" + "original_value", + "status" ] } """) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py index 3c70a0af75..3c9ae8777f 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py @@ -72,7 +72,7 @@ class GetCompleteAlertByIdOutput(insightconnect_plugin_runtime.Output): "order": 3 }, "details": { - "type": "object", + "$ref": "#/definitions/alert_details", "title": "Details", "description": "Alert details", "order": 4 @@ -128,10 +128,237 @@ class GetCompleteAlertByIdOutput(insightconnect_plugin_runtime.Output): "assets", "assignees", "details", - "id", "is_closed", "is_flagged" - ] + ], + "definitions": { + "alert_details": { + "type": "object", + "title": "alert_details", + "properties": { + "Description": { + "type": "string", + "title": "Description", + "description": "Description", + "order": 6 + }, + "Images": { + "type": "array", + "title": "Images", + "description": "Images", + "items": { + "type": "string" + }, + "order": 7 + }, + "RelatedIocs": { + "type": "array", + "title": "Related IOCs", + "description": "Related IOCs", + "items": { + "type": "string" + }, + "order": 9 + }, + "Severity": { + "type": "string", + "title": "Severity", + "description": "Severity", + "order": 3 + }, + "Source": { + "$ref": "#/definitions/alert_source", + "title": "Source", + "description": "Source", + "order": 4 + }, + "SubType": { + "type": "string", + "title": "Sub Type", + "description": "Sub type", + "order": 2 + }, + "Tags": { + "type": "array", + "title": "Tags", + "description": "Tags", + "items": { + "$ref": "#/definitions/alert_tags" + }, + "order": 8 + }, + "Title": { + "type": "string", + "title": "Title", + "description": "Title", + "order": 5 + }, + "Type": { + "type": "string", + "title": "Type", + "description": "Type", + "order": 1 + } + }, + "required": [ + "Description", + "Images", + "RelatedIocs", + "Severity", + "Source", + "SubType", + "Tags", + "Title", + "Type" + ], + "definitions": { + "alert_source": { + "type": "object", + "title": "alert_source", + "properties": { + "Date": { + "type": "string", + "title": "Date", + "description": "Date", + "order": 5 + }, + "Email": { + "type": "string", + "title": "Email", + "description": "Email", + "order": 3 + }, + "NetworkType": { + "type": "string", + "title": "Network Type", + "description": "Network type", + "order": 4 + }, + "Type": { + "type": "string", + "title": "Type", + "description": "Type", + "order": 1 + }, + "URL": { + "type": "string", + "title": "URL", + "description": "URL", + "order": 2 + } + }, + "required": [ + "Date", + "Email", + "NetworkType", + "Type", + "URL" + ] + }, + "alert_tags": { + "type": "object", + "title": "alert_tags", + "properties": { + "CreatedBy": { + "type": "string", + "title": "Created By", + "description": "Created by", + "order": 3 + }, + "Name": { + "type": "string", + "title": "Name", + "description": "Name", + "order": 2 + }, + "_id": { + "type": "string", + "title": "ID", + "description": "ID", + "order": 1 + } + }, + "required": [ + "CreatedBy", + "Name", + "_id" + ] + } + } + }, + "alert_source": { + "type": "object", + "title": "alert_source", + "properties": { + "Date": { + "type": "string", + "title": "Date", + "description": "Date", + "order": 5 + }, + "Email": { + "type": "string", + "title": "Email", + "description": "Email", + "order": 3 + }, + "NetworkType": { + "type": "string", + "title": "Network Type", + "description": "Network type", + "order": 4 + }, + "Type": { + "type": "string", + "title": "Type", + "description": "Type", + "order": 1 + }, + "URL": { + "type": "string", + "title": "URL", + "description": "URL", + "order": 2 + } + }, + "required": [ + "Date", + "Email", + "NetworkType", + "Type", + "URL" + ] + }, + "alert_tags": { + "type": "object", + "title": "alert_tags", + "properties": { + "CreatedBy": { + "type": "string", + "title": "Created By", + "description": "Created by", + "order": 3 + }, + "Name": { + "type": "string", + "title": "Name", + "description": "Name", + "order": 2 + }, + "_id": { + "type": "string", + "title": "ID", + "description": "ID", + "order": 1 + } + }, + "required": [ + "CreatedBy", + "Name", + "_id" + ] + } + } } """) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_by_value/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_by_value/schema.py index 0cc67fce1e..6c2604e39d 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_by_value/schema.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_by_value/schema.py @@ -38,7 +38,7 @@ class GetIndicatorByValueInput(insightconnect_plugin_runtime.Input): "indicator_value": { "type": "string", "title": "Indicator Value", - "description": "Value of the indicator", + "description": "Value of the indicator, example: IP Address, URL, Domain, Hash", "order": 1 } }, diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/schema.py index 47351fded0..0f6d593b66 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/schema.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_indicator_scan_status/schema.py @@ -57,11 +57,7 @@ class GetIndicatorScanStatusOutput(insightconnect_plugin_runtime.Output): "description": "Task ID", "order": 1 } - }, - "required": [ - "status", - "task_id" - ] + } } """) diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/rescan_indicator/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/rescan_indicator/schema.py index c3b87523a7..271cda4c3e 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/rescan_indicator/schema.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/rescan_indicator/schema.py @@ -57,11 +57,7 @@ class RescanIndicatorOutput(insightconnect_plugin_runtime.Output): "description": "Task ID", "order": 1 } - }, - "required": [ - "status", - "task_id" - ] + } } """) From e1ba917f4a4a9b87808f903f9733c0ff2505a874 Mon Sep 17 00:00:00 2001 From: Maxim Berezin Date: Mon, 1 Nov 2021 13:59:00 -0400 Subject: [PATCH 58/60] Update help.md for validator --- plugins/rapid7_intsights/help.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/rapid7_intsights/help.md b/plugins/rapid7_intsights/help.md index f3beb3f5d6..6cddc0e57f 100644 --- a/plugins/rapid7_intsights/help.md +++ b/plugins/rapid7_intsights/help.md @@ -200,7 +200,7 @@ This action is used to force an indicator scan in Intsights TIP system. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_file_hash|string|None|True|IOC value in type file hash|None|30f800f97aeaa8d62bdf3a6fb2b0681179a360c12e127f07038f8521461e5050| +|indicator_file_hash|string|None|True|IOC value in type file hash|None|275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f| Example input: @@ -275,7 +275,7 @@ This action is used to search Alerts based on criteria. |has_indicators|boolean|None|False|Show alerts with IOCs results|None|False| |is_closed|boolean|None|False|Status of the alert, either closed or open|['Closed', 'Open']|Closed| |is_flagged|string|None|False|Show flagged/unflagged alerts|['Flagged', 'Unflagged']|Flagged| -|matched_asset_value|[]string|None|False|List of matched asset values|None|["https://example.com"]| +|matched_asset_value|[]string|None|False|List of matched asset values|None|["example.com"]| |network_type|[]string|None|False|List of network type. Allowed values: ClearWeb, DarkWeb|None|["DarkWeb"]| |remediation_status|[]string|None|False|List of remediation statuses. Allowed values: InProgress, Pending, CancellationInProgress, Cancelled, CompletedSuccessfully, Failed|None|["InProgress", "Pending"]| |severity|[]string|None|False|List of alerts severity. Allowed values: High, Medium, Low|None|["Low"]| @@ -342,7 +342,7 @@ This action is used to submit an indicator to IntSights for investigation and re |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_value|string|None|True|Value of the indicator example: IP Address, URL, Domain, Hash|None|https://example.com| +|indicator_value|string|None|True|Value of the indicator example: IP Address, URL, Domain, Hash|None|example.com| Example input: @@ -571,7 +571,8 @@ This action will search indicators in IntSights TIP. |Name|Type|Default|Required|Description|Enum|Example| |----|----|-------|--------|-----------|----|-------| -|indicator_value|string|None|True|Value of the indicator, example: IP Address, URL, Domain, Hash|None|https://example.com| +|indicator_value|string|None|True|Value of the indicator, example: IP Address, URL, Domain, Hash|None|example.com| + Example input: From 95280cae23f8c9f3853ea45ba2b8f1b5f91c6812 Mon Sep 17 00:00:00 2001 From: Mike Rinehart <32079048+mrinehart-r7@users.noreply.github.com> Date: Tue, 2 Nov 2021 09:54:52 -0500 Subject: [PATCH 59/60] Update plugins/rapid7_intsights/help.md --- plugins/rapid7_intsights/help.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/rapid7_intsights/help.md b/plugins/rapid7_intsights/help.md index 6cddc0e57f..68fc534261 100644 --- a/plugins/rapid7_intsights/help.md +++ b/plugins/rapid7_intsights/help.md @@ -72,7 +72,10 @@ Example input: { "description": "Suspicious addresses", "found_date": "2020-01-01", - "images": "[{\"Type\": \"jpeg\",\"Data\": \"UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==\"}]", + "images": [{ + "Type": "jpeg", + "Data": "UmFwaWQ3IEluc2lnaHRDb25uZWN0Cg==" + }], "severity": "Medium", "source_date": "2020-02-01", "source_network_type": "DarkWeb", From a814760d7b11ac101cb4c236c9680c2178f91ba2 Mon Sep 17 00:00:00 2001 From: Mateusz Gorny Date: Tue, 2 Nov 2021 21:48:27 +0100 Subject: [PATCH 60/60] [MC-683] Set some output to required false --- plugins/rapid7_intsights/.CHECKSUM | 4 ++-- .../actions/get_complete_alert_by_id/schema.py | 10 ---------- plugins/rapid7_intsights/plugin.spec.yaml | 14 +++++++------- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/plugins/rapid7_intsights/.CHECKSUM b/plugins/rapid7_intsights/.CHECKSUM index 3932be6683..14e2e0d404 100644 --- a/plugins/rapid7_intsights/.CHECKSUM +++ b/plugins/rapid7_intsights/.CHECKSUM @@ -1,5 +1,5 @@ { - "spec": "23fa055c61c44298f0bd3a8550f3edfa", + "spec": "0adf1b012936b256501cb9d2365aac51", "manifest": "9a1c0ed12f4a14563a7e6ee8431fcb56", "setup": "03540fca0745c2f43e81830a80d402bb", "schemas": [ @@ -17,7 +17,7 @@ }, { "identifier": "get_complete_alert_by_id/schema.py", - "hash": "e1caf7b9e81e3e8ccff0dec44f5ec2b7" + "hash": "a5a4e73ebf917dc6ae329aa958ae94a6" }, { "identifier": "get_indicator_by_value/schema.py", diff --git a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py index 3c9ae8777f..4c7f54d665 100755 --- a/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py +++ b/plugins/rapid7_intsights/icon_rapid7_intsights/actions/get_complete_alert_by_id/schema.py @@ -201,13 +201,9 @@ class GetCompleteAlertByIdOutput(insightconnect_plugin_runtime.Output): } }, "required": [ - "Description", - "Images", - "RelatedIocs", "Severity", "Source", "SubType", - "Tags", "Title", "Type" ], @@ -248,9 +244,6 @@ class GetCompleteAlertByIdOutput(insightconnect_plugin_runtime.Output): } }, "required": [ - "Date", - "Email", - "NetworkType", "Type", "URL" ] @@ -322,9 +315,6 @@ class GetCompleteAlertByIdOutput(insightconnect_plugin_runtime.Output): } }, "required": [ - "Date", - "Email", - "NetworkType", "Type", "URL" ] diff --git a/plugins/rapid7_intsights/plugin.spec.yaml b/plugins/rapid7_intsights/plugin.spec.yaml index d400dec7de..ac2985ad1f 100644 --- a/plugins/rapid7_intsights/plugin.spec.yaml +++ b/plugins/rapid7_intsights/plugin.spec.yaml @@ -60,17 +60,17 @@ types: title: Email description: Email type: string - required: true + required: false NetworkType: title: Network Type description: Network type type: string - required: true + required: false Date: title: Date description: Date type: string - required: true + required: false alert_tags: _id: title: ID @@ -117,22 +117,22 @@ types: title: Description description: Description type: string - required: true + required: false Images: title: Images description: Images type: "[]string" - required: true + required: false Tags: title: Tags description: Tags type: "[]alert_tags" - required: true + required: false RelatedIocs: title: Related IOCs description: Related IOCs type: "[]string" - required: true + required: false connection: account_id: title: Account ID