From a408339f7b2a87a6fbf7478b161f3707fa90f65d Mon Sep 17 00:00:00 2001 From: JD Babac Date: Fri, 13 Sep 2024 02:59:53 +0800 Subject: [PATCH] IDEV-1867: Test NOD feeds with Splunk SOAR --- domaintools_iris.json | 46 ++++++++++++++++++++++++++++++++++- domaintools_iris_connector.py | 39 ++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/domaintools_iris.json b/domaintools_iris.json index 98d2779..833530e 100644 --- a/domaintools_iris.json +++ b/domaintools_iris.json @@ -7,7 +7,7 @@ "type": "information", "license": "Copyright (c) 2019-2024 DomainTools, LLC", "main_module": "domaintools_iris_connector.py", - "app_version": "1.5.1", + "app_version": "1.5.2", "utctime_updated": "2023-10-25T15:44:30.000000Z", "product_vendor": "DomainTools", "product_name": "DomainTools Iris Investigate", @@ -210,6 +210,50 @@ ], "versions": "EQ(*)" }, + { + "action": "nod feed", + "description": "Lists newly observed domains from feed", + "type": "investigate", + "identifier": "nod_feed", + "read_only": true, + "parameters": {}, + "render": { + "width": 12, + "title": "Newly Observed Domains List", + "type": "table", + "height": 10 + }, + "output": [ + { + "data_path": "action_result.data", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.domain", + "data_type": "string", + "column_name": "Domain Names", + "column_order": 1, + "contains": [ + "domain" + ] + }, + { + "data_path": "action_result.data.*.timestamp", + "data_type": "string", + "column_name": "Time Stamp", + "column_order": 2 + }, + { + "data_path": "action_result.status", + "data_type": "string", + "example_values": [ + "success", + "failed" + ] + } + ], + "versions": "EQ(*)" + }, { "action": "pivot action", "description": "Find domains connected by any supported Iris Investigate search parameter", diff --git a/domaintools_iris_connector.py b/domaintools_iris_connector.py index 8876eba..0165b1e 100644 --- a/domaintools_iris_connector.py +++ b/domaintools_iris_connector.py @@ -14,6 +14,7 @@ import phantom.app as phantom import requests import tldextract + # 3rd party imports from domaintools import API from phantom.action_result import ActionResult @@ -32,6 +33,7 @@ class DomainToolsConnector(BaseConnector): ACTION_ID_LOAD_HASH = "load_hash" ACTION_ID_ON_POLL = "on_poll" ACTION_ID_CONFIGURE_SCHEDULED_PLAYBOOK = "configure_monitoring_scheduled_playbooks" + ACTION_ID_NOD_FEED = "nod_feed" def __init__(self): # Call the BaseConnectors init first @@ -274,9 +276,11 @@ def _convert_risk_scores_to_string(self, results_data): # Make the final result sorted in descending order by default return sorted( final_result, - key=lambda d: 0 - if d.get("domain_risk", {}).get("risk_score_string") == "" - else d.get("domain_risk", {}).get("risk_score"), + key=lambda d: ( + 0 + if d.get("domain_risk", {}).get("risk_score_string") == "" + else d.get("domain_risk", {}).get("risk_score") + ), reverse=True, ) @@ -354,6 +358,8 @@ def handle_action(self, param): ret_val = self._on_poll(param) elif action_id == self.ACTION_ID_CONFIGURE_SCHEDULED_PLAYBOOK: ret_val = self._configure_monitoring_scheduled_playbooks(param) + elif action_id == self.ACTION_ID_NOD_FEED: + ret_val = self._nod_feed(param) return ret_val @@ -883,6 +889,33 @@ def _configure_monitoring_scheduled_playbooks(self, param): f"`{self._scheduled_playbooks_list_name}` custom list {res.get('message')}", ) + def _nod_feed(self, param): + self.save_progress("Starting nod_feeds action.") + action_result = self.add_action_result(ActionResult(param)) + + # params = {"domains": self._domains} + # self._do_query("iris_investigate", action_result, query_args=params) + # response = requests.get() + response = requests.get( + "https://api.domaintools.com/v1/feed/nod/?api_key=c5650-ee587-40d73-8ddc2-8f001&api_username=ajohnson_nod_api&after=-60" + ) + rows = response.text.strip().split("\n") + data = [] + for row in rows: + feed_result = json.loads(row) + data.append( + { + "timestamp": feed_result.get("timestamp"), + "domain": feed_result.get("domain"), + } + ) + + action_result.update_data(data) + action_result.set_status(phantom.APP_SUCCESS) + self.save_progress("Completed nod_feed action.") + + return action_result.get_status() + if __name__ == "__main__": import argparse