Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

Potential DGA(Domain Generation Algorithm) detected via Repetitive Failures - Static threshold based (ASIM DNS Solution)

Back
Id89ba52fa-96a7-4653-829a-ca49bb13336c
RulenamePotential DGA(Domain Generation Algorithm) detected via Repetitive Failures - Static threshold based (ASIM DNS Solution)
DescriptionThis rule identifies clients with a high NXDomain count, which could be indicative of a DGA (cycling through possible C2 domains where most C2s are not live). An alert is generated when a new IP address is seen (based on not being seen associated with NXDomain records in prior 10-day baseline period).\n\nIt utilizes ASIM normalization and is applied to any source that supports the ASIM DNS schema.
SeverityMedium
TacticsCommandAndControl
TechniquesT1568
T1008
Required data connectorsAIVectraStream
ASimDnsActivityLogs
AzureFirewall
CiscoUmbrellaDataConnector
Corelight
DNS
GCPDNSDataConnector
InfobloxNIOS
ISCBind
NXLogDnsLogs
WindowsForwardedEvents
Zscaler
KindScheduled
Query frequency1d
Query period10d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/DNS Essentials/Analytic Rules/PotentialDGADetectedviaRepetitiveFailuresStaticThresholdBased.yaml
Version1.0.0
Arm template89ba52fa-96a7-4653-829a-ca49bb13336c.json
Deploy To Azure
let threshold = materialize (_GetWatchlist('DNS_Solution_Monitoring_Configuration')
  | where wl_RuleName == 'Potential DGA(Domain Generation Algorithm) detected' and wl_Type == 'Detection'
  | project toint(wl_Threshold));
let lookback = 10d;
let referenceendtime = 1d;
let nxDomainDnsEvents = (stime: datetime, etime: datetime) {
  _Im_Dns(responsecodename='NXDOMAIN', starttime=stime, endtime=etime)
  | where DnsQueryTypeName in ("A", "AAAA")
  | where ipv4_is_match("127.0.0.1", SrcIpAddr) == False
  | where DnsQuery !contains "/" and DnsQuery contains "."
};
nxDomainDnsEvents (stime=ago(referenceendtime), etime=now())
| summarize
  StartTimeUtc = min(TimeGenerated),
  EndTimeUtc = max(TimeGenerated),
  DNSQueryCount=dcount(DnsQuery)
  by SrcIpAddr
| where DNSQueryCount > toscalar(threshold)
// Filter out previously seen IPs
| join kind=leftanti (nxDomainDnsEvents (stime=ago(lookback), etime=ago(referenceendtime))
  | summarize DNSQueryCount=dcount(DnsQuery) by SrcIpAddr
  | where DNSQueryCount > toscalar(threshold))
  on SrcIpAddr
// Pull out sample NXDomain responses for those remaining potentially infected IPs
| join kind = inner (nxDomainDnsEvents (stime=ago(lookback), etime=now())
  | summarize by DnsQuery, SrcIpAddr)
  on SrcIpAddr
| summarize
  StartTimeUtc = min(StartTimeUtc),
  EndTimeUtc = max(EndTimeUtc),
  DNSQueries=make_list(DnsQuery, 100)
  by SrcIpAddr, DNSQueryCount
| extend DNSQueryThreshold=toint(toscalar(threshold))
queryFrequency: 1d
alertDetailsOverride:
  alertDisplayNameFormat: "[Static threshold] Potential DGA (Domain Generation Algorithm) originating from client IP: '{{SrcIpAddr}}' has been detected."
  alertDescriptionFormat: |-
    Client has been identified with high NXDomain count which could be indicative of a DGA (cycling through possible C2 domains where most C2s are not live). This client is found to be communicating with multiple Domains which do not exist.

    DGA DNS query count baseline is: '{{DNSQueryThreshold}}'

    Current failed DNS query count from this client: '{{DNSQueryCount}}'

    DNS queries requested by this client inlcude: '{{DNSQueries}}'    
triggerOperator: gt
tactics:
- CommandAndControl
description: |
    'This rule identifies clients with a high NXDomain count, which could be indicative of a DGA (cycling through possible C2 domains where most C2s are not live). An alert is generated when a new IP address is seen (based on not being seen associated with NXDomain records in prior 10-day baseline period).\n\nIt utilizes [ASIM](https://aka.ms/AboutASIM) normalization and is applied to any source that supports the ASIM DNS schema.'
