Detection rules › Kusto

[Deprecated] - Zinc Actor IOCs domains hashes IPs and useragent - October 2022

Status
available
Severity
high
Time window
6h
Source
github.com/Azure/Azure-Sentinel

Use Microsoft's up-to-date Threat Intelligence solution from the Content Hub to replace the deprecated query with outdated IoCs. Install it from: https://learn.microsoft.com/azure/sentinel/sentinel-solutions-deploy

MITRE ATT&CK coverage

TacticTechniques
Persistence

Telemetry coverage

Rule body

id: 95543d6d-f00d-4193-a63f-4edeefb7ec36
name: "[Deprecated] - Zinc Actor IOCs domains hashes IPs and useragent - October 2022"
description: | 
  'Use Microsoft's up-to-date Threat Intelligence solution from the Content Hub to replace the deprecated query with outdated IoCs. Install it from: https://learn.microsoft.com/azure/sentinel/sentinel-solutions-deploy'
severity: High 
status: Available
requiredDataConnectors: 
  - connectorId: DNS
    dataTypes:
      - DnsEvents
  - connectorId: AzureMonitor(VMInsights)
    dataTypes:
      - VMConnection
  - connectorId: F5
    dataTypes:
      - CommonSecurityLog
  - connectorId: CiscoASA
    dataTypes: 
      - CommonSecurityLog
  - connectorId: CiscoAsaAma
    dataTypes: 
      - CommonSecurityLog
  - connectorId: PaloAltoNetworks
    dataTypes: 
      - CommonSecurityLog
  - connectorId: Fortinet
    dataTypes: 
      - CommonSecurityLog
  - connectorId: CheckPoint
    dataTypes: 
      - CommonSecurityLog
  - connectorId: CEF
    dataTypes: 
      - CommonSecurityLog  
  - connectorId: CefAma
    dataTypes: 
      - CommonSecurityLog             
  - connectorId: MicrosoftThreatProtection
    dataTypes:
      - DeviceNetworkEvents
      - DeviceFileEvents
      - DeviceEvents
      - DeviceProcessEvents
  - connectorId: SecurityEvents
    dataTypes:
      - SecurityEvent
  - connectorId: Office365
    dataTypes:
      - OfficeActivity
  - connectorId: AzureFirewall
    dataTypes: 
      - AzureDiagnostics
  - connectorId: WindowsFirewall
    dataTypes:
      - WindowsFirewall
  - connectorId: WindowsFirewallAma
    dataTypes:
      - WindowsFirewall
  - connectorId: WindowsSecurityEvents
    dataTypes: 
      - SecurityEvents 
  - connectorId: WindowsForwardedEvents
    dataTypes: 
      - WindowsEvent             
queryFrequency: 6h 
queryPeriod: 6h 
triggerOperator: gt 
triggerThreshold: 0 
tactics: 
  - Persistence
relevantTechniques:
  - T1546
tags:
  - Zinc
