-
Notifications
You must be signed in to change notification settings - Fork 527
[crowdstrike] Fix/5309 Crowdstrike intrusion set name resolution #5410
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
base: master
Are you sure you want to change the base?
[crowdstrike] Fix/5309 Crowdstrike intrusion set name resolution #5410
Conversation
instead of slugs Added debug and warning logs for actor resolution process
Kakudou
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi,
Thanks for the PR.
Unfortunately, I have to mark it as "Request Changes" for a few reasons.
The first and most important one:
Those fixes do not seem to work. I still see intrusion names being created using the slug/id name.
They were retrieved using the "indicator" scope only.

Regarding the report part, it feels over-engineered and contains a lot of unused code.
I was unable to reach that code path, even after ingesting a full day of historical data.
Could you provide some insight about your configuration for this part, so I can retrieve the same dataset as you and observe the same behavior?
| elif isinstance(actor, str) and actor: | ||
| if actor in self._actor_cache: | ||
| actor_entity = self._actor_cache[actor] | ||
| elif self.actor_resolver is not None: | ||
| try: | ||
| actor_entity = self.actor_resolver(actor) | ||
| except Exception: | ||
| logger.exception("Failed to resolve actor identifier '%s'", actor) | ||
| actor_entity = None | ||
| self._actor_cache[actor] = actor_entity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've let the ingestion running on a long time (timestamp at 0), to be able to catch that case.
Was unable to enter that elif, feel a little like overengineered, since the case doesn't look like to occurs on my side.
Where you able to trigger it ? Any insight on the conf/dataset you are using, so i can replicate that on my side ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. To me, this part of the code is unnecessary because "actors" always seems to be represented as a dict and contain all the information we need (especially the name) when retrieving reports.
| related_indicators_with_related_entities, | ||
| self.report_guess_relations, | ||
| malwares_from_field=malwares_from_field, | ||
| actor_resolver=self.reports_api_cs.get_actor_entity_by_id, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As all previous comments, look overengineered, wasn't able to go through it a single time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. To me, this part of the code is unnecessary because "actors" always seems to be represented as a dictionary and contain all the information we need (especially the name) when retrieving reports.
| # NOTE: FalconPy Intel exposes GetIntelActorEntities; the underlying client is `self.cs_intel`. | ||
| # The response is expected to be a dict with a `body` that contains `resources`. | ||
| response = self.cs_intel.get_intel_actor_entities( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like the previous comment, i never enter the 'actor_resolver' and so this method is never called.
But also, feel like get_intel_actor_entities don't exist on the falconpy, as we can see:
https://www.falconpy.io/Service-Collections/Intel.html?highlight=GetIntelActor#getintelactorentities

look like you should have used get_actor_entities instead.
But once again, in my tests cases, i've never encounter any reports going through 'actor_resolver'
| # Reports may provide actors as either full actor entities (dict) or as | ||
| # CrowdStrike actor identifiers (str). For identifiers, resolve via the | ||
| # provided resolver (if any) to get the canonical actor name. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was unable to verify that statement, leading to a lot of 'unused code' for my review.
I need more insight on how to trigger that.
And was unable to get one matching elif isinstance(actor, str) and actor
| if fields is None: | ||
| # Start with basic – can switch to "__full__" if you need more. | ||
| fields = ["__basic__"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if not cleaned_slugs: | ||
| return "" | ||
|
|
||
| conditions = [f"name:'{slug}'" for slug in cleaned_slugs] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
| fql_filter = self.build_slug_filter(cleaned_slugs) | ||
|
|
||
| return self.get_combined_actor_entities( |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.





Summary
Fixes #5309 by ensuring we do not use CrowdStrike actor identifiers (e.g.,
LABYRINTHCHOLLIMA) as Intrusion Set names when processingactorsassociations found in collections likeindicators,reports,yara_master, andsnort_suricata_master.Instead, when an object payload includes
actors: ["<CS_ACTOR_ID>"], we resolve that identifier to the actor's canonical display name (and aliases where relevant) via CrowdStrike’s actor entity endpoint and use that name consistently when creating/updating the corresponding Intrusion Set. oai_citation:1‡e50b7e94-e625-496a-bef8-d88e8175f5d9_CrowdStrike_Connector_Issues.pdfProblem
Multiple collections return an
actorsfield containing CrowdStrike internal actor IDs, not the human-readable name. The connector previously treated the value as the Intrusion Set name, which led to Intrusion Sets being renamed back and forth:This broke entity stability and enrichment workflows dependent on consistent STIX IDs.
Changes
actors[]to canonical actor names before creating/updating Intrusion Sets.Why this approach
CrowdStrike’s
actorsarray contains identifiers, and the correct name must be retrieved by querying the actor definition endpoint (GetIntelActorEntities). This makes the Intrusion Set naming stable across all collections while remaining faithful to the source.Testing
Manual / functional verification:
actors: ["<CS_ACTOR_ID>"]Logs:
Notes / Follow-ups