Detection rules › Panther
Panther rules: malicious
| Rule | Severity |
|---|---|
| Malicious SSO DNS Lookup | medium |
Malicious SSO DNS Lookup
#The rule looks for DNS requests to sites potentially posing as SSO domains.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Detection logic
"""
We highly recommend running this logic over 30 days of historical data using data replay
before enabling this in your Panther instance. If ALLOWED_DOMAINS is not fully populated with
domains you own, that contain your company name, false positive alerts will be generated.
Recommended steps to enable:
1. Change COMPANY_NAME to match your organization
2. Update the occurrences of "company_name_here" in malicious_sso_dns_lookup.yml
3. Add known domains containing COMPANY_NAME to ALLOWED_DOMAINS
4. Run local tests
5. Run a Data Replay test to identify unknown domains that should be in ALLOWED_DOMAINS
"""
from panther_crowdstrike_fdr_helpers import filter_crowdstrike_fdr_event_type
# *** Change this to match your company name ***
COMPANY_NAME = "company_name_here"
# Ref: https://blog.group-ib.com/0ktapus
FAKE_KEYWORDS = [
"sso",
"okta",
"corp",
"vpn",
"citrix",
"help",
"edge",
]
# Add known good domains that contain your company name
ALLOWED_DOMAINS = [
".amazonaws.com",
".okta.com",
".oktapreview.com",
# "COMPANY.com",
]
def rule(event):
# We need to run either for Crowdstrike.DnsRequest or for DnsRequest.FDREvent of 'DnsRequest'
# type. Crowdstrike.DnsRequest is covered because of the association with the type
if filter_crowdstrike_fdr_event_type(event, "DnsRequest"):
return False
# check domain for company name AND a fake keyword
for domain in event.get("p_any_domain_names", []):
domain_was_allowed = [x for x in ALLOWED_DOMAINS if domain.lower().endswith(x)]
if domain_was_allowed:
continue
if COMPANY_NAME in domain.lower():
fake_matches = [x for x in FAKE_KEYWORDS if x in domain.lower()]
if fake_matches:
return True
# The domain did not have a fake keyword and the company name
return False
def title(event):
return (
f"Potential Malicious SSO Domain - {event.get('p_any_domain_names',['NO_DOMAINs_FOUND'])}"
)
Rule specification
AnalysisType: rule
Filename: malicious_sso_dns_lookup.py
RuleID: "Standard.MaliciousSSODNSLookup"
DedupPeriodMinutes: 1440 # dedup & threshold is high to prevent alert storms from FPs
DisplayName: "Malicious SSO DNS Lookup"
Enabled: false
LogTypes:
- CiscoUmbrella.DNS
- Crowdstrike.DNSRequest
- Crowdstrike.FDREvent
- Suricata.DNS
- Zeek.DNS
Severity: Medium
Threshold: 1000 # dedup & threshold is high to prevent alert storms from FPs
Tags:
- Configuration Required
Reports:
MITRE ATT&CK:
- TA0001:T1566
Description: The rule looks for DNS requests to sites potentially posing as SSO domains.
Runbook: Verify if the destination domain is owned by your organization.
Reference: https://www.cloudns.net/wiki/article/254/#:~:text=A%20DNS%20query%20(also%20known,associated%20with%20a%20domain%20name
SummaryAttributes:
- p_any_ip_addresses
Stages and Predicates
Fires on CiscoUmbrella.DNS, Crowdstrike.DNSRequest, Crowdstrike.FDREvent (and 2 more) events when any of the conditions below holds.
Condition
any of:
p_log_typeis notCrowdstrike.FDREventfdr_event_typeisDnsRequest
This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
fdr_event_type | ne | DnsRequest | excludes:fdr_event_type field:"fdr_event_type" value:"DnsRequest" |
p_log_type | eq | Crowdstrike.FDREvent | excludes:p_log_type field:"p_log_type" value:"Crowdstrike.FDREvent" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
fdr_event_type | eq |
| field:"fdr_event_type" kind:eq value:"DnsRequest" |
p_log_type | ne |
| field:"p_log_type" kind:ne value:"Crowdstrike.FDREvent" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field |
|---|
p_any_domain_names |
Response runbook
Verify if the destination domain is owned by your organization.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"ContextProcessId": "440890253753908704",
"ContextThreadId": "0",
"ContextTimeStamp": "2022-08-31 07:03:48.879",
"DomainName": "company_name_here-okta.com",
"EffectiveTransmissionClass": 2,
"Entitlements": "15",
"RequestType": "1",
"event_platform": "Mac",
"event_simpleName": "DnsRequest",
"name": "DnsRequestMacV2",
"p_any_domain_names": [
"company_name_here-okta.com"
],
"timestamp": "2022-08-31 07:03:49.195"
}