← Back to SOC feed Coverage →

Known Forest Blizzard group domains - July 2019

kql HIGH Azure-Sentinel
T1071
AzureDiagnosticsCommonSecurityLogVMConnection
microsoftofficial
This rule was pulled from an open-source repository and enriched with AI. Validate in a test environment before deploying to production.
View original rule at Azure-Sentinel →
Retrieved: 2026-03-25T03:06:09Z · Confidence: medium

Hunt Hypothesis

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)

Analytic Rule Definition

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

Required Data Sources

Sentinel TableNotes
AzureDiagnosticsEnsure this data connector is enabled
CommonSecurityLogEnsure this data connector is enabled
VMConnectionEnsure this data connector is enabled

MITRE ATT&CK Context

References

False Positive Guidance

Original source: https://github.com/Azure/Azure-Sentinel/blob/main/Detections/MultipleDataSources/ForestBlizzardJuly2019IOCs.yaml