How can I adapt my custom Panther CrowdStrike detections and queries to work with the Crowdstrike.FDREvent log type?
QUESTION
How can I adapt my existing custom CrowdStrike detections and queries so that they work seamlessly with the Crowdstrike.FDREvent log type?
ANSWER
Detections
Get the value for a field
To get the value for a field (regardless of whether it is present as a top-level field, nested under unknown_payload
(Crowdstrike.Unknown
) or nested under event
in Crowdstrike.FDREvent)
the following helper can be used:
from panther_base_helpers import get_crowdstrike_field
The following condition will work seamlessly for both Crowdstrike.ProcessRollup2
and Crowdstrike.FDREvent
with fdr_event_type
→ ProcessRollup2
:
if "curl" in get_crowdstrike_field("CommandLine", ""):
Note that key lookups are case-insensitive: commandline, commandLine and CommandLine will all fetch the same field value.
Filtering
Detections associated with Crowdstrike.FDREvent
and other log types will need to introduce filtering based on fdr_event_type
field value, when it is present.
For example, a detection associated with both Crowdstrike.DNSRequest
and Crowdstrike.FDREvent
will need to use the following condition, since it will be called for every CrowdStrike event:
def rule(event): if ( event.get("p_log_type") == "Crowdstrike.FDREvent" and event.get("fdr_event_type", "") != "DnsRequest" ): return False
For an application of the above, you can review the Crowdstrike.DNS.Request detection, annotated here with comments explaining the logic step-by-step:
from panther_base_helpers import get_crowdstrike_field # baddomain.com is present for testing purposes. Add domains you wish to be alerted on to this list DENYLIST = ["baddomain.com"] def rule(event): # If the log type is Crowdstrike.FDREvent but the event type is not DnsRequest, # the rule should not run thus we return early. if ( event.get("p_log_type") == "Crowdstrike.FDREvent" and event.get("fdr_event_type", "") != "DnsRequest" ): return False # The following call returns the value for the DomainName field for DnsRequest events, regardless of log type: # - For log type Crowdstrike.FDREvent -> {"p_log_type": "Crowdstrike.FDREvent", "event": {"DomainName": "example.com"}} # - For log type Crowdstrike.DNSRequest -> {"p_log_type": "Crowdstrike.DNSRequest", "DomainName": "example.com"} if get_crowdstrike_field(event, "DomainName") in DENYLIST: return True return False
Queries
The following list contains CrowdStrike Managed Queries and their counterpart for the Crowdstrike.FDREvent datalake table.
- AWS Authentication from CrowdStrike Unmanaged Device
- CrowdStrike Large Zip Creation
- MacOS Browser Credential Access
Filter records for a given event type
Queries on event-type-specific tables such crowdstrike_processrollup2
must now include a condition on the fdr_event_type
field in order to filter records that belong to the given event type:
SELECT DISTINCT aid FROM crowdstrike_processrollup2 WHERE commandline LIKE '%curl%'
SELECT DISTINCT aid FROM crowdstrike_fdrevent WHERE fdr_event_type = 'ProcessRollup2' AND event:CommandLine LIKE '%curl%'
Nested element names are case-sensitive. See Snowflake documentation for accessing semi-structured data.
Fields nested under event
Queries that were previously referencing fields that are now nested under event
must be duplicated/updated according to the new structure. For example:
SELECT commandline FROM crowdstrike_processrollup2 WHERE commandline LIKE '%curl%'
SELECT event:CommandLine FROM crowdstrike_fdrevent WHERE fdr_event_type = 'ProcessRollup2' AND event:CommandLine LIKE '%curl%'
Joining between tables
SELECT zips.*, pr2.TargetProcessId, pr2.CommandLine FROM crowdstrike_unknown AS zips LEFT JOIN crowdstrike_processrollup2 pr2 ON zips.ContextProcessId = pr2.targetprocessid WHERE zips.event_simpleName IN ( 'GzipFileWritten', 'SevenZipFileWritten', 'ZipFileWritten', 'BZip2FileWritten' ) AND CAST(unknown_payload:Size as integer) > 10000000
SELECT zips.*, pr2.event:TargetProcessId, pr2.event:CommandLine FROM crowdstrike_fdrevent AS zips LEFT JOIN crowdstrike_fdrevent pr2 ON zips.ContextProcessId = pr2.event:TargetProcessId WHERE zips.fdr_event_type IN ( 'GzipFileWritten', 'SevenZipFileWritten', 'ZipFileWritten', 'BZip2FileWritten' ) AND CAST(zips.event:Size as integer) > 10000000