This commit is contained in:
overcuriousity 2025-07-30 21:49:54 +02:00
parent dfa3a9fc53
commit e97f8d3a70

View File

@ -124,10 +124,20 @@ class MispAnalyzer(interface.BaseAnalyzer):
return []
try:
# For IP searches, query both ip-src and ip-dst
search_types = []
if attr.startswith("ip-"):
search_types = ["ip-src", "ip-dst"]
else:
search_types = [attr]
all_results = []
for search_type in search_types:
payload = {
"returnFormat": "json",
"value": value,
"type": attr,
"type": search_type,
"enforceWarninglist": False,
"includeEventTags": True,
"includeContext": True,
@ -141,10 +151,10 @@ class MispAnalyzer(interface.BaseAnalyzer):
"includeDecayScore": False,
"includeFullModel": False,
})
logger.debug(f"Community search enabled for {value} ({attr})")
logger.debug(f"Community search enabled for {value} ({search_type})")
else:
payload["distribution"] = [0]
logger.debug(f"Own org search only for {value} ({attr})")
logger.debug(f"Own org search only for {value} ({search_type})")
self.stats['api_calls'] += 1
@ -156,22 +166,25 @@ class MispAnalyzer(interface.BaseAnalyzer):
timeout=45,
)
if response.status_code != 200:
logger.debug(f"MISP API returned status {response.status_code} for {value}")
return []
if response.status_code == 200:
data = response.json()
attributes = data.get("response", {}).get("Attribute", [])
all_results.extend(attributes)
else:
logger.debug(f"MISP API returned status {response.status_code} for {value} ({search_type})")
if attributes and self.include_community:
# Small delay between search types
time.sleep(0.1)
if all_results and self.include_community:
orgs = set()
for attr_data in attributes:
for attr_data in all_results:
org = attr_data.get("Event", {}).get("Orgc", {}).get("name", "Unknown")
orgs.add(org)
if len(orgs) > 1 or (orgs and list(orgs)[0] not in ["Unknown", "Your Org"]):
logger.info(f"Community hit for {value}: {len(attributes)} matches from {', '.join(list(orgs)[:3])}")
logger.info(f"Community hit for {value}: {len(all_results)} matches from {', '.join(list(orgs)[:3])}")
return attributes
return all_results
except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
self.stats['api_timeouts'] += 1
@ -198,10 +211,8 @@ class MispAnalyzer(interface.BaseAnalyzer):
else:
msg = "MISP: Known indicator"
correlating_events = []
unique_events = {}
orgs = set()
event_ids = set()
event_links = []
for res in result:
event_info = res.get("Event", {})
@ -209,23 +220,31 @@ class MispAnalyzer(interface.BaseAnalyzer):
event_desc = event_info.get("info", "Unknown")
org_name = event_info.get("Orgc", {}).get("name", "Unknown")
if event_id and event_id not in event_ids:
event_ids.add(event_id)
short_desc = event_desc[:60] + "..." if len(event_desc) > 60 else event_desc
correlating_events.append(short_desc)
event_links.append(f"{self.misp_url}/events/view/{event_id}")
if event_id and event_id not in unique_events:
unique_events[event_id] = {
'description': event_desc,
'url': f"{self.misp_url}/events/view/{event_id}"
}
if org_name != "Unknown":
orgs.add(org_name)
if len(correlating_events) == 1:
msg += f" | Event: {correlating_events[0]}"
elif len(correlating_events) > 1:
msg += f" | Events: {correlating_events[0]}"
if len(correlating_events) > 1:
msg += f" + {correlating_events[1]}"
if len(correlating_events) > 2:
msg += f" + {len(correlating_events)-2} more"
unique_event_list = list(unique_events.values())
if len(unique_event_list) == 1:
event_data = unique_event_list[0]
short_desc = event_data['description'][:50] + "..." if len(event_data['description']) > 50 else event_data['description']
msg += f" | Event: {short_desc} | Link: {event_data['url']}"
elif len(unique_event_list) > 1:
msg += f" | {len(unique_event_list)} Events:"
for i, event_data in enumerate(unique_event_list[:2]):
short_desc = event_data['description'][:40] + "..." if len(event_data['description']) > 40 else event_data['description']
msg += f" [{i+1}] {short_desc} ({event_data['url']})"
if i < len(unique_event_list) - 1 and i < 1:
msg += " |"
if len(unique_event_list) > 2:
msg += f" | +{len(unique_event_list)-2} more events"
if self.include_community and orgs:
if len(orgs) > 1:
@ -236,22 +255,12 @@ class MispAnalyzer(interface.BaseAnalyzer):
msg += f" | Source: {list(orgs)[0]}"
if len(result) > 1:
msg += f" | {len(result)} correlations"
if event_links:
if len(event_links) == 1:
msg += f" | MISP Event: {event_links[0]}"
else:
msg += f" | MISP Events: {event_links[0]}"
if len(event_links) > 1:
msg += f", {event_links[1]}"
if len(event_links) > 2:
msg += f" +{len(event_links)-2} more"
msg += f" | {len(result)} total correlations"
tags = [f"MISP-{attr}", "threat-intel"]
if self.include_community:
tags.append("community-intel")
if len(correlating_events) > 1:
if len(unique_event_list) > 1:
tags.append("multi-event-correlation")
event.add_comment(msg)
@ -260,7 +269,7 @@ class MispAnalyzer(interface.BaseAnalyzer):
self.stats['events_marked'] += 1
logger.info(f"Marked event with {len(correlating_events)} correlating MISP events: {', '.join(correlating_events[:3])}")
logger.info(f"Marked event with {len(unique_event_list)} unique MISP events")
except Exception as e:
logger.error(f"Error marking event: {e}")