TI map Domain entity to Dns Events ASIM DNS Schema
| Id | 7c1ea2e6-6210-412c-92e4-180803a741b4 |
| Rulename | TI map Domain entity to Dns Events (ASIM DNS Schema) |
| Description | Identifies a match in DNS events from any Domain IOC from TI This analytic rule uses ASIM and supports any built-in or custom source that supports the ASIM DNS schema |
| Severity | Medium |
| Tactics | CommandAndControl |
| Techniques | T1071 |
| Required data connectors | AzureFirewall CiscoUmbrellaDataConnector Corelight DNS GCPDNSDataConnector InfobloxNIOS MicrosoftDefenderThreatIntelligence NXLogDnsLogs ThreatIntelligence ThreatIntelligenceTaxii Zscaler |
| Kind | Scheduled |
| Query frequency | 1h |
| Query period | 14d |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence (NEW)/Analytic Rules/imDns_DomainEntity_DnsEvents.yaml |
| Version | 1.2.3 |
| Arm template | 7c1ea2e6-6210-412c-92e4-180803a741b4.json |
let HAS_ANY_MAX = 10000;
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let DomainTIs= ThreatIntelIndicators
// Picking up only IOC's that contain the entities we want
//extract key part of kv pair
| extend IndicatorType = replace(@"\[|\]|\""", "", tostring(split(ObservableKey, ":", 0)))
| extend IndicatorId = tostring(split(Id, "--")[2])
| where IndicatorType == "domain-name"
| extend DomainName = ObservableValue
| extend Url = iff(ObservableKey == "url:value", ObservableValue, "")
| extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)
| extend ThreatList = tostring(parse_json(Data).indicator_types[0])
| where TimeGenerated >= ago(ioc_lookBack)
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId, ObservableValue
| where IsActive and (ValidUntil > now() or isempty(ValidUntil));
let Domains = DomainTIs |summarize NDomains=dcount(DomainName), DomainsList=make_set(DomainName)
| project DomainList = iff(NDomains > HAS_ANY_MAX, dynamic([]), DomainsList);
DomainTIs
| project-reorder *, ThreatList, IsActive, Tags, TrafficLightProtocolLevel, DomainName, Type
| join (
_Im_Dns(starttime=ago(dt_lookBack), domain_has_any=toscalar(Domains))
| extend DNS_TimeGenerated = TimeGenerated
) on $left.DomainName==$right.DnsQuery
| where DNS_TimeGenerated < ValidUntil
| extend Description = tostring(parse_json(Data).description)
| extend ActivityGroupNames = extract(@"ActivityGroup:(\S+)", 1, tostring(parse_json(Data).labels))
| project LatestIndicatorTime, Description, ActivityGroupNames, IndicatorId, ValidUntil, Confidence, DNS_TimeGenerated, Dvc, SrcIpAddr, Domain, DnsQuery, DnsQueryType, Url
| extend HostName = tostring(split(Dvc, ".")[0]), DomainIndex = toint(indexof(Dvc, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Dvc, DomainIndex + 1), Dvc)
description: |
Identifies a match in DNS events from any Domain IOC from TI
This analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM DNS schema'
kind: Scheduled
tactics:
- CommandAndControl
requiredDataConnectors:
- connectorId: ThreatIntelligence
dataTypes:
- ThreatIntelIndicators
- connectorId: ThreatIntelligenceTaxii
dataTypes:
- ThreatIntelIndicators
- connectorId: DNS
dataTypes:
- DnsEvents
- connectorId: AzureFirewall
dataTypes:
- AzureDiagnostics
- connectorId: Zscaler
dataTypes:
- CommonSecurityLog
- connectorId: InfobloxNIOS
dataTypes:
- Syslog
- connectorId: GCPDNSDataConnector
dataTypes:
- GCP_DNS_CL
- connectorId: NXLogDnsLogs
dataTypes:
- NXLog_DNS_Server_CL
- connectorId: MicrosoftDefenderThreatIntelligence
dataTypes:
- ThreatIntelIndicators
- connectorId: CiscoUmbrellaDataConnector
dataTypes:
- Cisco_Umbrella_dns_CL
- connectorId: Corelight
dataTypes:
- Corelight_CL
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence (NEW)/Analytic Rules/imDns_DomainEntity_DnsEvents.yaml
severity: Medium
name: TI map Domain entity to Dns Events (ASIM DNS Schema)
customDetails:
ActivityGroupNames: ActivityGroupNames
ExpirationDateTime: ValidUntil
Description: Description
DNSRequestTime: DNS_TimeGenerated
IndicatorId: IndicatorId
QueryType: DnsQueryType
DnsQuery: DnsQuery
LatestIndicatorTime: LatestIndicatorTime
ConfidenceScore: Confidence
SourceIPAddress: SrcIpAddr
triggerThreshold: 0
queryPeriod: 14d
query: "let HAS_ANY_MAX = 10000;\nlet dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet DomainTIs= ThreatIntelIndicators\n // Picking up only IOC's that contain the entities we want\n //extract key part of kv pair\n | extend IndicatorType = replace(@\"\\[|\\]|\\\"\"\", \"\", tostring(split(ObservableKey, \":\", 0)))\n | extend IndicatorId = tostring(split(Id, \"--\")[2])\n | where IndicatorType == \"domain-name\"\n | extend DomainName = ObservableValue\n | extend Url = iff(ObservableKey == \"url:value\", ObservableValue, \"\")\n \n | extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)\n | extend ThreatList = tostring(parse_json(Data).indicator_types[0])\n | where TimeGenerated >= ago(ioc_lookBack)\n | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId, ObservableValue\n | where IsActive and (ValidUntil > now() or isempty(ValidUntil));\nlet Domains = DomainTIs |summarize NDomains=dcount(DomainName), DomainsList=make_set(DomainName) \n | project DomainList = iff(NDomains > HAS_ANY_MAX, dynamic([]), DomainsList);\nDomainTIs\n| project-reorder *, ThreatList, IsActive, Tags, TrafficLightProtocolLevel, DomainName, Type\n | join (\n _Im_Dns(starttime=ago(dt_lookBack), domain_has_any=toscalar(Domains))\n | extend DNS_TimeGenerated = TimeGenerated\n) on $left.DomainName==$right.DnsQuery\n| where DNS_TimeGenerated < ValidUntil\n| extend Description = tostring(parse_json(Data).description)\n| extend ActivityGroupNames = extract(@\"ActivityGroup:(\\S+)\", 1, tostring(parse_json(Data).labels))\n| project LatestIndicatorTime, Description, ActivityGroupNames, IndicatorId, ValidUntil, Confidence, DNS_TimeGenerated, Dvc, SrcIpAddr, Domain, DnsQuery, DnsQueryType, Url\n| extend HostName = tostring(split(Dvc, \".\")[0]), DomainIndex = toint(indexof(Dvc, '.'))\n| extend HostNameDomain = iff(DomainIndex != -1, substring(Dvc, DomainIndex + 1), Dvc)\n"
relevantTechniques:
- T1071
id: 7c1ea2e6-6210-412c-92e4-180803a741b4
queryFrequency: 1h
entityMappings:
- entityType: Host
fieldMappings:
- columnName: Dvc
identifier: FullName
- columnName: HostName
identifier: HostName
- columnName: HostNameDomain
identifier: DnsDomain
- entityType: IP
fieldMappings:
- columnName: SrcIpAddr
identifier: Address
- entityType: URL
fieldMappings:
- columnName: Url
identifier: Url
- entityType: DNS
fieldMappings:
- columnName: Domain
identifier: DomainName
triggerOperator: gt
version: 1.2.3
tags:
- Id: 85aca4d1-5d15-4001-abd9-acb86ca1786a
version: 1.0.0
- Schema: ASIMDns
SchemaVersion: 0.1.1