diff --git a/Splunk SOAR/DomainTools_Feeds_Domain_Hotlist/DomainTools_Feeds_Domain_Hotlist.tgz b/Splunk SOAR/DomainTools_Feeds_Domain_Hotlist/DomainTools_Feeds_Domain_Hotlist.tgz new file mode 100644 index 0000000..d7606ac Binary files /dev/null and b/Splunk SOAR/DomainTools_Feeds_Domain_Hotlist/DomainTools_Feeds_Domain_Hotlist.tgz differ diff --git a/Splunk SOAR/DomainTools_Feeds_Domain_Hotlist/README.md b/Splunk SOAR/DomainTools_Feeds_Domain_Hotlist/README.md new file mode 100644 index 0000000..e45ff3e --- /dev/null +++ b/Splunk SOAR/DomainTools_Feeds_Domain_Hotlist/README.md @@ -0,0 +1,12 @@ +## DomainTools Feeds Domain Hotlist Playbook + +This playbook retrieves newly observed domains from DomainTools Real Time Unified Feeds from a given `sessionID`, `before`, and/or `after` params. It will save the Domain Hotlist feeds list in a csv file with naming convention - `domaintools_feed_domain_hotlist__.csv`. The flow will continue to retrieve Domain Hotlist feeds based on the scheduled run + +#### DomainTools API Asset + +**The DomainTools playbooks in this repo will require an asset called `domaintoolscreds`** for a DomainTools API username and key. This asset is used to retrieve Domain Hotlist feeds data via the DomainTools API during playbook execution. Current action selected is `domain_hotlist_feed` and it requires `sessionID`, `before`, and/or `after` input parameters. Optional input parameters are `domain` and `top`. +
+ +#### Installation + +Download the tar file in this directory and import the playbook using that file. The asset accessed in the playbook is for DomainTools API credentials. Point the playbook to the `domaintoolscreds` asset, save the playbook, make sure it's active, and give it a shot. diff --git a/Splunk SOAR/DomainTools_Feeds_Domain_Hotlist/src/DomainTools Feeds Domain Hotlist.json b/Splunk SOAR/DomainTools_Feeds_Domain_Hotlist/src/DomainTools Feeds Domain Hotlist.json new file mode 100644 index 0000000..45b4c21 --- /dev/null +++ b/Splunk SOAR/DomainTools_Feeds_Domain_Hotlist/src/DomainTools Feeds Domain Hotlist.json @@ -0,0 +1,153 @@ +{ + "blockly": false, + "blockly_xml": "", + "category": "Uncategorized", + "coa": { + "data": { + "description": "", + "edges": [ + { + "id": "port_0_to_port_2", + "sourceNode": "0", + "sourcePort": "0_out", + "targetNode": "2", + "targetPort": "2_in" + }, + { + "id": "port_2_to_port_3", + "sourceNode": "2", + "sourcePort": "2_out", + "targetNode": "3", + "targetPort": "3_in" + }, + { + "id": "port_3_to_port_1", + "sourceNode": "3", + "sourcePort": "3_out", + "targetNode": "1", + "targetPort": "1_in" + } + ], + "hash": "286c15eed27262925745bfb80a40129e99bc925f", + "nodes": { + "0": { + "data": { + "advanced": { + "join": [] + }, + "functionName": "on_start", + "id": "0", + "type": "start" + }, + "errors": {}, + "id": "0", + "type": "start", + "warnings": {}, + "x": 19.999999999999986, + "y": -1.2789769243681803e-13 + }, + "1": { + "data": { + "advanced": { + "join": [] + }, + "functionName": "on_finish", + "id": "1", + "type": "end" + }, + "errors": {}, + "id": "1", + "type": "end", + "warnings": {}, + "x": 19.999999999999986, + "y": 443.9999999999998 + }, + "2": { + "data": { + "action": "domain hotlist feed", + "actionType": "investigate", + "advanced": { + "join": [] + }, + "connector": "DomainTools Iris Investigate", + "connectorConfigs": [ + "domaintoolscreds" + ], + "connectorId": "f18b7ef9-0cbd-4dbb-b8ed-ce62e17f0603", + "connectorVersion": "v1", + "functionId": 1, + "functionName": "domain_hotlist_feed_1", + "id": "2", + "loop": { + "enabled": false, + "exitAfterUnit": "m", + "exitAfterValue": 10, + "exitConditionEnabled": false, + "exitLoopAfter": 2, + "pauseUnit": "m", + "pauseValue": 2 + }, + "parameters": { + "before": "", + "session_id": "integrations-testing", + "top": "" + }, + "requiredParameters": [], + "type": "action" + }, + "errors": {}, + "id": "2", + "type": "action", + "userCode": "\n # Write your custom code here...\n\n", + "warnings": {}, + "x": 0, + "y": 140 + }, + "3": { + "data": { + "advanced": { + "customName": "output domain risk list", + "customNameId": 0, + "join": [] + }, + "functionId": 1, + "functionName": "output_domain_risk_list", + "id": "3", + "inputParameters": [ + "domain_hotlist_feed_1:action_result.data" + ], + "outputVariables": [], + "type": "code" + }, + "errors": {}, + "id": "3", + "type": "code", + "userCode": "\n # Write your custom code here...\n from datetime import datetime\n import csv\n \n event_name = container.get(\"name\")\n file_name = f\"domaintools_feed_domain_hotlist_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv\"\n phantom.debug(f\"dt debug - exporting Domain Hotlist to {file_name} file.\")\n \n with open(f\"/opt/phantom/vault/tmp/{file_name}\", \"w\", newline='') as report_csv_file:\n headers = [\"domain\", \"timestamp\", \"phishing_risk\", \"malware_risk\", \"spam_risk\", \"proximity_risk\", \"overall_risk\", \"expires\"]\n writer = csv.DictWriter(report_csv_file, fieldnames=headers)\n \n writer.writeheader()\n for data in domain_hotlist_feed_1_result_item_0[0] or []:\n writer.writerow(data)\n \n # Define the CEF data in a Python dictionary\n cef_data = {\n \"destinationDnsDomain\": data.get(\"domain\"),\n \"timestamp\": data.get(\"timestamp\"),\n \"phishing_risk\": data.get(\"phishing_risk\"),\n \"malware_risk\": data.get(\"malware_risk\"),\n \"spam_risk\": data.get(\"spam_risk\"),\n \"proximity_risk\": data.get(\"proximity_risk\"),\n \"overall_risk\": data.get(\"overall_risk\"),\n \"expires\": data.get(\"expires\"),\n }\n # Use the dictionary to create a new artifact\n phantom.add_artifact(\n container=container,\n label=\"domaintools-realtime-feeds\",\n severity=\"high\",\n name=\"Domain Hotlist Feed\",\n cef_data=cef_data\n )\n\n success, message, vault_id = phantom.vault_add(container=container, file_location=f\"/opt/phantom/vault/tmp/{file_name}\", file_name=file_name)\n \n if not success:\n phantom.error(f\"dt error - Error creating {file_name} file. Message: {message}\")\n return\n\n\n", + "warnings": {}, + "x": 0, + "y": 300 + } + }, + "notes": "", + "origin": { + "playbook_id": 364, + "playbook_name": "DomainTools Feeds Domain Risk", + "playbook_repo_id": 2, + "playbook_repo_name": "local" + } + }, + "input_spec": null, + "output_spec": null, + "playbook_trigger": "artifact_created", + "playbook_type": "automation", + "python_version": "3", + "schema": "5.0.17", + "version": "6.4.0.90" + }, + "create_time": "2025-09-05T18:47:19.464749+00:00", + "draft_mode": false, + "labels": [ + "events" + ], + "tags": [] +} \ No newline at end of file diff --git a/Splunk SOAR/DomainTools_Feeds_Domain_Hotlist/src/DomainTools Feeds Domain Hotlist.py b/Splunk SOAR/DomainTools_Feeds_Domain_Hotlist/src/DomainTools Feeds Domain Hotlist.py new file mode 100644 index 0000000..1f45afe --- /dev/null +++ b/Splunk SOAR/DomainTools_Feeds_Domain_Hotlist/src/DomainTools Feeds Domain Hotlist.py @@ -0,0 +1,127 @@ +""" + +""" + + +import phantom.rules as phantom +import json +from datetime import datetime, timedelta + + +@phantom.playbook_block() +def on_start(container): + phantom.debug('on_start() called') + + # call 'domain_hotlist_feed_1' block + domain_hotlist_feed_1(container=container) + + return + +@phantom.playbook_block() +def domain_hotlist_feed_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, loop_state_json=None, **kwargs): + phantom.debug("domain_hotlist_feed_1() called") + + # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) + + parameters = [] + + parameters.append({ + "before": "", + "session_id": "integrations-testing", + "top": "", + }) + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.act("domain hotlist feed", parameters=parameters, name="domain_hotlist_feed_1", assets=["domaintoolscreds"], callback=output_domain_risk_list) + + return + + +@phantom.playbook_block() +def output_domain_risk_list(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, loop_state_json=None, **kwargs): + phantom.debug("output_domain_risk_list() called") + + domain_hotlist_feed_1_result_data = phantom.collect2(container=container, datapath=["domain_hotlist_feed_1:action_result.data"], action_results=results) + + domain_hotlist_feed_1_result_item_0 = [item[0] for item in domain_hotlist_feed_1_result_data] + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + from datetime import datetime + import csv + + event_name = container.get("name") + file_name = f"domaintools_feed_domain_hotlist_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv" + phantom.debug(f"dt debug - exporting Domain Hotlist to {file_name} file.") + + with open(f"/opt/phantom/vault/tmp/{file_name}", "w", newline='') as report_csv_file: + headers = ["domain", "timestamp", "phishing_risk", "malware_risk", "spam_risk", "proximity_risk", "overall_risk", "expires"] + writer = csv.DictWriter(report_csv_file, fieldnames=headers) + + writer.writeheader() + for data in domain_hotlist_feed_1_result_item_0[0] or []: + writer.writerow(data) + + # Define the CEF data in a Python dictionary + cef_data = { + "destinationDnsDomain": data.get("domain"), + "timestamp": data.get("timestamp"), + "phishing_risk": data.get("phishing_risk"), + "malware_risk": data.get("malware_risk"), + "spam_risk": data.get("spam_risk"), + "proximity_risk": data.get("proximity_risk"), + "overall_risk": data.get("overall_risk"), + "expires": data.get("expires"), + } + # Use the dictionary to create a new artifact + phantom.add_artifact( + container=container, + label="domaintools-realtime-feeds", + severity="high", + name="Domain Hotlist Feed", + cef_data=cef_data + ) + + success, message, vault_id = phantom.vault_add(container=container, file_location=f"/opt/phantom/vault/tmp/{file_name}", file_name=file_name) + + if not success: + phantom.error(f"dt error - Error creating {file_name} file. Message: {message}") + return + + + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.save_block_result(key="output_domain_risk_list__inputs:0:domain_hotlist_feed_1:action_result.data", value=json.dumps(domain_hotlist_feed_1_result_item_0)) + + return + + +@phantom.playbook_block() +def on_finish(container, summary): + phantom.debug("on_finish() called") + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + + ################################################################################ + ## Custom Code End + ################################################################################ + + return \ No newline at end of file