Known Forest Blizzard group domains - July 2019
Id | 074ce265-f684-41cd-af07-613c5f3e6d0d |
Rulename | 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 |
Tactics | CommandAndControl |
Techniques | T1071 |
Required data connectors | AzureFirewall AzureMonitor(VMInsights) CiscoASA CiscoUmbrellaDataConnector Corelight DNS GCPDNSDataConnector InfobloxNIOS NXLogDnsLogs PaloAltoNetworks Zscaler |
Kind | Scheduled |
Query frequency | 1d |
Query period | 1d |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/ForestBlizzardJuly2019IOCs.yaml |
Version | 1.6.1 |
Arm template | 074ce265-f684-41cd-af07-613c5f3e6d0d.json |
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)
relevantTechniques:
- T1071
name: Known Forest Blizzard group domains - July 2019
requiredDataConnectors:
- dataTypes:
- DnsEvents
connectorId: DNS
- dataTypes:
- VMConnection
connectorId: AzureMonitor(VMInsights)
- dataTypes:
- CommonSecurityLog
connectorId: CiscoASA
- dataTypes:
- CommonSecurityLog
connectorId: PaloAltoNetworks
- dataTypes:
- AzureDiagnostics
- AZFWApplicationRule
- AZFWDnsQuery
connectorId: AzureFirewall
- dataTypes:
- CommonSecurityLog
connectorId: Zscaler
- dataTypes:
- Syslog
connectorId: InfobloxNIOS
- dataTypes:
- GCP_DNS_CL
connectorId: GCPDNSDataConnector
- dataTypes:
- NXLog_DNS_Server_CL
connectorId: NXLogDnsLogs
- dataTypes:
- Cisco_Umbrella_dns_CL
connectorId: CiscoUmbrellaDataConnector
- dataTypes:
- Corelight_CL
connectorId: Corelight
entityMappings:
- fieldMappings:
- identifier: FullName
columnName: User
- identifier: Name
columnName: AccountName
- identifier: NTDomain
columnName: AccountDomain
entityType: Account
- fieldMappings:
- identifier: FullName
columnName: DeviceName
- identifier: HostName
columnName: HostName
- identifier: NTDomain
columnName: HostNameDomain
entityType: Host
- fieldMappings:
- identifier: Address
columnName: IPAddress
entityType: IP
triggerThreshold: 0
id: 074ce265-f684-41cd-af07-613c5f3e6d0d
tactics:
- CommandAndControl
version: 1.6.1
queryPeriod: 1d
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/ForestBlizzardJuly2019IOCs.yaml
triggerOperator: gt
kind: Scheduled
tags:
- Schema: ASIMDns
SchemaVersion: 0.1.1
metadata:
categories:
domains:
- Security - 0-day Vulnerability
author:
name: Microsoft Security Research
support:
tier: Community
source:
kind: Community
queryFrequency: 1d
severity: High
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/.'
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)
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/074ce265-f684-41cd-af07-613c5f3e6d0d')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/074ce265-f684-41cd-af07-613c5f3e6d0d')]",
"properties": {
"alertRuleTemplateName": "074ce265-f684-41cd-af07-613c5f3e6d0d",
"customDetails": null,
"description": "'Matches domain name IOCs related to Forest Blizzard group activity published July 2019 with CommonSecurityLog, DnsEvents and VMConnection dataTypes.\nReferences: https://blogs.microsoft.com/on-the-issues/2019/07/17/new-cyberthreats-require-new-ways-to-protect-democracy/.'\n",
"displayName": "Known Forest Blizzard group domains - July 2019",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "User",
"identifier": "FullName"
},
{
"columnName": "AccountName",
"identifier": "Name"
},
{
"columnName": "AccountDomain",
"identifier": "NTDomain"
}
]
},
{
"entityType": "Host",
"fieldMappings": [
{
"columnName": "DeviceName",
"identifier": "FullName"
},
{
"columnName": "HostName",
"identifier": "HostName"
},
{
"columnName": "HostNameDomain",
"identifier": "NTDomain"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "IPAddress",
"identifier": "Address"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/ForestBlizzardJuly2019IOCs.yaml",
"query": "let DomainNames = dynamic([\"irf.services\",\"microsoft-onthehub.com\",\"msofficelab.com\",\"com-mailbox.com\",\"my-sharefile.com\",\"my-sharepoints.com\",\n\"accounts-web-mail.com\",\"customer-certificate.com\",\"session-users-activities.com\",\"user-profile-credentials.com\",\"verify-linke.com\",\"support-servics.net\",\n\"onedrive-sharedfile.com\",\"onedrv-live.com\",\"transparencyinternational-my-sharepoint.com\",\"transparencyinternational-my-sharepoints.com\",\"soros-my-sharepoint.com\"]);\n(union isfuzzy=true\n (CommonSecurityLog\n | where Message has_any (DomainNames)\n | parse Message with * '(' DNSName ')' *\n | extend AccountName = SourceUserID, DeviceName, IPAddress = SourceIP\n ),\n (_Im_Dns(domain_has_any=DomainNames)\n | where DnsQuery has_any (DomainNames)\n | extend IPAddress = SrcIpAddr, DeviceName = Dvc\n ),\n (VMConnection\n | where RemoteDnsCanonicalNames has_any (DomainNames)\n | parse RemoteDnsCanonicalNames with * '[\"' DNSName '\"]' *\n | extend IPAddress = RemoteIp, DeviceName = Computer\n ),\n (AzureDiagnostics \n | where ResourceType == \"AZUREFIREWALLS\"\n | where Category == \"AzureFirewallApplicationRule\"\n | parse msg_s with Protocol 'request from ' SourceHost ':' SourcePort 'to ' DestinationHost ':' DestinationPort '. Action:' Action\n | where DestinationHost has_any (DomainNames)\n | extend DNSName = DestinationHost \n | extend IPAddress = SourceHost\n ),\n (AzureDiagnostics\n | where ResourceType == \"AZUREFIREWALLS\"\n | where Category == \"AzureFirewallDnsProxy\"\n | project TimeGenerated,Resource, msg_s, Type\n | 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\n | where Request_Name has_any (DomainNames)\n | extend DNSName = Request_Name\n | extend IPAddress = ClientIP\n ),\n (AZFWApplicationRule\n | where isnotempty(Fqdn)\n | where Fqdn has_any (DomainNames) \n | extend DNSName = Fqdn \n | extend IPAddress = SourceIp\n ),\n (AZFWDnsQuery\n | where isnotempty(QueryName)\n | where QueryName has_any (DomainNames)\n | extend DNSName = QueryName\n | extend IPAddress = SourceIp\n ),\n (\n _Im_WebSession(url_has_any=DomainNames)\n | extend IPAddress=IpAddr, DeviceName=Hostname, AccountName = tostring(split(User, \"@\")[0]), AccountDomain = tostring(split(User, \"@\")[1])\n )\n)\n| where DNSName has_any (DomainNames)\n| extend timestamp = TimeGenerated\n| extend HostName = tostring(split(DeviceName, \".\")[0]), DomainIndex = toint(indexof(DeviceName, '.'))\n| extend HostNameDomain = iff(DomainIndex != -1, substring(DeviceName, DomainIndex + 1), DeviceName)\n",
"queryFrequency": "P1D",
"queryPeriod": "P1D",
"severity": "High",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"CommandAndControl"
],
"tags": [
{
"Schema": "ASIMDns",
"SchemaVersion": "0.1.1"
}
],
"techniques": [
"T1071"
],
"templateVersion": "1.6.1",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}