{
  "version": "Notebook/1.0",
  "items": [
    {
      "type": 9,
      "content": {
        "version": "KqlParameterItem/1.0",
        "query": "",
        "crossComponentResources": [],
        "parameters": [
          {
            "id": "4459cc76-3bf4-4ca1-a981-ac7b57aa245a",
            "version": "KqlParameterItem/1.0",
            "name": "TimeRange",
            "label": "Time range",
            "type": 4,
            "isRequired": true,
            "value": {
              "durationMs": 1209600000
            },
            "typeSettings": {
              "selectableValues": [
                {
                  "durationMs": 300000
                },
                {
                  "durationMs": 900000
                },
                {
                  "durationMs": 1800000
                },
                {
                  "durationMs": 3600000
                },
                {
                  "durationMs": 14400000
                },
                {
                  "durationMs": 43200000
                },
                {
                  "durationMs": 86400000
                },
                {
                  "durationMs": 172800000
                },
                {
                  "durationMs": 259200000
                },
                {
                  "durationMs": 604800000
                },
                {
                  "durationMs": 1209600000
                },
                {
                  "durationMs": 2419200000
                },
                {
                  "durationMs": 2592000000
                },
                {
                  "durationMs": 5184000000
                },
                {
                  "durationMs": 7776000000
                }
              ],
              "allowCustom": true
            }
          },
          {
            "id": "594d398d-703f-4e6d-81e7-97ab7803b08f",
            "version": "KqlParameterItem/1.0",
            "name": "IpAddresses",
            "label": "IP Addresses",
            "type": 2,
            "description": "Choose IP for the queries",
            "isRequired": true,
            "multiSelect": true,
            "quote": "'",
            "delimiter": ",",
            "query": "DnsEvents\n| extend IpAddresses = iif(IPAddresses==\"\",\"empty\" ,IPAddresses)\n| summarize by IpAddresses\n| sort by IpAddresses desc",
            "value": [
              "value::all"
            ],
            "typeSettings": {
              "additionalResourceOptions": [
                "value::all"
              ],
              "selectAllValue": "*"
            },
            "timeContext": {
              "durationMs": 0
            },
            "timeContextFromParameter": "TimeRange",
            "queryType": 0,
            "resourceType": "microsoft.operationalinsights/workspaces"
          }
        ],
        "style": "pills",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces"
      },
      "name": "parameters - 5"
    },
    {
      "type": 1,
      "content": {
        "json": "## Overview"
      },
      "name": "text - 4"
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "DnsEvents\r\n| extend IPAddresses = iif(IPAddresses==\"\", \"empty\", IPAddresses)\r\n| where \"*\" in ({IpAddresses}) or IPAddresses in ({IpAddresses})\r\n| summarize Events= count() by bin_at(TimeGenerated, 1h, now()), SubType\r\n",
        "size": 0,
        "exportToExcelOptions": "visible",
        "title": "Activity, by time",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces",
        "visualization": "timechart"
      },
      "conditionalVisibility": {
        "parameterName": "IpAddresses",
        "comparison": "isNotEqualTo"
      },
      "customWidth": "50",
      "name": "query - 1"
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "DnsEvents\r\n| extend IPAddresses = iif(IPAddresses==\"\", \"empty\", IPAddresses)\r\n| where \"*\" in ({IpAddresses}) or IPAddresses in ({IpAddresses})\r\n| summarize count()  by SubType\r\n| order by count_ desc \r\n",
        "size": 0,
        "exportToExcelOptions": "visible",
        "title": "Dns events by subtype",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces",
        "visualization": "piechart"
      },
      "conditionalVisibility": {
        "parameterName": "IpAddresses",
        "comparison": "isNotEqualTo"
      },
      "customWidth": "25",
      "name": "query - 1 - Copy"
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "DnsEvents\r\n| extend IPAddresses = iif(IPAddresses==\"\", \"empty\", IPAddresses)\r\n| where \"*\" in ({IpAddresses}) or IPAddresses in ({IpAddresses})\r\n| extend type = case(\r\n    QueryType == \"A\", \"IPv4 address record\", \r\n    QueryType == \"AAAA\", \"IPv6 address record\",\r\n    QueryType == \"ANY\", \"All cached records\",\r\n    QueryType == \"CNAME\", \"Canonical name record\",\r\n    QueryType == \"MX\", \"Mail exchange record\",\r\n    QueryType == \"NS\", \"Name server record\",\r\n    QueryType == \"PTR\", \"Pointer record\",\r\n    QueryType == \"SIG\", \"Signature\",\r\n    QueryType == \"SOA\", \"Start of authority record\",\r\n    QueryType == \"SRV\", \"Service locator\",\r\n    QueryType == \"TXT\", \"Text record\",\r\n    strcat('Other'))\r\n| summarize count()  by type\r\n",
        "size": 0,
        "exportToExcelOptions": "visible",
        "title": "DNS events per query type",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces",
        "visualization": "piechart"
      },
      "conditionalVisibility": {
        "parameterName": "IpAddresses",
        "comparison": "isNotEqualTo"
      },
      "customWidth": "25",
      "name": "query - 1 - Copy - Copy"
    },
    {
      "type": 1,
      "content": {
        "json": "## Domain overview"
      },
      "name": "text - 5"
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "let data = DnsEvents\r\n| extend IPAddresses = iif(IPAddresses==\"\", \"empty\", IPAddresses)\r\n| where \"*\" in ({IpAddresses}) or IPAddresses in ({IpAddresses})\r\n| where SubType == \"LookupQuery\"\r\n| extend Domain = Name;\r\nlet appData = data\r\n| summarize TotalCount = count() by Domain\r\n| join kind=inner (data\r\n    | make-series Trend = count() default = 0 on TimeGenerated in range({TimeRange:start}, {TimeRange:end}, {TimeRange:grain}) by Domain\r\n    | project-away TimeGenerated) on Domain\r\n| order by TotalCount desc, Domain asc\r\n| project Domain, TotalCount, Trend\r\n| serialize Id = row_number();\r\ndata\r\n| summarize TotalCount = count() by Computer , Domain\r\n| join kind=inner (data\r\n    | make-series Trend = count() default = 0 on TimeGenerated in range({TimeRange:start}, {TimeRange:end}, {TimeRange:grain}) by Domain, Computer\r\n    | project-away TimeGenerated) on Domain, Computer\r\n| order by TotalCount desc, Domain asc\r\n| project Domain, Computer, TotalCount, Trend\r\n| serialize Id = row_number(1000000)\r\n| join kind=inner (appData) on Domain\r\n| project Id, Name = Computer, Type = 'Computer', ['Computer Count'] = TotalCount, Trend, ParentId = Id1\r\n| union (appData \r\n    | project Id, Name = Domain, Type = 'Domain', ['Computer Count'] = TotalCount, Trend )\r\n| order by ['Computer Count'] desc, Name asc\r\n\r\n",
        "size": 0,
        "exportFieldName": "",
        "exportParameterName": "ComputerSelector",
        "exportDefaultValue": "{ \"Name\":\"\", \"Type\":\"*\"}",
        "exportToExcelOptions": "visible",
        "title": "Top domains queried",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces",
        "visualization": "table",
        "gridSettings": {
          "formatters": [
            {
              "columnMatch": "Id",
              "formatter": 5,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "Name",
              "formatter": 0,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "Type",
              "formatter": 0,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "Computer Count",
              "formatter": 8,
              "formatOptions": {
                "min": 0,
                "palette": "lightBlue",
                "showIcon": true
              }
            },
            {
              "columnMatch": "Trend",
              "formatter": 9,
              "formatOptions": {
                "min": 0,
                "palette": "gray",
                "showIcon": true
              }
            },
            {
              "columnMatch": "ParentId",
              "formatter": 5,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "Domain",
              "formatter": 0,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "Queries",
              "formatter": 4,
              "formatOptions": {
                "min": 0,
                "palette": "blueDark",
                "showIcon": true
              }
            }
          ],
          "filter": true,
          "hierarchySettings": {
            "idColumn": "Id",
            "parentColumn": "ParentId",
            "treeType": 0,
            "expanderColumn": "Name"
          },
          "labelSettings": []
        }
      },
      "customWidth": "50",
      "name": "query - 1 - Copy - Copy - Copy - Copy"
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "let Selector = dynamic({ComputerSelector});\r\nDnsEvents\r\n| extend IPAddresses = iif(IPAddresses==\"\", \"empty\", IPAddresses)\r\n| where \"*\" in ({IpAddresses}) or IPAddresses in ({IpAddresses})\r\n| where (Selector.Type == '*' or (Selector.Type == 'Computer' and Computer == Selector.Name)) or (Selector.Type == '*' or (Selector.Type == 'Domain' and Name == Name))\r\n| where SubType == \"LookupQuery\" \r\n| summarize Domains = dcount(Name) by bin_at(TimeGenerated, 1h, now())\r\n\r\n",
        "size": 0,
        "exportToExcelOptions": "visible",
        "title": "Unique domains queried",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces",
        "visualization": "timechart"
      },
      "customWidth": "50",
      "name": "query - 1 - Copy - Copy - Copy"
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "DnsEvents\r\n| extend IPAddresses = iif(IPAddresses==\"\", \"empty\", IPAddresses)\r\n| where \"*\" in ({IpAddresses}) or IPAddresses in ({IpAddresses})\r\n| extend NameParts = split(Name,'.')\r\n//Break the domain into its parts\r\n| extend Top_Level_Domain =  strcat(NameParts[toint(array_length(NameParts)-2)],'.',NameParts[toint(array_length(NameParts)-1)] )\r\n//Use the rightmost parts of the URL\r\n| extend Top_Level_Domain = iif(strlen(Top_Level_Domain)<7,strcat(NameParts[toint(array_length(NameParts)-3)],'.',Top_Level_Domain),Top_Level_Domain)\r\n//If the two right most parts are too short (e.g. \"co.uk\" or \"com.tr\", add another part\r\n| summarize SubDomainCount = count() by Top_Level_Domain, Name\r\n| join kind= inner\r\n(\r\n    DnsEvents\r\n    | extend NameParts = split(Name,'.')\r\n    //Break the domain into its parts\r\n    | extend Top_Level_Domain =  strcat(NameParts[toint(array_length(NameParts)-2)],'.',NameParts[toint(array_length(NameParts)-1)] )\r\n    //Use the rightmost parts of the URL\r\n    | extend Top_Level_Domain = iif(strlen(Top_Level_Domain)<7,strcat(NameParts[toint(array_length(NameParts)-3)],'.',Top_Level_Domain),Top_Level_Domain)\r\n    //If the two right most parts are too short (e.g. \"co.uk\" or \"com.tr\", add another part\r\n    | summarize Total_Sub_Domains = count() by Top_Level_Domain\r\n)\r\non Top_Level_Domain\r\n| extend pk = SubDomainCount/todouble(Total_Sub_Domains)\r\n| extend h1= -log2(pk)*pk\r\n//calculate entropy according to Sannon function https://en.wiktionary.org/wiki/Shannon_entropy\r\n| summarize Sub_Domain_Entropy = sum(h1), Total_Sub_Domains = any(Total_Sub_Domains) ,make_list(Name)  by Top_Level_Domain\r\n| order by Sub_Domain_Entropy desc",
        "size": 0,
        "exportToExcelOptions": "visible",
        "title": "Domain entropy",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces",
        "visualization": "table",
        "gridSettings": {
          "formatters": [
            {
              "columnMatch": "Top_Level_Domain",
              "formatter": 0,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "Sub_Domain_Entropy",
              "formatter": 8,
              "formatOptions": {
                "palette": "coldHot",
                "showIcon": true
              }
            },
            {
              "columnMatch": "Total_Sub_Domains",
              "formatter": 4,
              "formatOptions": {
                "min": 0,
                "palette": "blueDark",
                "showIcon": true
              }
            },
            {
              "columnMatch": "list_Name",
              "formatter": 0,
              "formatOptions": {
                "showIcon": true
              }
            }
          ],
          "filter": true,
          "labelSettings": []
        }
      },
      "customWidth": "100",
      "name": "query - 1 - Copy - Copy - Copy - Copy - Copy",
      "styleSettings": {
        "showBorder": true
      }
    },
    {
      "type": 1,
      "content": {
        "json": "## Malicious traffic on DNS servers"
      },
      "name": "text - 9"
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "DnsInventory\r\n| where SubType == \"Server\"\r\n| project Computer, DomainName, ForestName, ServerIPs",
        "size": 0,
        "exportToExcelOptions": "visible",
        "title": "Active servers",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces",
        "gridSettings": {
          "filter": true,
          "labelSettings": []
        }
      },
      "name": "query - 10"
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "DnsEvents\r\n| extend IPAddresses = iif(IPAddresses==\"\", \"empty\", IPAddresses)\r\n| where \"*\" in ({IpAddresses}) or IPAddresses in ({IpAddresses})\r\n| where SubType == 'LookupQuery' and isnotempty(MaliciousIP)\r\n| summarize Attempts = count() by  Computer,RemoteIPCountry, IndicatorThreatType\r\n| order by Attempts desc",
        "size": 0,
        "exportToExcelOptions": "visible",
        "title": "Malicious traffic",
        "noDataMessage": "No malicious traffic",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces",
        "visualization": "table",
        "gridSettings": {
          "formatters": [
            {
              "columnMatch": "Computer",
              "formatter": 0,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "RemoteIPCountry",
              "formatter": 0,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "IndicatorThreatType",
              "formatter": 0,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "Attempts",
              "formatter": 4,
              "formatOptions": {
                "min": 0,
                "palette": "orange",
                "showIcon": true
              }
            }
          ],
          "labelSettings": []
        }
      },
      "customWidth": "40",
      "name": "query - 11"
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "DnsEvents\r\n| extend IPAddresses = iif(IPAddresses==\"\", \"empty\", IPAddresses)\r\n| where \"*\" in ({IpAddresses}) or IPAddresses in ({IpAddresses})\r\n| where SubType == 'LookupQuery' and isnotempty(MaliciousIP)\r\n| summarize Attempts = count() by ClientIP, MaliciousIP\r\n| project ClientIP , MaliciousIP, Attempts",
        "size": 0,
        "exportToExcelOptions": "visible",
        "title": "Malicious traffic by client IP address",
        "noDataMessage": "No malicious traffic",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces",
        "visualization": "table",
        "gridSettings": {
          "formatters": [
            {
              "columnMatch": "Computer",
              "formatter": 0,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "RemoteIPCountry",
              "formatter": 0,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "IndicatorThreatType",
              "formatter": 0,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "Attempts",
              "formatter": 4,
              "formatOptions": {
                "min": 0,
                "palette": "orange",
                "showIcon": true
              }
            }
          ],
          "labelSettings": []
        }
      },
      "customWidth": "40",
      "name": "query - 11 - Copy"
    },
    {
      "type": 1,
      "content": {
        "json": "## Dynamic registration"
      },
      "name": "text - 13"
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "DnsEvents\r\n| extend IPAddresses = iif(IPAddresses==\"\", \"empty\", IPAddresses)\r\n| where \"*\" in ({IpAddresses}) or IPAddresses in ({IpAddresses})\r\n| where SubType == \"DynamicRegistration\"\r\n| summarize count() by Result\r\n",
        "size": 0,
        "exportToExcelOptions": "visible",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces",
        "visualization": "table",
        "gridSettings": {
          "formatters": [
            {
              "columnMatch": "Result",
              "formatter": 0,
              "formatOptions": {
                "showIcon": true
              }
            },
            {
              "columnMatch": "count_",
              "formatter": 8,
              "formatOptions": {
                "palette": "purpleBlue",
                "showIcon": true
              }
            }
          ],
          "labelSettings": []
        }
      },
      "name": "query - 14"
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "//DNS Configuration Events\r\nDnsEvents\r\n| extend IPAddresses = iif(IPAddresses==\"\", \"empty\", IPAddresses)\r\n| where \"*\" in ({IpAddresses}) or IPAddresses in ({IpAddresses})\r\n| where SubType == \"ConfigurationChange\"\r\n| project TimeGenerated, Category = TaskCategory, Event_ID = EventId",
        "size": 0,
        "exportToExcelOptions": "visible",
        "title": "Configuration events",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces"
      },
      "name": "query - 14 - Copy"
    },
    {
      "type": 1,
      "content": {
        "json": "## Lookup queries"
      },
      "name": "text - 17"
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "DnsEvents\r\n| extend IPAddresses = iif(IPAddresses==\"\", \"empty\", IPAddresses)\r\n| where \"*\" in ({IpAddresses}) or IPAddresses in ({IpAddresses})\r\n| where SubType == \"LookupQuery\"\r\n| extend Reasons = case(\r\n    ResultCode == 0, \"No Error\",\r\n    ResultCode == 1, \"Format Error\",\r\n    ResultCode == 2, \"Server Failure\",\r\n    ResultCode == 3, \"Non-Existent Domain\",\r\n    ResultCode == 4, \"Not Implemented\",\r\n    ResultCode == 5, \"Query Refused\",\r\n    ResultCode == 6, \"Name Exists when it should not\",\r\n    ResultCode == 7, \"RR Set Exists when it should not\",\r\n    ResultCode == 8, \"RR Set that should exist does not\",\r\n    ResultCode == 9, \"Server Not Authoritative for zone\",\r\n    ResultCode == 10, \"Name not contained in zone\",\r\n    ResultCode == 16, \"TSIG Signature Failure\",\r\n    ResultCode == 17, \"Key not recognized\",\r\n    ResultCode == 18, \"Signature out of time window\",\r\n    ResultCode == 19, \"Bad TKEY Mode\",\r\n    ResultCode == 20, \"Duplicate key name\",\r\n    ResultCode == 21, \"Algorithm not supported\",\r\n    ResultCode == 22, \"Bad Truncation\",\r\n    ResultCode == 23, \"Bad/missing Server Cookie\",\r\n    strcat('Other', ResultCode))\r\n| summarize count() by Reasons",
        "size": 0,
        "exportToExcelOptions": "visible",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces",
        "visualization": "piechart"
      },
      "customWidth": "50",
      "name": "query - 18",
      "styleSettings": {
        "margin": "50"
      }
    },
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "DnsEvents\r\n| extend IPAddresses = iif(IPAddresses==\"\", \"empty\", IPAddresses)\r\n| where \"*\" in ({IpAddresses}) or IPAddresses in ({IpAddresses})\r\n| where SubType == \"LookupQuery\"\r\n| summarize count() by ClientIP\r\n| order by count_ desc\r\n| project IP = ClientIP , Queries=count_\r\n",
        "size": 0,
        "exportToExcelOptions": "visible",
        "timeContext": {
          "durationMs": 0
        },
        "timeContextFromParameter": "TimeRange",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces",
        "visualization": "piechart"
      },
      "customWidth": "50",
      "name": "query - 19",
      "styleSettings": {
        "margin": "50"
      }
    }
  ],
  "styleSettings": {
    "paddingStyle": "wide"
  },
  "fromTemplateId": "sentinel-DNS",
  "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json"
}
