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

Discord CDN Risky File Download

Back
Id010bd98c-a6be-498c-bdcd-502308c0fdae
RulenameDiscord CDN Risky File Download
DescriptionIdentifies callouts to Discord CDN addresses for risky file extensions. This detection will trigger when a callout for a risky file

is made to a discord server that has only been seen once in your environment. Unique discord servers are identified using the server ID

that is included in the request URL (DiscordServerId in query). Discord CDN has been used in multiple campaigns to download additional payloads
SeverityMedium
TacticsCommandAndControl
TechniquesT1071.001
Required data connectorsZscaler
ZscalerAma
KindScheduled
Query frequency1d
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Zscaler Internet Access/Analytic Rules/DiscordCDNRiskyDownload.yaml
Version1.0.1
Arm template010bd98c-a6be-498c-bdcd-502308c0fdae.json
Deploy To Azure
let connectionThreshold = 1;
let riskyExtensions = dynamic([".bin",".exe",".dll",".bin",".msi"]);
CommonSecurityLog
| where DeviceVendor =~ "ZScaler"
| where RequestURL has_any("media.discordapp.net", "cdn.discordapp.com")
| where RequestURL has "attachments"
| where DeviceAction !~ "blocked"
| extend DiscordServerId = extract(@"\/attachments\/([0-9]+)\/", 1, RequestURL)
| summarize dcount(RequestURL), make_set(SourceUserName), make_set(SourceIP), make_set(RequestURL), min(TimeGenerated), max(TimeGenerated), make_set(DeviceAction) by DiscordServerId, DeviceProduct
| where dcount_RequestURL <= connectionThreshold
| mv-expand set_SourceUserName to typeof(string), set_RequestURL to typeof(string), set_DeviceAction to typeof(string), set_SourceIP to typeof(string)
| summarize by DiscordServerId, DeviceProduct, dcount_RequestURL, set_SourceUserName, min_TimeGenerated, max_TimeGenerated, set_DeviceAction, set_SourceIP, set_RequestURL
| project StartTime=min_TimeGenerated, EndTime=max_TimeGenerated, DeviceActionTaken=set_DeviceAction, DeviceProduct, SourceUser=set_SourceUserName, SourceIP=set_SourceIP, RequestURL=set_RequestURL
| where RequestURL has_any (riskyExtensions)
triggerOperator: gt
queryFrequency: 1d
description: |
  'Identifies callouts to Discord CDN addresses for risky file extensions. This detection will trigger when a callout for a risky file
  is made to a discord server that has only been seen once in your environment. Unique discord servers are identified using the server ID
  that is included in the request URL (DiscordServerId in query). Discord CDN has been used in multiple campaigns to download additional payloads'  
status: Available
kind: Scheduled
triggerThreshold: 0
requiredDataConnectors:
- connectorId: Zscaler
  dataTypes:
  - CommonSecurityLog
- connectorId: ZscalerAma
  dataTypes:
  - CommonSecurityLog
version: 1.0.1
queryPeriod: 1d
name: Discord CDN Risky File Download
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Zscaler Internet Access/Analytic Rules/DiscordCDNRiskyDownload.yaml
id: 010bd98c-a6be-498c-bdcd-502308c0fdae
tags:
- Discord
tactics:
- CommandAndControl
relevantTechniques:
- T1071.001
severity: Medium
entityMappings:
- fieldMappings:
  - identifier: FullName
    columnName: SourceUser
  entityType: Account
- fieldMappings:
  - identifier: Address
    columnName: SourceIP
  entityType: IP
- fieldMappings:
  - identifier: Url
    columnName: RequestURL
  entityType: URL