query:  |
  let iocs = externaldata(DateAdded:string,IoC:string,Type:string) [@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/ZincOctober2022IOCs.csv"] with (format="csv", ignoreFirstRecord=True);
  let domains = (iocs | where Type =~ "domainname"| project IoC);
  let IPList = (iocs | where Type =~ "ip"| project IoC);
  let sha256Hashes = (iocs | where Type =~ "sha256" | project IoC);
  let useragents = (iocs | where Type =~ "useragent" | project IoC);
  (union isfuzzy=true
  (CommonSecurityLog
  | where DestinationHostName has_any (domains) or RequestURL has_any (domains) or Message has_any (domains) or  SourceIP has_any (IPList) or DestinationIP  has_any (IPList)
  | parse Message with * '(' DNSName ')' *
  | project TimeGenerated, Message, SourceUserID, RequestURL, DestinationHostName, Type, SourceIP, DestinationIP, DNSName
  | extend timestamp = TimeGenerated, AccountEntity = SourceUserID, UrlEntity = RequestURL , IPEntity = DestinationIP, DNSCustomEntity = DNSName
  ),
  (DnsEvents
  | where Name in~ (domains) or IPAddresses has_any (IPList)
  | project TimeGenerated, Computer, IPAddresses, Name, ClientIP, Type
  | extend DNSName = Name, Host = Computer
  | extend timestamp = TimeGenerated, HostEntity = Host, DNSCustomEntity = DNSName, IPEntity = IPAddresses
  ),
  (VMConnection
  | where  RemoteDnsCanonicalNames has_any (domains)  or  SourceIp has_any (IPList) or DestinationIp has_any (IPList)
  | parse RemoteDnsCanonicalNames with * '["' DNSName '"]' *
  | project TimeGenerated, Computer, Direction, RemoteDnsCanonicalNames, ProcessName, SourceIp, DestinationIp, DestinationPort, DNSName,BytesSent, BytesReceived, RemoteCountry, Type
  | extend timestamp = TimeGenerated, IPEntity = DestinationIp, HostEntity = Computer, ProcessEntity = ProcessName, DNSCustomEntity = DNSName
  ),
  (Event
  | where Source =~ "Microsoft-Windows-Sysmon"
  | where EventID == 3
  | extend EvData = parse_xml(EventData)
  | extend EventDetail = EvData.DataItem.EventData.Data
  | extend SourceIP = tostring(EventDetail.[9].["#text"]), DestinationIP = tostring(EventDetail.[14].["#text"]), Image = EventDetail.[4].["#text"]
  | where  SourceIP has_any (IPList) or DestinationIP has_any (IPList)
  | project TimeGenerated, SourceIP, DestinationIP, Image, UserName, Computer, EventDetail, Type
  | extend timestamp = TimeGenerated, AccountEntity = UserName, ProcessEntity = tostring(split(Image, '\\', -1)[-1]), HostEntity = Computer , IPEntity = DestinationIP
  ),  
  (DeviceNetworkEvents
  | where RemoteUrl has_any (domains) or RemoteIP has_any (IPList) or InitiatingProcessSHA256 in (sha256Hashes) 
  | project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, RemoteIP, RemoteUrl, LocalIP, Type
  | extend timestamp = TimeGenerated, IPEntity = RemoteIP, HostEntity = DeviceName, UrlEntity =RemoteUrl
  ),
  (AzureDiagnostics
  | where ResourceType =~ "AZUREFIREWALLS"
  | where Category =~ "AzureFirewallDnsProxy"
  | project TimeGenerated,Resource, msg_s, Type
  | parse msg_s with "DNS Request: " ClientIP ":" ClientPort " - " QueryID " " Request_Type " " Request_Class " " Request_Name ". " Request_Protocol " " Request_Size " " EDNSO_DO " " EDNS0_Buffersize " " Responce_Code " " Responce_Flags " " Responce_Size " " Response_Duration
  | where Request_Name has_any (domains) or ClientIP has_any (IPList)
  | extend timestamp = TimeGenerated, DNSName = Request_Name, IPEntity = ClientIP
  ),
  (AzureDiagnostics
  | where ResourceType =~ "AZUREFIREWALLS"
  | where Category =~ "AzureFirewallApplicationRule"
  | project TimeGenerated,Resource, msg_s
  | parse msg_s with Protocol 'request from ' SourceHost ':' SourcePort 'to ' DestinationHost ':' DestinationPort '. Action:' Action
  | where DestinationHost has_any (domains) or SourceHost has_any (IPList)
  | extend timestamp = TimeGenerated, DNSName = DestinationHost, IPEntity = SourceHost
  ),
  (Event
  | where Source =~ "Microsoft-Windows-Sysmon"
  | where EventID == 1
  | extend EvData = parse_xml(EventData)
  | extend EventDetail = EvData.DataItem.EventData.Data
  | parse EventDetail with * 'SHA256=' SHA256 '",' *
  | extend Image = EventDetail.[4].["#text"],  CommandLine = EventDetail.[10].["#text"]
  | where SHA256 has_any (sha256Hashes)
  | project TimeGenerated, EventDetail, UserName, Computer, Type, Source, SHA256, CommandLine, Image
  | extend Type = strcat(Type, ": ", Source)
  | extend timestamp = TimeGenerated, HostEntity = Computer , AccountEntity = UserName, ProcessEntity = tostring(split(Image, '\\', -1)[-1]), AlgorithmEntity = "SHA256", FileHashEntity = SHA256
  ),  
  (DeviceProcessEvents
  | where  InitiatingProcessSHA256 has_any (sha256Hashes)
  | project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessSHA256, FolderPath, Type
  | extend timestamp = TimeGenerated, HostEntity = DeviceName , AccountEntity = InitiatingProcessAccountName, ProcessEntity = InitiatingProcessFileName, AlgorithmEntity = "SHA256", FileHashEntity = InitiatingProcessSHA256
  ),
  (DeviceFileEvents
  | where  InitiatingProcessSHA256 has_any (sha256Hashes)
  | project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, RequestAccountName, RequestSourceIP, InitiatingProcessSHA256, FolderPath, Type
  | extend timestamp = TimeGenerated, HostEntity = DeviceName , AccountEntity = RequestAccountName, ProcessEntity = InitiatingProcessFileName, AlgorithmEntity = "SHA256", FileHashEntity = InitiatingProcessSHA256
  ),
  (DeviceEvents
  | where  InitiatingProcessSHA256 has_any (sha256Hashes)
  | project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessSHA256, FolderPath, Type
  | extend CommandLine = InitiatingProcessCommandLine
  | extend timestamp = TimeGenerated, HostEntity = DeviceName , AccountEntity = InitiatingProcessAccountName, ProcessEntity = InitiatingProcessFileName, AlgorithmEntity = "SHA256", FileHashEntity = InitiatingProcessSHA256
  ),
  (OfficeActivity
  | where ClientIP has_any (IPList) or UserAgent has_any (useragents)
  | project TimeGenerated, UserAgent, Operation, RecordType, UserId, ClientIP, Type
  | extend timestamp = TimeGenerated, IPEntity = ClientIP, AccountEntity = UserId
  )
  )
  | extend HostName = tostring(split(HostEntity, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(HostEntity, '.'), 1, -1), '.'))
  | extend Name = tostring(split(AccountEntity, '@', 0)[0]), UPNSuffix = tostring(split(AccountEntity, '@', 1)[0])
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: Name
      - identifier: UPNSuffix
        columnName: UPNSuffix
  - entityType: Host
    fieldMappings:
      - identifier: HostName
        columnName: HostName
      - identifier: DnsDomain
        columnName: DnsDomain
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: IPEntity 
  - entityType: Process
    fieldMappings:
      - identifier: ProcessId
        columnName: ProcessEntity
  - entityType: FileHash
    fieldMappings:
      - identifier: Algorithm
        columnName: AlgorithmEntity
      - identifier: Value
        columnName: FileHashEntity        
