The hypothesis is that adversaries are using known Forest Blizzard group domains to establish command and control channels, leveraging domain name resolution to exfiltrate data and maintain persistence. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify and mitigate potential advanced persistent threats leveraging these known malicious domains.
KQL Query
let DomainNames = dynamic(["irf.services","microsoft-onthehub.com","msofficelab.com","com-mailbox.com","my-sharefile.com","my-sharepoints.com",
"accounts-web-mail.com","customer-certificate.com","session-users-activities.com","user-profile-credentials.com","verify-linke.com","support-servics.net",
"onedrive-sharedfile.com","onedrv-live.com","transparencyinternational-my-sharepoint.com","transparencyinternational-my-sharepoints.com","soros-my-sharepoint.com"]);
(union isfuzzy=true
(CommonSecurityLog
| where Message has_any (DomainNames)
| parse Message with * '(' DNSName ')' *
| extend AccountName = SourceUserID, DeviceName, IPAddress = SourceIP
),
(_Im_Dns(domain_has_any=DomainNames)
| where DnsQuery has_any (DomainNames)
| extend IPAddress = SrcIpAddr, DeviceName = Dvc
),
(VMConnection
| where RemoteDnsCanonicalNames has_any (DomainNames)
| parse RemoteDnsCanonicalNames with * '["' DNSName '"]' *
| extend IPAddress = RemoteIp, DeviceName = Computer
),
(AzureDiagnostics
| where ResourceType == "AZUREFIREWALLS"
| where Category == "AzureFirewallApplicationRule"
| parse msg_s with Protocol 'request from ' SourceHost ':' SourcePort 'to ' DestinationHost ':' DestinationPort '. Action:' Action
| where DestinationHost has_any (DomainNames)
| extend DNSName = DestinationHost
| extend IPAddress = SourceHost
),
(AzureDiagnostics
| where ResourceType == "AZUREFIREWALLS"
| where Category == "AzureFirewallDnsProxy"
| project TimeGenerated,Resource, msg_s, Type
| parse msg_s with "DNS Request: " ClientIP ":" ClientPort " - " QueryID " " Request_Type " " Request_Class " " Request_Name ". " Request_Protocol " " Request_Size " " EDNSO_DO " " EDNS0_Buffersize " " Responce_Code " " Responce_Flags " " Responce_Size " " Response_Duration
| where Request_Name has_any (DomainNames)
| extend DNSName = Request_Name
| extend IPAddress = ClientIP
),
(AZFWApplicationRule
| where isnotempty(Fqdn)
| where Fqdn has_any (DomainNames)
| extend DNSName = Fqdn
| extend IPAddress = SourceIp
),
(AZFWDnsQuery
| where isnotempty(QueryName)
| where QueryName has_any (DomainNames)
| extend DNSName = QueryName
| extend IPAddress = SourceIp
),
(
_Im_WebSession(url_has_any=DomainNames)
| extend IPAddress=IpAddr, DeviceName=Hostname, AccountName = tostring(split(User, "@")[0]), AccountDomain = tostring(split(User, "@")[1])
)
)
| where DNSName has_any (DomainNames)
| extend timestamp = TimeGenerated
| extend HostName = tostring(split(DeviceName, ".")[0]), DomainIndex = toint(indexof(DeviceName, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(DeviceName, DomainIndex + 1), DeviceName)
id: 074ce265-f684-41cd-af07-613c5f3e6d0d
name: Known Forest Blizzard group domains - July 2019
description: |
'Matches domain name IOCs related to Forest Blizzard group activity published July 2019 with CommonSecurityLog, DnsEvents and VMConnection dataTypes.
References: https://blogs.microsoft.com/on-the-issues/2019/07/17/new-cyberthreats-require-new-ways-to-protect-democracy/.'
severity: High
tags:
- Schema: ASIMDns
SchemaVersion: 0.1.1
requiredDataConnectors:
- connectorId: DNS
dataTypes:
- DnsEvents
- connectorId: AzureMonitor(VMInsights)
dataTypes:
- VMConnection
- connectorId: CiscoASA
dataTypes:
- CommonSecurityLog
- connectorId: PaloAltoNetworks
dataTypes:
- CommonSecurityLog
- connectorId: AzureFirewall
dataTypes:
- AzureDiagnostics
- AZFWApplicationRule
- AZFWDnsQuery
- connectorId: Zscaler
dataTypes:
- CommonSecurityLog
- connectorId: InfobloxNIOS
dataTypes:
- Syslog
- connectorId: GCPDNSDataConnector
dataTypes:
- GCP_DNS_CL
- connectorId: NXLogDnsLogs
dataTypes:
- NXLog_DNS_Server_CL
- connectorId: CiscoUmbrellaDataConnector
dataTypes:
- Cisco_Umbrella_dns_CL
- connectorId: Corelight
dataTypes:
- Corelight_CL
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- CommandAndControl
relevantTechniques:
- T1071
query: |
let DomainNames = dynamic(["irf.services","microsoft-onthehub.com","msofficelab.com","com-mailbox.com","my-sharefile.com","my-sharepoints.com",
"accounts-web-mail.com","customer-certificate.com","session-users-activities.com","user-profile-credentials.com","verify-linke.com","support-servics.net",
"onedrive-sharedfile.com","onedrv-live.com","transparencyinternational-my-sharepoint.com","transparencyinternational-my-sharepoints.com","soros-my-sharepoint.com"]);
(union isfuzzy=true
(CommonSecurityLog
| where Message has_any (DomainNames)
| parse Message with * '(' DNSName ')' *
| extend AccountName = SourceUserID, DeviceName, IPAddress = SourceIP
),
(_Im_Dns(domain_has_any=DomainNames)
| where DnsQuery has_any (DomainNames)
| extend IPAddress = SrcIpAddr, DeviceName = Dvc
),
(VMConnection
| where RemoteDnsCanonicalNames has_any (DomainNames)
| parse RemoteDnsCanonicalNames with * '["' DNSName '"]' *
| extend IPAddress = RemoteIp, DeviceName = Computer
),
(AzureDiagnostics
| where ResourceType == "AZUREFIREWALLS"
| where Category == "AzureFirewallApplicationRule"
| parse msg_s with Protocol 'request from ' SourceHost ':' SourcePort 'to ' DestinationHost ':' DestinationPort '. Action:' Action
| where DestinationHost has_any (DomainNames)
| extend DNSName = DestinationHost
| extend IPAddress = SourceHost
),
(AzureDiagnostics
| where ResourceType == "AZUREFIREWALLS"
| where Category == "AzureFirewallDnsProxy"
| project Time
| Sentinel Table | Notes |
|---|---|
AzureDiagnostics | Ensure this data connector is enabled |
CommonSecurityLog | Ensure this data connector is enabled |
VMConnection | Ensure this data connector is enabled |
Scenario: Legitimate DNS resolution for known malicious domains
Description: A system may resolve a known malicious domain as part of a legitimate DNS lookup (e.g., during a security tool update or a domain validation process).
Filter/Exclusion: dns.query.name != "malicious-domain.com" or use a whitelist of known safe domains in the DNS query context.
Scenario: Scheduled job for domain validation or certificate renewal
Description: A scheduled task (e.g., certutil or openssl) may attempt to validate or renew a certificate, which could involve querying a known malicious domain.
Filter/Exclusion: process.name != "certutil.exe" or process.name != "openssl.exe" and filter out certificate-related DNS queries.
Scenario: Admin task involving domain-based configuration management
Description: An administrator may use tools like PowerShell or Group Policy to manage domain configurations, which could involve querying a known malicious domain during a configuration check.
Filter/Exclusion: process.name != "powershell.exe" or process.name != "gpupdate.exe" and exclude queries related to domain configuration tasks.
Scenario: Legitimate use of a security tool with known malicious domain
Description: A security tool like Microsoft Defender ATP or CrowdStrike Falcon may use a known malicious domain for threat intelligence updates.
Filter/Exclusion: process.name contains "defender" or process.name contains "falcon" and exclude domains associated with security tool updates.
Scenario: False positive from a third-party service integration
Description: A third-party service (e.g., Azure AD Connect or Microsoft Intune) may use a known malicious domain as part of its integration with Microsoft services.
Filter/Exclusion: `process.name contains “azure