From 825a01d5047ef3892eb729bc840d1461c20d620e Mon Sep 17 00:00:00 2001 From: nusantara-self <15647296+nusantara-self@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:46:46 +0800 Subject: [PATCH 1/7] Update NetcraftTakedown.json --- responders/Netcraft/NetcraftTakedown.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/responders/Netcraft/NetcraftTakedown.json b/responders/Netcraft/NetcraftTakedown.json index b349e34f3..2e9887a7b 100644 --- a/responders/Netcraft/NetcraftTakedown.json +++ b/responders/Netcraft/NetcraftTakedown.json @@ -34,7 +34,9 @@ "name": "useUserPass", "description": "Use User and Password authentication", "type": "boolean", - "multi": false + "multi": false, + "required": true, + "defaultValue": false }, { "name": "takedown_url", From 746371fa397ab303e6f5cd419e3f6ce8fe52533c Mon Sep 17 00:00:00 2001 From: nusantara-self <15647296+nusantara-self@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:49:19 +0800 Subject: [PATCH 2/7] Add custom base_url support --- .../CrowdstrikeFalcon_GetDeviceVulnerabilities.json | 8 ++++++++ .../CrowdstrikeFalcon_GetDeviceVulnerabilities.py | 4 ++-- analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox.py | 3 ++- .../CrowdstrikeFalcon_Sandbox_Android.json | 8 ++++++++ .../CrowdstrikeFalcon_Sandbox_Linux.json | 8 ++++++++ .../CrowdstrikeFalcon_Sandbox_MacOS.json | 8 ++++++++ .../CrowdstrikeFalcon_Sandbox_Win10.json | 8 ++++++++ .../CrowdstrikeFalcon_Sandbox_Win11.json | 8 ++++++++ .../CrowdstrikeFalcon_Sandbox_Win7.json | 8 ++++++++ .../CrowdstrikeFalcon_Sandbox_Win7_64.json | 8 ++++++++ .../CrowdstrikeFalcon_getDeviceAlerts.json | 8 ++++++++ .../CrowdstrikeFalcon_getDeviceAlerts.py | 3 ++- .../CrowdstrikeFalcon_getDeviceDetails.json | 8 ++++++++ .../CrowdstrikeFalcon_getDeviceDetails.py | 4 +++- .../CrowdstrikeFalcon/CrowdStrikeFalcon_AddIOC.json | 8 ++++++++ responders/CrowdstrikeFalcon/CrowdStrikeFalcon_Sync.json | 8 ++++++++ .../CrowdstrikeFalcon/CrowdStrikeFalcon_removeIOC.json | 8 ++++++++ responders/CrowdstrikeFalcon/CrowdstrikeFalconHosts.py | 4 +++- responders/CrowdstrikeFalcon/CrowdstrikeFalconIOC.py | 9 ++++++--- responders/CrowdstrikeFalcon/CrowdstrikeFalconSync.py | 8 +++++--- .../CrowdstrikeFalcon/CrowdstrikeFalcon_containHost.json | 8 ++++++++ .../CrowdstrikeFalcon/CrowdstrikeFalcon_hideHost.json | 8 ++++++++ .../CrowdstrikeFalcon_liftContainmentHost.json | 8 ++++++++ .../CrowdstrikeFalcon_suppressDetections.json | 8 ++++++++ .../CrowdstrikeFalcon/CrowdstrikeFalcon_unhideHost.json | 8 ++++++++ .../CrowdstrikeFalcon_unsuppressDetection.json | 8 ++++++++ 26 files changed, 175 insertions(+), 12 deletions(-) diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_GetDeviceVulnerabilities.json b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_GetDeviceVulnerabilities.json index 865f707fd..d3f90b3dc 100644 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_GetDeviceVulnerabilities.json +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_GetDeviceVulnerabilities.json @@ -32,6 +32,14 @@ "required": true, "defaultValue": "" }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" + }, { "name": "vuln_fields", "description": "Specific field values to keep in resulting payload for vulnerabilities", diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_GetDeviceVulnerabilities.py b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_GetDeviceVulnerabilities.py index bffe8c154..8b9fd49f9 100755 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_GetDeviceVulnerabilities.py +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_GetDeviceVulnerabilities.py @@ -12,7 +12,7 @@ def __init__(self): self.client_id = self.get_param("config.client_id") self.client_secret = self.get_param("config.client_secret") self.vuln_fields = self.get_param("config.vuln_fields", []) - + self.base_url = self.get_param("config.base_url", "https://api.crowdstrike.com") def run(self): @@ -23,7 +23,7 @@ def run(self): extra_headers = { "User-Agent": "strangebee-thehive/1.0" } - auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret) + auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret, base_url=self.base_url) hosts = Hosts(auth_object=auth, ext_headers=extra_headers) hostname = self.get_data() diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox.py b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox.py index 54412b012..d8d75e4e1 100755 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox.py +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox.py @@ -15,6 +15,7 @@ def __init__(self): self.filepath = self.getParam("file", None, "File is missing") self.client_id = self.get_param("config.client_id") self.client_secret = self.get_param("config.client_secret") + self.base_url = self.get_param("config.base_url", "https://api.crowdstrike.com") self.environment = self.get_param("config.service", 160) self.network_settings = self.get_param("config.network_settings", "default") self.action_script = self.get_param("config.action_script", "default") @@ -48,7 +49,7 @@ def run(self): } with open(filepath, "rb") as sample: - auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret) + auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret, base_url=self.base_url) # Define the custom header extra_headers = { "User-Agent": "strangebee-thehive/1.0" diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Android.json b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Android.json index 5172e4523..f53727d70 100644 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Android.json +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Android.json @@ -32,6 +32,14 @@ "required": true, "defaultValue": "" }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" + }, { "name": "network_settings", "description": "Specifies the sandbox network_settings used for analysis : default, tor, simulated, offline", diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Linux.json b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Linux.json index a9e42738d..f28b4b502 100644 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Linux.json +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Linux.json @@ -32,6 +32,14 @@ "required": true, "defaultValue": "" }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" + }, { "name": "network_settings", "description": "Specifies the sandbox network_settings used for analysis : default, tor, simulated, offline", diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_MacOS.json b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_MacOS.json index 684e78b99..1570912a1 100644 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_MacOS.json +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_MacOS.json @@ -32,6 +32,14 @@ "required": true, "defaultValue": "" }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" + }, { "name": "network_settings", "description": "Specifies the sandbox network_settings used for analysis : default, tor, simulated, offline", diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win10.json b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win10.json index d558bf622..08a057364 100644 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win10.json +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win10.json @@ -32,6 +32,14 @@ "required": true, "defaultValue": "" }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" + }, { "name": "network_settings", "description": "Specifies the sandbox network_settings used for analysis : default, tor, simulated, offline", diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win11.json b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win11.json index 9b6a70d8a..06db49be1 100644 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win11.json +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win11.json @@ -32,6 +32,14 @@ "required": true, "defaultValue": "" }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" + }, { "name": "network_settings", "description": "Specifies the sandbox network_settings used for analysis : default, tor, simulated, offline", diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win7.json b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win7.json index 0e22f239d..33bb8b885 100644 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win7.json +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win7.json @@ -32,6 +32,14 @@ "required": true, "defaultValue": "" }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" + }, { "name": "network_settings", "description": "Specifies the sandbox network_settings used for analysis : default, tor, simulated, offline", diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win7_64.json b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win7_64.json index 380b49b25..bcdaf0dc9 100644 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win7_64.json +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Win7_64.json @@ -32,6 +32,14 @@ "required": true, "defaultValue": "" }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" + }, { "name": "network_settings", "description": "Specifies the sandbox network_settings used for analysis : default, tor, simulated, offline", diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceAlerts.json b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceAlerts.json index 198e9a9f5..b51a89852 100644 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceAlerts.json +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceAlerts.json @@ -32,6 +32,14 @@ "required": true, "defaultValue": "" }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" + }, { "name": "alert_fields", "description": "Fields to return for each invidividual alerts", diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceAlerts.py b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceAlerts.py index 219008f1d..4a36242d5 100755 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceAlerts.py +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceAlerts.py @@ -10,6 +10,7 @@ def __init__(self): Analyzer.__init__(self) self.client_id = self.get_param("config.client_id") self.client_secret = self.get_param("config.client_secret") + self.base_url = self.get_param("config.base_url", "https://api.crowdstrike.com") self.alert_fields = self.get_param("config.alert_fields") self.days_before = self.get_param("config.days_before") @@ -17,7 +18,7 @@ def run(self): Analyzer.run(self) if self.data_type == 'hostname': try: - auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret) + auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret, base_url=self.base_url) # Define the custom header extra_headers = { "User-Agent": "strangebee-thehive/1.0" diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceDetails.json b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceDetails.json index a5f557c5e..6951fbe57 100644 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceDetails.json +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceDetails.json @@ -31,6 +31,14 @@ "multi": false, "required": true, "defaultValue": "" + }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" } ], "registration_required": true, diff --git a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceDetails.py b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceDetails.py index f18c63875..b650aa5ce 100755 --- a/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceDetails.py +++ b/analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceDetails.py @@ -11,12 +11,14 @@ def __init__(self): Analyzer.__init__(self) self.client_id = self.get_param("config.client_id") self.client_secret = self.get_param("config.client_secret") + self.base_url = self.get_param("config.base_url", "https://api.crowdstrike.com") + def run(self): Analyzer.run(self) if self.data_type == 'hostname': try: - auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret) + auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret, base_url=self.base_url) # Define the custom header extra_headers = { "User-Agent": "strangebee-thehive/1.0" diff --git a/responders/CrowdstrikeFalcon/CrowdStrikeFalcon_AddIOC.json b/responders/CrowdstrikeFalcon/CrowdStrikeFalcon_AddIOC.json index 51946e9a6..81c0b569a 100644 --- a/responders/CrowdstrikeFalcon/CrowdStrikeFalcon_AddIOC.json +++ b/responders/CrowdstrikeFalcon/CrowdStrikeFalcon_AddIOC.json @@ -30,6 +30,14 @@ "required": true, "defaultValue": "" }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" + }, { "name": "severity", "description": "Severity linked to the IoC - informational, low, medium, high, critical", diff --git a/responders/CrowdstrikeFalcon/CrowdStrikeFalcon_Sync.json b/responders/CrowdstrikeFalcon/CrowdStrikeFalcon_Sync.json index 2380e74e1..ae0b9da2a 100644 --- a/responders/CrowdstrikeFalcon/CrowdStrikeFalcon_Sync.json +++ b/responders/CrowdstrikeFalcon/CrowdStrikeFalcon_Sync.json @@ -30,6 +30,14 @@ "required": true, "defaultValue": "" }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" + }, { "name": "custom_field_name_alert_id", "description": "Custom field in TheHive containing the CSFalcon Alert ID", diff --git a/responders/CrowdstrikeFalcon/CrowdStrikeFalcon_removeIOC.json b/responders/CrowdstrikeFalcon/CrowdStrikeFalcon_removeIOC.json index ed02746ac..10016a0b8 100644 --- a/responders/CrowdstrikeFalcon/CrowdStrikeFalcon_removeIOC.json +++ b/responders/CrowdstrikeFalcon/CrowdStrikeFalcon_removeIOC.json @@ -29,6 +29,14 @@ "multi": false, "required": true, "defaultValue": "" + }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" } ], "registration_required": true, diff --git a/responders/CrowdstrikeFalcon/CrowdstrikeFalconHosts.py b/responders/CrowdstrikeFalcon/CrowdstrikeFalconHosts.py index 9e751ca37..09b3954ef 100755 --- a/responders/CrowdstrikeFalcon/CrowdstrikeFalconHosts.py +++ b/responders/CrowdstrikeFalcon/CrowdstrikeFalconHosts.py @@ -9,6 +9,8 @@ def __init__(self): self.client_id = self.get_param("config.client_id") self.client_secret = self.get_param("config.client_secret") self.service = self.get_param("config.service", None) + self.base_url = self.get_param("config.base_url", "https://api.crowdstrike.com") + def run(self): Responder.run(self) @@ -18,7 +20,7 @@ def run(self): extra_headers = { "User-Agent": "strangebee-thehive/1.0" } - auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret) + auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret, base_url=self.base_url) hosts = Hosts(auth_object=auth, ext_headers=extra_headers) # Search for the device ID using the hostname diff --git a/responders/CrowdstrikeFalcon/CrowdstrikeFalconIOC.py b/responders/CrowdstrikeFalcon/CrowdstrikeFalconIOC.py index 174a978da..57704c8f4 100755 --- a/responders/CrowdstrikeFalcon/CrowdstrikeFalconIOC.py +++ b/responders/CrowdstrikeFalcon/CrowdstrikeFalconIOC.py @@ -2,7 +2,7 @@ from cortexutils.responder import Responder import requests -from falconpy import IOC +from falconpy import OAuth2, IOC from datetime import datetime, timedelta import re from urllib.parse import urlparse @@ -12,6 +12,7 @@ def __init__(self): Responder.__init__(self) self.client_id = self.get_param("config.client_id") self.client_secret = self.get_param("config.client_secret") + self.base_url = self.get_param("config.base_url", "https://api.crowdstrike.com") self.service = self.get_param("config.service", None) self.platform_list = self.get_param("config.platform_list", []) self.host_groups_list = self.get_param("config.host_groups_list", []) @@ -83,7 +84,8 @@ def run(self): "User-Agent": "strangebee-thehive/1.0" } # Create the IOC service object - ioc = IOC(client_id=self.client_id, client_secret=self.client_secret, ext_headers=extra_headers) + auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret, base_url=self.base_url) + ioc = IOC(auth_object=auth, ext_headers=extra_headers) # Determine if the IOC applies globally or to specific host groups ioc_kwargs = { @@ -127,7 +129,8 @@ def run(self): "User-Agent": "strangebee-thehive/1.0" } # Create the IOC service object - ioc = IOC(client_id=self.client_id, client_secret=self.client_secret, ext_headers=extra_headers) + auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret, base_url=self.base_url) + ioc = IOC(auth_object=auth, ext_headers=extra_headers) # Search for the IOC by value response = ioc.indicator_search(filter=filter,offset=0, limit=200) diff --git a/responders/CrowdstrikeFalcon/CrowdstrikeFalconSync.py b/responders/CrowdstrikeFalcon/CrowdstrikeFalconSync.py index 83e5d111b..3d057167b 100755 --- a/responders/CrowdstrikeFalcon/CrowdstrikeFalconSync.py +++ b/responders/CrowdstrikeFalcon/CrowdstrikeFalconSync.py @@ -1,13 +1,14 @@ #!/usr/bin/env python3 from cortexutils.responder import Responder -from falconpy import Alerts, Incidents +from falconpy import OAuth2, Alerts, Incidents class CrowdstrikeFalconSync(Responder): def __init__(self): Responder.__init__(self) self.client_id = self.get_param("config.client_id") self.client_secret = self.get_param("config.client_secret") + self.base_url = self.get_param("config.base_url", "https://api.crowdstrike.com") self.service = self.get_param("config.service", None) self.custom_field_name_alert_id = self.get_param("config.custom_field_name_alert_id") self.custom_field_name_incident_id = self.get_param("config.custom_field_name_incident_id") @@ -47,10 +48,11 @@ def run(self): if current_stage not in status_mapping_alert: self.error(f"Unknown case status: {current_stage}") + auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret, base_url=self.base_url) # Update the CrowdStrike alert status if detection_id: - alert_client = Alerts(client_id=self.client_id, client_secret=self.client_secret, ext_headers=extra_headers) + alert_client = Alerts(auth_object=auth, ext_headers=extra_headers) # Determine the corresponding CrowdStrike alert status cs_status_alert = status_mapping_alert[current_stage] if isinstance(detection_id,str): @@ -70,7 +72,7 @@ def run(self): if incident_id: - incident_client = Incidents(client_id=self.client_id, client_secret=self.client_secret, ext_headers=extra_headers) + incident_client = Incidents(auth_object=auth, ext_headers=extra_headers) # Determine the corresponding CrowdStrike incident status cs_status_incident = status_mapping_incident[current_stage] if isinstance(incident_id,str): diff --git a/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_containHost.json b/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_containHost.json index 1298a9086..b0df32e31 100644 --- a/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_containHost.json +++ b/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_containHost.json @@ -29,6 +29,14 @@ "multi": false, "required": true, "defaultValue": "" + }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" } ], "registration_required": true, diff --git a/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_hideHost.json b/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_hideHost.json index 1a92a0c7e..fee369dc2 100644 --- a/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_hideHost.json +++ b/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_hideHost.json @@ -29,6 +29,14 @@ "multi": false, "required": true, "defaultValue": "" + }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" } ], "registration_required": true, diff --git a/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_liftContainmentHost.json b/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_liftContainmentHost.json index 9f7d8e82d..e46cb3c09 100644 --- a/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_liftContainmentHost.json +++ b/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_liftContainmentHost.json @@ -29,6 +29,14 @@ "multi": false, "required": true, "defaultValue": "" + }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" } ], "registration_required": true, diff --git a/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_suppressDetections.json b/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_suppressDetections.json index 81cfe8161..c7ac2c7b0 100644 --- a/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_suppressDetections.json +++ b/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_suppressDetections.json @@ -29,6 +29,14 @@ "multi": false, "required": true, "defaultValue": "" + }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" } ], "registration_required": true, diff --git a/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_unhideHost.json b/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_unhideHost.json index 23809e109..b6ae3332d 100644 --- a/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_unhideHost.json +++ b/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_unhideHost.json @@ -29,6 +29,14 @@ "multi": false, "required": true, "defaultValue": "" + }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" } ], "registration_required": true, diff --git a/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_unsuppressDetection.json b/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_unsuppressDetection.json index 88e2d5ab0..75660eeef 100644 --- a/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_unsuppressDetection.json +++ b/responders/CrowdstrikeFalcon/CrowdstrikeFalcon_unsuppressDetection.json @@ -29,6 +29,14 @@ "multi": false, "required": true, "defaultValue": "" + }, + { + "name": "base_url", + "description": "Crowdstrike base URL. Also supports US-1, US-2, EU-1, US-GOV-1 values", + "type": "string", + "multi": false, + "required": true, + "defaultValue": "https://api.crowdstrike.com" } ], "registration_required": true, From 251c68322c35d5b625ae96afb8083e34485ab681 Mon Sep 17 00:00:00 2001 From: nusantara-self <15647296+nusantara-self@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:50:52 +0800 Subject: [PATCH 3/7] flavor schema validation improvements --- utils/flavors/README.md | 40 +++++++++++++++++++++++++++++++- utils/flavors/flavor_schema.json | 5 +++- utils/flavors/requirements.txt | 1 + 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 utils/flavors/requirements.txt diff --git a/utils/flavors/README.md b/utils/flavors/README.md index 50c5c3b95..3fed16598 100644 --- a/utils/flavors/README.md +++ b/utils/flavors/README.md @@ -14,7 +14,6 @@ optional arguments: JSON Schema of a flavor ``` - ## Examples @@ -47,3 +46,42 @@ python3 utils/flavors/check_json_schema.py -f analyzers/SEKOIAIntelligenceCenter If you want to start writing an Analyzer or a Responder, or a new flavor, you can start with the appropriate template: - `analyzer_flavor_template.json` for an new flavor of an analyser - `responder_flavor_template.json` for a new flavor of a responder + +## Running with virtualenv + +### Create a Virtual Environment + +To ensure a clean and isolated environment for running the script: + +```bash +python3 -m venv env +``` + +### Activate the virtual environment + +- On Linux/MacOS: +``` +source env/bin/activate +``` +- On Windows: +``` +.\env\Scripts\activate +``` + +### Install Dependencies + +Install the required package +```bash +pip install -r requirements.txt +``` + +### Run the script +Execute the script explicitly using the Python interpreter from the virtual environment: +```bash +env/bin/python3 utils/flavors/check_json_schema.py -r +``` + +When done running, deactivate the virtual environment when you're done by running: +```bash +deactivate +``` \ No newline at end of file diff --git a/utils/flavors/flavor_schema.json b/utils/flavors/flavor_schema.json index 3e3145d50..cfb27cddc 100644 --- a/utils/flavors/flavor_schema.json +++ b/utils/flavors/flavor_schema.json @@ -34,7 +34,10 @@ "type": "object", "properties": { "service": { - "type": "string" + "type": [ + "number", + "string" + ] } } }, diff --git a/utils/flavors/requirements.txt b/utils/flavors/requirements.txt new file mode 100644 index 000000000..7b8f01584 --- /dev/null +++ b/utils/flavors/requirements.txt @@ -0,0 +1 @@ +jsonschema \ No newline at end of file From 1b31d4c433110585c346bb2f8a91fd6165cf6113 Mon Sep 17 00:00:00 2001 From: nusantara-self <15647296+nusantara-self@users.noreply.github.com> Date: Wed, 15 Jan 2025 12:46:45 +0800 Subject: [PATCH 4/7] Update README.md --- analyzers/ValidateObservable/README.md | 38 +++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/analyzers/ValidateObservable/README.md b/analyzers/ValidateObservable/README.md index 7eccc3ac0..6f57ac087 100644 --- a/analyzers/ValidateObservable/README.md +++ b/analyzers/ValidateObservable/README.md @@ -13,49 +13,49 @@ The **ValidateObservable** analyzer is designed to validate multiple observable ## Supported Data Types / Features 1. **IP Addresses** -- Validates individual IPs and CIDR ranges. -- Flags reserved, private, and loopback IPs with appropriate notes. + - Validates individual IPs and CIDR ranges. + - Flags reserved, private, and loopback IPs with appropriate notes. 2. **Domains** -- Detects valid domain names. -- Flags domains using Punycode (e.g., xn--) as suspicious. -- Identifies unusual characters in domain names. + - Detects valid domain names. + - Flags domains using Punycode (e.g., xn--) as suspicious. + - Identifies unusual characters in domain names. 3. **URLs** -- Validates URLs with or without schemes. -- Flags URLs containing Punycode domains or unusual characters as suspicious. -- Detects malformed URLs. + - Validates URLs with or without schemes. + - Flags URLs containing Punycode domains or unusual characters as suspicious. + - Detects malformed URLs. 4. **Fully Qualified Domain Names (FQDNs)** -- Validates FQDNs for proper structure and length. -- Flags FQDNs using Punycode and unusual characters as suspicious. + - Validates FQDNs for proper structure and length. + - Flags FQDNs using Punycode and unusual characters as suspicious. 5. **Emails** -- Checks email structure for validity. -- Detects unusual characters in email addresses. -- Validates against length constraints. + - Checks email structure for validity. + - Detects unusual characters in email addresses. + - Validates against length constraints. 6. **File Hashes** -- Validates MD5, SHA1, SHA256, and SHA512 hash formats. + - Validates MD5, SHA1, SHA256, and SHA512 hash formats. 7. **Filenames** -- Flags invalid characters in filenames (<, >, :, |, etc.). -- Detects multiple extensions (for example, .txt.exe) as suspicious. -- Identifies Unicode bidirectional override characters (U+202E, etc.) to prevent obfuscated extensions. + - Flags invalid characters in filenames (<, >, :, |, etc.). + - Detects multiple extensions (for example, .txt.exe) as suspicious. + - Identifies Unicode bidirectional override characters (U+202E, etc.) to prevent obfuscated extensions. 8. **URI Paths** -- Ensures paths start with / and are well-formed. + - Ensures paths start with / and are well-formed. 9. **User Agents** -- Checks for excessive length and control characters. + - Checks for excessive length and control characters. ## Special Features From 156689853d6642b7d7b1571843d75986a7a6d989 Mon Sep 17 00:00:00 2001 From: nusantara-self <15647296+nusantara-self@users.noreply.github.com> Date: Thu, 16 Jan 2025 09:58:46 +0800 Subject: [PATCH 5/7] test_doc utils improvements & README --- utils/test_doc/README.md | 26 +++++++++++++ utils/test_doc/testdoc-venv.sh | 70 ++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 utils/test_doc/README.md create mode 100755 utils/test_doc/testdoc-venv.sh diff --git a/utils/test_doc/README.md b/utils/test_doc/README.md new file mode 100644 index 000000000..681c8cefc --- /dev/null +++ b/utils/test_doc/README.md @@ -0,0 +1,26 @@ +# Cortex-Neurons local documentation preview + +This script renders the Cortex-Neurons documentation locally. + +## Usage + +1. Run the script from root directory Cortex-Analyzers +```bash +bash utils/test_doc/testdoc-venv.sh +``` + +2. View the documentation at http://0.0.0.0:8889 + +## Script Overview +The script performs the following actions: + +- Creates a test environment for documentation in a temporary folder. +- Copies necessary files and directories into the temporary folder. +- Sets up a Python virtual environment and installs dependencies from requirements.txt. +- Clones the doc-builder repository from GitHub if not already cloned. +- Runs the documentation generation script. +- Serves the generated documentation using MkDocs. +- Cleans up temporary files upon completion. + +## Notes +Ensure the script is ran from the root directory of the Cortex-Analyzers repository. \ No newline at end of file diff --git a/utils/test_doc/testdoc-venv.sh b/utils/test_doc/testdoc-venv.sh new file mode 100755 index 000000000..ef97f300d --- /dev/null +++ b/utils/test_doc/testdoc-venv.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# This program is for test purposes only, to ensure the documentation is generated as expected. +# This program should be run from the Cortex-Analyzers/ path only. + +ROOT_PATH="${PWD}" +TEST_PATH="./test_doc" +VENV_PATH="${ROOT_PATH}/venv" +REQUIREMENTS_FILE="${ROOT_PATH}/utils/test_doc/requirements.txt" + +# Cleanup function +cleanup() { + echo "Cleaning up temporary files..." + deactivate 2>/dev/null + cd "${ROOT_PATH}" || exit + rm -rf "${TEST_PATH}" +} +trap 'cleanup' EXIT + +# Create the test documentation path +mkdir -p "${TEST_PATH}" + +# Copy necessary directories and files +for I in analyzers responders assets images AUTHORS docs *.md; do + cp -rv "$I" "${TEST_PATH}" +done + +cd "${TEST_PATH}" || exit + +# Create a Python virtual environment if not already created +if [ ! -d "$VENV_PATH" ]; then + echo "Creating virtual environment..." + python3 -m venv "$VENV_PATH" +fi + +# Activate the virtual environment +source "${VENV_PATH}/bin/activate" + +# Ensure pip is updated +pip install --upgrade pip + +# Check and install dependencies from requirements.txt +if [ -f "$REQUIREMENTS_FILE" ]; then + echo "Installing dependencies from $REQUIREMENTS_FILE..." + pip install -r "$REQUIREMENTS_FILE" +else + echo "Error: $REQUIREMENTS_FILE not found!" + deactivate + exit 1 +fi + +# Clone the repository if not already cloned +if [ ! -d "doc-builder" ]; then + gh repo clone TheHive-Project/doc-builder +fi + +# Execute the generate script +python doc-builder/build/Cortex-Neurons/generate.py + +# Copy specific files to the docs folder +cp -v CHANGELOG.md docs/. +cp -v code_of_conduct.md docs/. +cp -v README.md docs/ +cp -v SECURITY.md docs/ +cp -v AUTHORS docs/AUTHORS.md + +# Serve documentation with mkdocs +mkdocs serve -a 0.0.0.0:8889 + +echo "Script execution completed!" From fbf3b7aa872bb04974d7a00d461a741bb193dde7 Mon Sep 17 00:00:00 2001 From: nusantara-self <15647296+nusantara-self@users.noreply.github.com> Date: Thu, 16 Jan 2025 15:42:10 +0800 Subject: [PATCH 6/7] Add build.sh --- utils/docker/build.sh | 74 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 utils/docker/build.sh diff --git a/utils/docker/build.sh b/utils/docker/build.sh new file mode 100644 index 000000000..4c2ab113d --- /dev/null +++ b/utils/docker/build.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +### +# This program assumes your analyzers and responders folder looks like: +# +# Custom-Analyzers +# ├── analyzers/ +# │ └── My_custom_analyzer/ +# └── responders/ +# └── My_custom_responder/ +# ├── customresponderflavor.json +# ├── Dockerfile +# ├── program.py* +# ├── README.md +# └── requirements.txt +# +# Usage: +# Update DOCKER_REPOSITORY variable +# cd ./Custom-Analyzers +# bash /path/to/build.sh +### + +# Set your docker repository name +DOCKER_REPOSITORY=ilovestrangebee + +build_image() { + JSON=$1 + cat << EOF > /tmp/default_dockerfile +FROM python:3 +WORKDIR /worker +ARG workername +ARG command +COPY . \$workername +RUN test ! -e \$workername/requirements.txt || pip install --no-cache-dir -r \$workername/requirements.txt +ENTRYPOINT \$command +EOF + + DEFAULT_DOCKERFILE=/tmp/default_dockerfile + TAG=`cat ${JSON} | jq -r '( "'"$DOCKER_REPOSITORY"'" + "/" + (.name | ascii_downcase) + ":" + (.version))'` + WORKER_NAME=`cat ${JSON} | jq -r '(.version)'` + COMMAND=`cat ${JSON} | jq -r '(.command)'` + DIRNAME=`dirname ${JSON}` + WORKER_NAME=`basename ${DIRNAME}` + if test -f ${DIRNAME}/Dockerfile + then + docker build -t ${TAG} `dirname ${JSON}` + else + docker build --build-arg workername=${WORKER_NAME} --build-arg command=${COMMAND} -f ${DEFAULT_DOCKERFILE} -t ${TAG} `dirname ${JSON}` + fi +} + +build_catalog() { + DIR=$1 + echo '[' > ${DIR}/${DIR}.json + + + first=1 + for JSON in ${DIR}/*/*.json + do + build_image ${JSON} + if test -z "${first}" + then + echo ',' >> ${DIR}/${DIR}.json + else + first= + fi + jq 'del(.command) + { dockerImage: ("'"$DOCKER_REPOSITORY"'" + "/" + (.name | ascii_downcase) + ":" + (.version)) }' ${JSON} >> ${DIR}/${DIR}.json + done + + echo ']' >> ${DIR}/${DIR}.json +} + +build_catalog analyzers +build_catalog responders \ No newline at end of file From f3073fa4fdefc4d70ade1da59e1163fb4b8bce58 Mon Sep 17 00:00:00 2001 From: nusantara-self <15647296+nusantara-self@users.noreply.github.com> Date: Thu, 16 Jan 2025 17:06:15 +0800 Subject: [PATCH 7/7] Update version and changelog for 3.4.3 --- CHANGELOG.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfd66fa07..627be6844 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ # Changelog -## [3.4.2](https://github.com/TheHive-Project/Cortex-Analyzers/tree/3.4.2) (2024-12-24) +## [3.4.3](https://github.com/TheHive-Project/Cortex-Analyzers/tree/3.4.2) (2025-01-16) + +[Full Changelog](https://github.com/TheHive-Project/Cortex-Analyzers/compare/3.4.2...3.4.3) + +**Closed issues:** + +- \[FR\] Crowdstrike Falcon: support custom base URL [\#1306](https://github.com/TheHive-Project/Cortex-Analyzers/issues/1309) + +**Merged pull requests:** + +- Crowdstrike Falcon - Custom Base URL support [\#1310](https://github.com/TheHive-Project/Cortex-Analyzers/pull/1310) ([nusantara-self](https://github.com/nusantara-self)) +- utils improvements [\#1311](https://github.com/TheHive-Project/Cortex-Analyzers/pull/1311) ([nusantara-self](https://github.com/nusantara-self)) + +## [3.4.2](https://github.com/TheHive-Project/Cortex-Analyzers/tree/3.4.2) (2024-12-26) [Full Changelog](https://github.com/TheHive-Project/Cortex-Analyzers/compare/3.4.1...3.4.2) @@ -10,6 +23,13 @@ - \[FR\] Analyzer for observable validation [\#1305](https://github.com/TheHive-Project/Cortex-Analyzers/issues/1305) - \[FR\] New Analyzer: Axur Ioc's \(WIP\) [\#1190](https://github.com/TheHive-Project/Cortex-Analyzers/issues/1190) +**Merged pull requests:** + +- Add ValidateObservable analyzer [\#1308](https://github.com/TheHive-Project/Cortex-Analyzers/pull/1308) ([nusantara-self](https://github.com/nusantara-self)) +- CrowdStrike Falcon - Implement TheHive custom user-agent across integrations [\#1307](https://github.com/TheHive-Project/Cortex-Analyzers/pull/1307) ([nusantara-self](https://github.com/nusantara-self)) +- feat\(c25\): adds cluster25's cortex analyzer [\#1241](https://github.com/TheHive-Project/Cortex-Analyzers/pull/1241) ([Mv35](https://github.com/Mv35)) +- Implemented Axur ioc's analyzer [\#1191](https://github.com/TheHive-Project/Cortex-Analyzers/pull/1191) ([Paulovgarcia](https://github.com/Paulovgarcia)) + ## [3.4.1](https://github.com/TheHive-Project/Cortex-Analyzers/tree/3.4.1) (2024-12-17) [Full Changelog](https://github.com/TheHive-Project/Cortex-Analyzers/compare/3.4.0...3.4.1)