version: 1.0.4
kind: Scheduled

Stages and Predicates

Stage 0: let

let iocs = externaldata(DateAdded:string,IoC:string,Type:string) [@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/ZincOctober2022IOCs.csv"] with (format="csv", ignoreFirstRecord=True);
let domains = (iocs | where Type =~ "domainname"| project IoC);
let IPList = (iocs | where Type =~ "ip"| project IoC);
let sha256Hashes = (iocs | where Type =~ "sha256" | project IoC);
let useragents = (iocs | where Type =~ "useragent" | project IoC);

Stage 1: union

union of 12 branches

Stage 2: source

CommonSecurityLog

Stage 3: where

| where DestinationHostName has_any (domains) or RequestURL has_any (domains) or Message has_any (domains) or  SourceIP has_any (IPList) or DestinationIP  has_any (IPList)

Stage 4: parse

| parse Message with * '(' DNSName ')' *

Stage 5: project

| project TimeGenerated, Message, SourceUserID, RequestURL, DestinationHostName, Type, SourceIP, DestinationIP, DNSName

Stage 6: extend

| extend timestamp = TimeGenerated, AccountEntity = SourceUserID, UrlEntity = RequestURL , IPEntity = DestinationIP, DNSCustomEntity = DNSName

Stage 7: source

DnsEvents

Stage 8: where

| where Name in~ (domains) or IPAddresses has_any (IPList)

Stage 9: project

| project TimeGenerated, Computer, IPAddresses, Name, ClientIP, Type

Stage 10: extend

| extend DNSName = Name, Host = Computer

Stage 11: extend

| extend timestamp = TimeGenerated, HostEntity = Host, DNSCustomEntity = DNSName, IPEntity = IPAddresses

Stage 12: source

VMConnection

Stage 13: where

| where  RemoteDnsCanonicalNames has_any (domains)  or  SourceIp has_any (IPList) or DestinationIp has_any (IPList)

Stage 14: parse

| parse RemoteDnsCanonicalNames with * '["' DNSName '"]' *

Stage 15: project

| project TimeGenerated, Computer, Direction, RemoteDnsCanonicalNames, ProcessName, SourceIp, DestinationIp, DestinationPort, DNSName,BytesSent, BytesReceived, RemoteCountry, Type

Stage 16: extend

| extend timestamp = TimeGenerated, IPEntity = DestinationIp, HostEntity = Computer, ProcessEntity = ProcessName, DNSCustomEntity = DNSName

Stage 17: source

Event

Stage 18: where

| where Source =~ "Microsoft-Windows-Sysmon"

Stage 19: where

| where EventID == 3

Stage 20: extend (3 consecutive steps)

| extend EvData = parse_xml(EventData)
| extend EventDetail = EvData.DataItem.EventData.Data
| extend SourceIP = tostring(EventDetail.[9].["#text"]), DestinationIP = tostring(EventDetail.[14].["#text"]), Image = EventDetail.[4].["#text"]

Stage 21: where

| where  SourceIP has_any (IPList) or DestinationIP has_any (IPList)

Stage 22: project

| project TimeGenerated, SourceIP, DestinationIP, Image, UserName, Computer, EventDetail, Type

Stage 23: extend

| extend timestamp = TimeGenerated, AccountEntity = UserName, ProcessEntity = tostring(split(Image, '\\', -1)[-1]), HostEntity = Computer , IPEntity = DestinationIP

Stage 24: source

DeviceNetworkEvents

Stage 25: where

| where RemoteUrl has_any (domains) or RemoteIP has_any (IPList) or InitiatingProcessSHA256 in (sha256Hashes)

Stage 26: project

| project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, RemoteIP, RemoteUrl, LocalIP, Type

Stage 27: extend

| extend timestamp = TimeGenerated, IPEntity = RemoteIP, HostEntity = DeviceName, UrlEntity =RemoteUrl

Stage 28: source

AzureDiagnostics

Stage 29: where

| where ResourceType =~ "AZUREFIREWALLS"

Stage 30: where

| where Category =~ "AzureFirewallDnsProxy"

Stage 31: project

| project TimeGenerated,Resource, msg_s, Type

Stage 32: parse

| parse msg_s with "DNS Request: " ClientIP ":" ClientPort " - " QueryID " " Request_Type " " Request_Class " " Request_Name ". " Request_Protocol " " Request_Size " " EDNSO_DO " " EDNS0_Buffersize " " Responce_Code " " Responce_Flags " " Responce_Size " " Response_Duration

Stage 33: where

| where Request_Name has_any (domains) or ClientIP has_any (IPList)

Stage 34: extend

| extend timestamp = TimeGenerated, DNSName = Request_Name, IPEntity = ClientIP

Stage 35: source

AzureDiagnostics

Stage 36: where

| where ResourceType =~ "AZUREFIREWALLS"

Stage 37: where

| where Category =~ "AzureFirewallApplicationRule"

Stage 38: project

| project TimeGenerated,Resource, msg_s

Stage 39: parse

| parse msg_s with Protocol 'request from ' SourceHost ':' SourcePort 'to ' DestinationHost ':' DestinationPort '. Action:' Action

Stage 40: where

| where DestinationHost has_any (domains) or SourceHost has_any (IPList)

Stage 41: extend

| extend timestamp = TimeGenerated, DNSName = DestinationHost, IPEntity = SourceHost

Stage 42: source

Event

Stage 43: where

| where Source =~ "Microsoft-Windows-Sysmon"

Stage 44: where

| where EventID == 1

Stage 45: extend

| extend EvData = parse_xml(EventData)

Stage 46: extend

| extend EventDetail = EvData.DataItem.EventData.Data

Stage 47: parse

| parse EventDetail with * 'SHA256=' SHA256 '",' *

Stage 48: extend

| extend Image = EventDetail.[4].["#text"],  CommandLine = EventDetail.[10].["#text"]

Stage 49: where

| where SHA256 has_any (sha256Hashes)

Stage 50: project

| project TimeGenerated, EventDetail, UserName, Computer, Type, Source, SHA256, CommandLine, Image

Stage 51: extend

| extend Type = strcat(Type, ": ", Source)

Stage 52: extend

| extend timestamp = TimeGenerated, HostEntity = Computer , AccountEntity = UserName, ProcessEntity = tostring(split(Image, '\\', -1)[-1]), AlgorithmEntity = "SHA256", FileHashEntity = SHA256

Stage 53: source

DeviceProcessEvents

Stage 54: where

| where  InitiatingProcessSHA256 has_any (sha256Hashes)

Stage 55: project

| project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessSHA256, FolderPath, Type

Stage 56: extend

| extend timestamp = TimeGenerated, HostEntity = DeviceName , AccountEntity = InitiatingProcessAccountName, ProcessEntity = InitiatingProcessFileName, AlgorithmEntity = "SHA256", FileHashEntity = InitiatingProcessSHA256

Stage 57: source

DeviceFileEvents

Stage 58: where

| where  InitiatingProcessSHA256 has_any (sha256Hashes)

Stage 59: project

| project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, RequestAccountName, RequestSourceIP, InitiatingProcessSHA256, FolderPath, Type

Stage 60: extend

| extend timestamp = TimeGenerated, HostEntity = DeviceName , AccountEntity = RequestAccountName, ProcessEntity = InitiatingProcessFileName, AlgorithmEntity = "SHA256", FileHashEntity = InitiatingProcessSHA256

Stage 61: source

DeviceEvents

Stage 62: where

| where  InitiatingProcessSHA256 has_any (sha256Hashes)

Stage 63: project

| project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessSHA256, FolderPath, Type

Stage 64: extend

| extend CommandLine = InitiatingProcessCommandLine

Stage 65: extend

| extend timestamp = TimeGenerated, HostEntity = DeviceName , AccountEntity = InitiatingProcessAccountName, ProcessEntity = InitiatingProcessFileName, AlgorithmEntity = "SHA256", FileHashEntity = InitiatingProcessSHA256

Stage 66: source

OfficeActivity

Stage 67: where

| where ClientIP has_any (IPList) or UserAgent has_any (useragents)

Stage 68: project

| project TimeGenerated, UserAgent, Operation, RecordType, UserId, ClientIP, Type

Stage 69: extend (3 consecutive steps)

| extend timestamp = TimeGenerated, IPEntity = ClientIP, AccountEntity = UserId

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Categoryeq
  • AzureFirewallApplicationRule
  • AzureFirewallDnsProxy
field:"Category" kind:eq
ClientIPmatch
  • IPList transforms: term
field:"ClientIP" kind:match value:"IPList"
DestinationHostmatch
  • domains transforms: term corpus 2 (kusto 2)
field:"DestinationHost" kind:match value:"domains"
DestinationHostNamematch
  • domains transforms: term corpus 2 (kusto 2)
field:"DestinationHostName" kind:match value:"domains"
DestinationIPmatch
  • IPList transforms: term
field:"DestinationIP" kind:match value:"IPList"
DestinationIpmatch
  • IPList transforms: term corpus 2 (kusto 2)
field:"dest_ip" kind:match value:"IPList"
EventIDeq
  • 1 corpus 242 (splunk 226, kusto 15, elastic 1)
  • 3 corpus 25 (splunk 15, kusto 8, chronicle 2)
field:"EventID" kind:eq
IPAddressesmatch
  • IPList transforms: term
field:"IPAddresses" kind:match value:"IPList"
InitiatingProcessSHA256in
  • sha256Hashes corpus 3 (kusto 3)
field:"InitiatingProcessSHA256" kind:in value:"sha256Hashes"
InitiatingProcessSHA256match
  • sha256Hashes transforms: term
field:"InitiatingProcessSHA256" kind:match value:"sha256Hashes"
Messagematch
  • domains transforms: term
field:"Message" kind:match value:"domains"
Namein
  • domains corpus 2 (kusto 2)
field:"Name" kind:in value:"domains"
RemoteDnsCanonicalNamesmatch
  • domains transforms: term corpus 2 (kusto 2)
field:"RemoteDnsCanonicalNames" kind:match value:"domains"
RemoteIPmatch
  • IPList transforms: term corpus 2 (kusto 2)
field:"dest_ip" kind:match value:"IPList"
RemoteUrlmatch
  • domains transforms: term corpus 2 (kusto 2)
field:"DestinationHostname" kind:match value:"domains"
RequestURLmatch
  • domains transforms: term corpus 2 (kusto 2)
field:"RequestURL" kind:match value:"domains"
Request_Namematch
  • domains transforms: term
field:"Request_Name" kind:match value:"domains"
ResourceTypeeq
  • AZUREFIREWALLS corpus 2 (kusto 2)
field:"ResourceType" kind:eq value:"AZUREFIREWALLS"
SHA256match
  • sha256Hashes transforms: term corpus 3 (kusto 3)
field:"sha256" kind:match value:"sha256Hashes"
SourceHostmatch
  • IPList transforms: term
field:"SourceHost" kind:match value:"IPList"
SourceIPmatch
  • IPList transforms: term
field:"SourceIP" kind:match value:"IPList"
SourceIpmatch
  • IPList transforms: term
field:"src_ip" kind:match value:"IPList"
UserAgentmatch
  • useragents transforms: term
field:"aws::userAgent" kind:match value:"useragents"

Output fields

These fields are emitted when the rule matches.

FieldSource
ClientIPproject
Operationproject
RecordTypeproject
TimeGeneratedproject
Typeproject
UserAgentproject
UserIdproject
AccountEntityextend
IPEntityextend
timestampextend
DnsDomainextend
HostNameextend
Nameextend
UPNSuffixextend