query: |
  let connectionThreshold = 1;
  let riskyExtensions = dynamic([".bin",".exe",".dll",".bin",".msi"]);
  CommonSecurityLog
  | where DeviceVendor =~ "ZScaler"
  | where RequestURL has_any("media.discordapp.net", "cdn.discordapp.com")
  | where RequestURL has "attachments"
  | where DeviceAction !~ "blocked"
  | extend DiscordServerId = extract(@"\/attachments\/([0-9]+)\/", 1, RequestURL)
  | summarize dcount(RequestURL), make_set(SourceUserName), make_set(SourceIP), make_set(RequestURL), min(TimeGenerated), max(TimeGenerated), make_set(DeviceAction) by DiscordServerId, DeviceProduct
  | where dcount_RequestURL <= connectionThreshold
  | mv-expand set_SourceUserName to typeof(string), set_RequestURL to typeof(string), set_DeviceAction to typeof(string), set_SourceIP to typeof(string)
  | summarize by DiscordServerId, DeviceProduct, dcount_RequestURL, set_SourceUserName, min_TimeGenerated, max_TimeGenerated, set_DeviceAction, set_SourceIP, set_RequestURL
  | project StartTime=min_TimeGenerated, EndTime=max_TimeGenerated, DeviceActionTaken=set_DeviceAction, DeviceProduct, SourceUser=set_SourceUserName, SourceIP=set_SourceIP, RequestURL=set_RequestURL
  | where RequestURL has_any (riskyExtensions)  
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2023-02-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/010bd98c-a6be-498c-bdcd-502308c0fdae')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/010bd98c-a6be-498c-bdcd-502308c0fdae')]",
      "properties": {
        "alertRuleTemplateName": "010bd98c-a6be-498c-bdcd-502308c0fdae",
        "customDetails": null,
        "description": "'Identifies callouts to Discord CDN addresses for risky file extensions. This detection will trigger when a callout for a risky file\nis made to a discord server that has only been seen once in your environment. Unique discord servers are identified using the server ID\nthat is included in the request URL (DiscordServerId in query). Discord CDN has been used in multiple campaigns to download additional payloads'\n",
        "displayName": "Discord CDN Risky File Download",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "SourceUser",
                "identifier": "FullName"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "SourceIP",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "URL",
            "fieldMappings": [
              {
                "columnName": "RequestURL",
                "identifier": "Url"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Zscaler Internet Access/Analytic Rules/DiscordCDNRiskyDownload.yaml",
        "query": "let connectionThreshold = 1;\nlet riskyExtensions = dynamic([\".bin\",\".exe\",\".dll\",\".bin\",\".msi\"]);\nCommonSecurityLog\n| where DeviceVendor =~ \"ZScaler\"\n| where RequestURL has_any(\"media.discordapp.net\", \"cdn.discordapp.com\")\n| where RequestURL has \"attachments\"\n| where DeviceAction !~ \"blocked\"\n| extend DiscordServerId = extract(@\"\\/attachments\\/([0-9]+)\\/\", 1, RequestURL)\n| summarize dcount(RequestURL), make_set(SourceUserName), make_set(SourceIP), make_set(RequestURL), min(TimeGenerated), max(TimeGenerated), make_set(DeviceAction) by DiscordServerId, DeviceProduct\n| where dcount_RequestURL <= connectionThreshold\n| mv-expand set_SourceUserName to typeof(string), set_RequestURL to typeof(string), set_DeviceAction to typeof(string), set_SourceIP to typeof(string)\n| summarize by DiscordServerId, DeviceProduct, dcount_RequestURL, set_SourceUserName, min_TimeGenerated, max_TimeGenerated, set_DeviceAction, set_SourceIP, set_RequestURL\n| project StartTime=min_TimeGenerated, EndTime=max_TimeGenerated, DeviceActionTaken=set_DeviceAction, DeviceProduct, SourceUser=set_SourceUserName, SourceIP=set_SourceIP, RequestURL=set_RequestURL\n| where RequestURL has_any (riskyExtensions)\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P1D",
        "severity": "Medium",
        "status": "Available",
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CommandAndControl"
        ],
        "tags": [
          "Discord"
        ],
        "techniques": [
          "T1071"
        ],
        "templateVersion": "1.0.1",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}