eventGroupingSettings:
  aggregationKind: AlertPerResult
status: Available
relevantTechniques:
- T1568
- T1008
name: Potential DGA(Domain Generation Algorithm) detected via Repetitive Failures - Static threshold based (ASIM DNS Solution)
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/DNS Essentials/Analytic Rules/PotentialDGADetectedviaRepetitiveFailuresStaticThresholdBased.yaml
severity: Medium
triggerThreshold: 0
version: 1.0.0
entityMappings:
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: SrcIpAddr
tags:
- Schema: ASimDns
  SchemaVersion: 0.1.6
customDetails:
  DNSQueryCount: DNSQueryCount
  DNSQueries: DNSQueries
  DNSQueryThreshold: DNSQueryThreshold
id: 89ba52fa-96a7-4653-829a-ca49bb13336c
requiredDataConnectors:
- connectorId: ASimDnsActivityLogs
  dataTypes:
  - ASimDnsActivityLogs
- connectorId: GCPDNSDataConnector
  dataTypes:
  - GCP_DNS_CL
- connectorId: AzureFirewall
  dataTypes:
  - AzureDiagnostics
- connectorId: CiscoUmbrellaDataConnector
  dataTypes:
  - Cisco_Umbrella_proxy_CL
- connectorId: Corelight
  dataTypes:
  - Corelight_CL
- connectorId: InfobloxNIOS
  dataTypes:
  - Syslog
- connectorId: NXLogDnsLogs
  dataTypes:
  - NXLog_DNS_Server_CL
- connectorId: DNS
  dataTypes:
  - DnsEvents
- connectorId: AIVectraStream
  dataTypes:
  - VectraStream_CL
- connectorId: WindowsForwardedEvents
  dataTypes:
  - WindowsEvents
- connectorId: Zscaler
  dataTypes:
  - CommonSecurityLog
- connectorId: ISCBind
  dataTypes:
  - Syslog
kind: Scheduled
query: |
  let threshold = materialize (_GetWatchlist('DNS_Solution_Monitoring_Configuration')
    | where wl_RuleName == 'Potential DGA(Domain Generation Algorithm) detected' and wl_Type == 'Detection'
    | project toint(wl_Threshold));
  let lookback = 10d;
  let referenceendtime = 1d;
  let nxDomainDnsEvents = (stime: datetime, etime: datetime) {
    _Im_Dns(responsecodename='NXDOMAIN', starttime=stime, endtime=etime)
    | where DnsQueryTypeName in ("A", "AAAA")
    | where ipv4_is_match("127.0.0.1", SrcIpAddr) == False
    | where DnsQuery !contains "/" and DnsQuery contains "."
  };
  nxDomainDnsEvents (stime=ago(referenceendtime), etime=now())
  | summarize
    StartTimeUtc = min(TimeGenerated),
    EndTimeUtc = max(TimeGenerated),
    DNSQueryCount=dcount(DnsQuery)
    by SrcIpAddr
  | where DNSQueryCount > toscalar(threshold)
  // Filter out previously seen IPs
  | join kind=leftanti (nxDomainDnsEvents (stime=ago(lookback), etime=ago(referenceendtime))
    | summarize DNSQueryCount=dcount(DnsQuery) by SrcIpAddr
    | where DNSQueryCount > toscalar(threshold))
    on SrcIpAddr
  // Pull out sample NXDomain responses for those remaining potentially infected IPs
  | join kind = inner (nxDomainDnsEvents (stime=ago(lookback), etime=now())
    | summarize by DnsQuery, SrcIpAddr)
    on SrcIpAddr
  | summarize
    StartTimeUtc = min(StartTimeUtc),
    EndTimeUtc = max(EndTimeUtc),
    DNSQueries=make_list(DnsQuery, 100)
    by SrcIpAddr, DNSQueryCount
  | extend DNSQueryThreshold=toint(toscalar(threshold))  
