Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Analyzers & Responders for CrowdstrikeFalcon #1297

Merged
merged 3 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"name": "CrowdstrikeFalcon_GetDeviceVulnerabilities",
"version": "1.0",
"author": "nusantara-self, StrangeBee",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "AGPL-V3",
"baseConfig": "CrowdstrikeFalcon",
"config": {
"check_tlp": false,
"max_tlp": 3,
"service": ""
},
"description": "Get device vulnerabilities from hostname",
"dataTypeList": [
"hostname"
],
"command": "CrowdstrikeFalcon/CrowdstrikeFalcon_getDeviceVulnerabilities.py",
"configurationItems": [
{
"name": "client_id",
"description": "Crowdstrike client ID key",
"type": "string",
"multi": false,
"required": true,
"defaultValue": ""
},
{
"name": "client_secret",
"description": "Crowdstrike client secret key",
"type": "string",
"multi": false,
"required": true,
"defaultValue": ""
},
{
"name": "vuln_fields",
"description": "Specific field values to keep in resulting payload for vulnerabilities",
"type": "string",
"multi": true,
"required": true,
"defaultValue": [
"vulnerability_id",
"status",
"created_timestamp",
"updated_timestamp",
"apps.product_name_version",
"confidence",
"cve",
"host_info.asset_criticality",
"host_info.internet_exposure",
"remediation.entities.action"
]
}
],
"registration_required": true,
"subscription_required": true,
"free_subscription": false,
"service_homepage": "https://www.crowdstrike.com",
"service_logo": {
"path": "assets/crowdstrike.png",
"caption": "Crowdstrike logo"
},
"screenshots": [
{
"path": "assets/short-report-vulns.png",
"caption": "Crowdstrike: Short report template"
},
{
"path": "assets/long-report-vulns.png",
"caption": "Crowdstrike: Long report template"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/usr/bin/env python3
# encoding: utf-8
from cortexutils.analyzer import Analyzer
from falconpy import OAuth2
from falconpy import Hosts
from falconpy import SpotlightVulnerabilities


class CrowdstrikeFalcon_GetDeviceVulnerabilities(Analyzer):
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.vuln_fields = self.get_param("config.vuln_fields", [])



def run(self):
Analyzer.run(self)
if self.data_type == 'hostname':
try:
auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret)
hosts = Hosts(auth_object=auth)
hostname = self.get_data()

# Search for the device ID using the hostname
response = hosts.query_devices_by_filter(filter=f"hostname:'{hostname}'")
device_ids = response["body"]["resources"]

# Check the response
status_code = response["status_code"]
if status_code != 200 :
self.error(f"No devices found with hostname: {hostname} -- {status_code}")

if device_ids:
device_id = device_ids[0]
# Get detailed asset information using the device ID
spotlight = SpotlightVulnerabilities(auth_object=auth)
host_vulns = spotlight.query_vulnerabilities_combined(parameters={"filter": f"aid:'{device_id}'+status:!'closed'"})
host_vulns = host_vulns["body"]["resources"]
#print(host_vulns)
vuln_details = []
products_with_vulns = {}
for vuln in host_vulns:
product_name = vuln["apps"][0]["product_name_normalized"]
vuln_id = vuln["id"]

if product_name not in products_with_vulns:
products_with_vulns[product_name] = []

products_with_vulns[product_name].append(vuln_id)
for key, vuln_ids in products_with_vulns.items():
for vuln_id in vuln_ids:
request = spotlight.get_vulnerabilities(vuln_id)
data = request["body"]["resources"][0]
# Filter the dictionary
#filtered_data = {key: data[key] for key in top_10_keys if key in data}
filtered_data = self.filter_dict(data, self.vuln_fields)
vuln_details.append(filtered_data)
self.report({"message": vuln_details})
except Exception as e:
self.unexpectedError(e)
else:
self.notSupported()

def filter_dict(self, d, keys):
filtered = {}
for key in keys:
parts = key.split(".")
if len(parts) == 3:
main_key, sub_key, sub_sub_key = parts
if main_key in d and sub_key in d[main_key]:
filtered.setdefault(main_key, {}).setdefault(sub_key, [])
for entity in d[main_key][sub_key]:
filtered[main_key][sub_key].append({sub_sub_key: entity[sub_sub_key]})
elif len(parts) == 2:
main_key, sub_key = parts
if main_key in d and sub_key in d[main_key]:
filtered.setdefault(main_key, {})[sub_key] = d[main_key][sub_key]
elif len(parts) == 1:
main_key = parts[0]
if main_key in d:
filtered[main_key] = d[main_key]
return filtered

def summary(self, raw):
taxonomies = []
level = "safe"
namespace = "CSFalcon"
predicate = "VulnDetails"

count_vulns = len(raw["message"])
if count_vulns > 0:
level = "suspicious"
for vuln in raw["message"]:
if vuln["cve"]["base_score"] >= 7:
level = "malicious"

# Build summary
taxonomies.append(
self.build_taxonomy(
level, namespace, predicate, str(count_vulns)
)
)
return {"taxonomies": taxonomies}

def artifacts(self, raw):
artifacts = []
#artifacts.append(self.build_artifact("ip",raw["external_ip"],tags=["hostname=" + raw["hostname"], "external_ip"]))
return artifacts


if __name__ == "__main__":
CrowdstrikeFalcon_GetDeviceVulnerabilities().run()
121 changes: 121 additions & 0 deletions analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#!/usr/bin/env python3
# encoding: utf-8
from os.path import basename
from cortexutils.analyzer import Analyzer
from falconpy import FalconXSandbox, SampleUploads, OAuth2
import time



class CrowdstrikeFalcon_Sandbox(Analyzer):
def __init__(self):
Analyzer.__init__(self)
# filename of the observable
self.filename = self.getParam("attachment.name", "noname.ext")
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.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")

def run(self):
Analyzer.run(self)

# file analysis
if self.data_type == 'file':
filepath = self.get_param('file', None, 'File is missing')
filename = self.get_param('filename', basename(filepath))
comment = f"Submitted from TheHive"
# additional_params = {
# "action_script": "default",
# "command_line": "",
# "document_password": "",
# "environment_id": 160,
# "network_settings": "default",
# "send_email_notifications": False,
# "submit_name": filename,
# "submit_date": "2024-08-01",
# "submit_time": "12:00:00",
# "user_tags": ["test", "sample"]
# }

additional_params = {
"environment_id": self.environment,
"submit_name": filename,
"network_settings": self.network_settings,
"action_script": self.action_script
}

with open(filepath, "rb") as sample:
auth = OAuth2(client_id=self.client_id, client_secret=self.client_secret)
samples = SampleUploads(auth_object=auth)
sandbox = FalconXSandbox(auth_object=auth)
response = samples.upload_sample(file_data=sample.read(),
file_name=filename,
comment=comment,
is_confidential=True
)
#response = falconx.query_sample()

#response = falconx.submit(file_name=filename, file_data=sample, **additional_params)

# Check the response
if response["status_code"] in [200, 201] :
#message = f"File uploaded successfully! Submission ID : {response['body']["resources"]}"
sha256 = response['body']["resources"][0]["sha256"]
submit_response = sandbox.submit(body={
"sandbox": [{
"sha256": sha256,
**additional_params
}]
})

message = f"File submitted successfully for ! Submission ID : {submit_response}"

## Check status of on-going scan
status = "running"
while status == "running":
submit_id = submit_response["body"]["resources"][0]["id"]
scan_status = sandbox.get_submissions(ids=submit_id)
if scan_status["body"]["resources"]:
status = scan_status["body"]["resources"][0]["state"]

analysis_result = sandbox.get_reports(ids=submit_id)
message = analysis_result['body']
else:
self.error(f"Error uploading file: {response} and {filepath} and {sample} and {filename}")
self.report(message)
else:
self.error("Datatype is not file")

def summary(self, raw):
taxonomies = []

level = "info"
namespace = "CSFalcon"
predicate = "Sandbox"

value = raw["resources"][0]["verdict"]

if value == "suspicious":
level = "suspicious"
elif value == "malicious":
level = "malicious"
elif value == "no specific threat":
level = "safe"

# Build summary
taxonomies.append(
self.build_taxonomy(
level, namespace, predicate, value
)
)
return {"taxonomies": taxonomies}

def artifacts(self, raw):
artifacts = []
return artifacts

if __name__ == "__main__":
CrowdstrikeFalcon_Sandbox().run()
70 changes: 70 additions & 0 deletions analyzers/CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox_Android.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"name": "CrowdstrikeFalcon_Sandbox_Android",
"version": "1.0",
"author": "nusantara-self, StrangeBee",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "AGPL-V3",
"baseConfig": "CrowdstrikeFalcon",
"config": {
"check_tlp": false,
"max_tlp": 3,
"service": 200
},
"description": "Send a file to CrowdstrikeFalcon Sandbox",
"dataTypeList": [
"file"
],
"command": "CrowdstrikeFalcon/CrowdstrikeFalcon_Sandbox.py",
"configurationItems": [
{
"name": "client_id",
"description": "Crowdstrike client ID key",
"type": "string",
"multi": false,
"required": true,
"defaultValue": ""
},
{
"name": "client_secret",
"description": "Crowdstrike client secret key",
"type": "string",
"multi": false,
"required": true,
"defaultValue": ""
},
{
"name": "network_settings",
"description": "Specifies the sandbox network_settings used for analysis : default, tor, simulated, offline",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "default"
},
{
"name": "action_script",
"description": "Runtime script for sandbox analysis : default, default_randomtheme, default_maxantievasion, default_openie, default_randomfiles",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "default"
}
],
"registration_required": true,
"subscription_required": true,
"free_subscription": false,
"service_homepage": "https://www.crowdstrike.com",
"service_logo": {
"path": "assets/crowdstrike.png",
"caption": "Crowdstrike logo"
},
"screenshots": [
{
"path": "assets/short-report-sandbox.png",
"caption": "Crowdstrike: Short report template"
},
{
"path": "assets/long-report-sandbox.png",
"caption": "Crowdstrike: Long report template"
}
]
}
Loading