Detection rules › Kusto

AV detections related to Dev-0530 actors

Severity
high
Time window
1d
Group by
AlertSeverity, CompromisedEntity, Description, DeviceId, DeviceName, DisplayName, Entities, ProductName, PublicIP, TenantId, ThreatFamilyName, ThreatName
Author
Microsoft Security Research
Source
github.com/Azure/Azure-Sentinel

This query looks for Microsoft Defender AV detections related to Dev-0530 actors. In Microsoft Sentinel the SecurityAlerts table includes only the Device Name of the affected device, this query joins the DeviceInfo table to clearly connect other information such as Device group, ip, logged on users etc. This would allow the Microsoft Sentinel analyst to have more context related to the alert, if available.

MITRE ATT&CK coverage

TacticTechniques
Impact

Telemetry coverage

Rule body

id: 5f171045-88ab-4634-baae-a7b6509f483b
name: AV detections related to Dev-0530 actors
description: |
  'This query looks for Microsoft Defender AV detections related to  Dev-0530 actors.
  In Microsoft Sentinel the SecurityAlerts table includes only the Device Name of the affected device, this query joins the DeviceInfo table to clearly connect other information such as Device group, ip, logged on users etc. This would allow the Microsoft Sentinel analyst to have more context related to the alert, if available.'
severity: High
requiredDataConnectors:
  - connectorId: MicrosoftThreatProtection
    dataTypes:
      - SecurityAlert
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Impact
relevantTechniques:
  - T1486
tags:
  -  Dev-0530 actors
query: |
  let Dev0530_threats = dynamic(["Trojan:Win32/SiennaPurple.A", "Ransom:Win32/SiennaBlue.A", "Ransom:Win32/SiennaBlue.B"]);
  SecurityAlert
  | where ProviderName == "MDATP"
  | extend ThreatName = tostring(parse_json(ExtendedProperties).ThreatName)
  | extend ThreatFamilyName = tostring(parse_json(ExtendedProperties).ThreatFamilyName)
  | where ThreatName in~ (Dev0530_threats) or ThreatFamilyName in~ (Dev0530_threats)
  | extend CompromisedEntity = tolower(CompromisedEntity)
  | join kind=inner (DeviceInfo
      | extend DeviceName = tolower(DeviceName)
  ) on $left.CompromisedEntity == $right.DeviceName
  | summarize by bin(TimeGenerated, 1d), DisplayName, ThreatName, ThreatFamilyName, PublicIP, AlertSeverity, Description, tostring(LoggedOnUsers), DeviceId, TenantId, CompromisedEntity, tostring(LoggedOnUsers), ProductName, Entities
  | extend HostName = tostring(split(CompromisedEntity, ".")[0]), DomainIndex = toint(indexof(CompromisedEntity, '.'))
  | extend HostNameDomain = iff(DomainIndex != -1, substring(CompromisedEntity, DomainIndex + 1), CompromisedEntity)
  | project-away DomainIndex
entityMappings:
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: CompromisedEntity
      - identifier: HostName
        columnName: HostName
      - identifier: DnsDomain
        columnName: HostNameDomain
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: PublicIP
version: 1.0.5
kind: Scheduled
metadata:
    source:
        kind: Community
    author:
        name: Microsoft Security Research
    support:
        tier: Community
    categories:
        domains: [ "Security - Others" ]

Stages and Predicates

Parameters

let Dev0530_threats = dynamic(["Trojan:Win32/SiennaPurple.A", "Ransom:Win32/SiennaBlue.A", "Ransom:Win32/SiennaBlue.B"]);

Stage 1: source

SecurityAlert

Stage 2: where

| where ProviderName == "MDATP"

Stage 3: extend

| extend ThreatName = tostring(parse_json(ExtendedProperties).ThreatName)

Stage 4: extend

| extend ThreatFamilyName = tostring(parse_json(ExtendedProperties).ThreatFamilyName)

Stage 5: where

| where ThreatName in~ (Dev0530_threats) or ThreatFamilyName in~ (Dev0530_threats)

Stage 6: extend

| extend CompromisedEntity = tolower(CompromisedEntity)

Stage 7: join

| join kind=inner (DeviceInfo
    | extend DeviceName = tolower(DeviceName)
) on $left.CompromisedEntity == $right.DeviceName

Stage 8: summarize

| summarize by bin(TimeGenerated, 1d), DisplayName, ThreatName, ThreatFamilyName, PublicIP, AlertSeverity, Description, tostring(LoggedOnUsers), DeviceId, TenantId, CompromisedEntity, tostring(LoggedOnUsers), ProductName, Entities

Stage 9: extend

| extend HostName = tostring(split(CompromisedEntity, ".")[0]), DomainIndex = toint(indexof(CompromisedEntity, '.'))

Stage 10: extend

| extend HostNameDomain = iff(DomainIndex != -1, substring(CompromisedEntity, DomainIndex + 1), CompromisedEntity)
HostNameDomain =
ifDomainIndex != -1substring(CompromisedEntity, (DomainIndex + 1))
elseCompromisedEntity

Stage 11: project-away

| project-away DomainIndex

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
ProviderNameeq
  • MDATP
field:"ProviderName" kind:eq value:"MDATP"
ThreatFamilyNamein
  • Ransom:Win32/SiennaBlue.A
  • Ransom:Win32/SiennaBlue.B
  • Trojan:Win32/SiennaPurple.A
field:"ThreatFamilyName" kind:in
ThreatNamein
  • Ransom:Win32/SiennaBlue.A
  • Ransom:Win32/SiennaBlue.B
  • Trojan:Win32/SiennaPurple.A
field:"ThreatName" kind:in

Output fields

These fields are emitted when the rule matches.

FieldSource
AlertSeveritysummarize
CompromisedEntitysummarize
Descriptionsummarize
DeviceIdsummarize
DisplayNamesummarize
Entitiessummarize
ProductNamesummarize
PublicIPsummarize
TenantIdsummarize
ThreatFamilyNamesummarize
ThreatNamesummarize
HostNameextend
HostNameDomainextend