queryPeriod: 10d
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/89ba52fa-96a7-4653-829a-ca49bb13336c')]",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/89ba52fa-96a7-4653-829a-ca49bb13336c')]",
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules",
      "kind": "Scheduled",
      "apiVersion": "2022-11-01",
      "properties": {
        "displayName": "Potential DGA(Domain Generation Algorithm) detected via Repetitive Failures - Static threshold based (ASIM DNS Solution)",
        "description": "'This rule identifies clients with a high NXDomain count, which could be indicative of a DGA (cycling through possible C2 domains where most C2s are not live). An alert is generated when a new IP address is seen (based on not being seen associated with NXDomain records in prior 10-day baseline period).\\n\\nIt utilizes [ASIM](https://aka.ms/AboutASIM) normalization and is applied to any source that supports the ASIM DNS schema.'\n",
        "severity": "Medium",
        "enabled": true,
        "query": "let threshold = materialize (_GetWatchlist('DNS_Solution_Monitoring_Configuration')\n  | where wl_RuleName == 'Potential DGA(Domain Generation Algorithm) detected' and wl_Type == 'Detection'\n  | project toint(wl_Threshold));\nlet lookback = 10d;\nlet referenceendtime = 1d;\nlet nxDomainDnsEvents = (stime: datetime, etime: datetime) {\n  _Im_Dns(responsecodename='NXDOMAIN', starttime=stime, endtime=etime)\n  | where DnsQueryTypeName in (\"A\", \"AAAA\")\n  | where ipv4_is_match(\"127.0.0.1\", SrcIpAddr) == False\n  | where DnsQuery !contains \"/\" and DnsQuery contains \".\"\n};\nnxDomainDnsEvents (stime=ago(referenceendtime), etime=now())\n| summarize\n  StartTimeUtc = min(TimeGenerated),\n  EndTimeUtc = max(TimeGenerated),\n  DNSQueryCount=dcount(DnsQuery)\n  by SrcIpAddr\n| where DNSQueryCount > toscalar(threshold)\n// Filter out previously seen IPs\n| join kind=leftanti (nxDomainDnsEvents (stime=ago(lookback), etime=ago(referenceendtime))\n  | summarize DNSQueryCount=dcount(DnsQuery) by SrcIpAddr\n  | where DNSQueryCount > toscalar(threshold))\n  on SrcIpAddr\n// Pull out sample NXDomain responses for those remaining potentially infected IPs\n| join kind = inner (nxDomainDnsEvents (stime=ago(lookback), etime=now())\n  | summarize by DnsQuery, SrcIpAddr)\n  on SrcIpAddr\n| summarize\n  StartTimeUtc = min(StartTimeUtc),\n  EndTimeUtc = max(EndTimeUtc),\n  DNSQueries=make_list(DnsQuery, 100)\n  by SrcIpAddr, DNSQueryCount\n| extend DNSQueryThreshold=toint(toscalar(threshold))\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P10D",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0,
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CommandAndControl"
        ],
        "techniques": [
          "T1568",
          "T1008"
        ],
        "alertRuleTemplateName": "89ba52fa-96a7-4653-829a-ca49bb13336c",
        "eventGroupingSettings": {
          "aggregationKind": "AlertPerResult"
        },
        "alertDetailsOverride": {
          "alertDisplayNameFormat": "[Static threshold] Potential DGA (Domain Generation Algorithm) originating from client IP: '{{SrcIpAddr}}' has been detected.",
          "alertDescriptionFormat": "Client has been identified with high NXDomain count which could be indicative of a DGA (cycling through possible C2 domains where most C2s are not live). This client is found to be communicating with multiple Domains which do not exist.\n\nDGA DNS query count baseline is: '{{DNSQueryThreshold}}'\n\nCurrent failed DNS query count from this client: '{{DNSQueryCount}}'\n\nDNS queries requested by this client inlcude: '{{DNSQueries}}'"
        },
        "customDetails": {
          "DNSQueryCount": "DNSQueryCount",
          "DNSQueries": "DNSQueries",
          "DNSQueryThreshold": "DNSQueryThreshold"
        },
        "entityMappings": [
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "identifier": "Address",
                "columnName": "SrcIpAddr"
              }
            ]
          }
        ],
        "status": "Available",
        "templateVersion": "1.0.0",
        "tags": [
          {
            "Schema": "ASimDns",
            "SchemaVersion": "0.1.6"
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/DNS Essentials/Analytic Rules/PotentialDGADetectedviaRepetitiveFailuresStaticThresholdBased.yaml"
      }
    }
  ]
}