Detection rules › Kusto

Prestige ransomware IOCs Oct 2022

Severity
high
Time window
1d
Author
Microsoft Security Research
Source
github.com/Azure/Azure-Sentinel

This query looks for file hashes and AV signatures associated with Prestige ransomware payload.

MITRE ATT&CK coverage

Telemetry coverage

Rule body

id: bca9c877-2afc-4246-a26d-087ab1cdcd5f
name: Prestige ransomware IOCs Oct 2022
description: |
  'This query looks for file hashes and AV signatures associated with Prestige ransomware payload.'
severity: High
requiredDataConnectors:
  - connectorId: MicrosoftThreatProtection
    dataTypes:
      - DeviceEvents
      - DeviceFileEvents
      - DeviceImageLoadEvents
  - connectorId: SecurityEvents
    dataTypes:
      - SecurityEvents  
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Execution
relevantTechniques:
  - T1203
tags:
  - Prestige
  - Ransomware
query: |
  let sha256Hashes = dynamic(["5dd1ca0d471dee41eb3ea0b6ea117810f228354fc3b7b47400a812573d40d91d", "5fc44c7342b84f50f24758e39c8848b2f0991e8817ef5465844f5f2ff6085a57", "6cff0bbd62efe99f381e5cc0c4182b0fb7a9a34e4be9ce68ee6b0d0ea3eee39c"]);
  let signames = dynamic(["Ransom:Win32/Prestige"]);
  (union isfuzzy=true
  (CommonSecurityLog
  | where FileHash in (sha256Hashes)
  | project TimeGenerated, Message, SourceUserID, FileHash, Type
  | extend timestamp = TimeGenerated, Algorithm = "SHA256", AccountNTName = SourceUserID
  ),
  (imFileEvent
  | where TargetFileSHA256 has_any (sha256Hashes)
  | extend AccountNT = ActorUsername, Computer = DvcHostname, IPAddress = SrcIpAddr, CommandLine = ActingProcessCommandLine, FileHash = TargetFileSHA256
  | project Type, TimeGenerated, Computer, AccountNT, IPAddress, CommandLine, FileHash, Algorithm = "SHA256"
  ),
  (Event
  | where Source =~ "Microsoft-Windows-Sysmon"
  | where EventID == 1
  | extend EvData = parse_xml(EventData)
  | extend EventDetail = EvData.DataItem.EventData.Data
  | extend ProcessId = tolong(EventDetail.[3].["#text"]), Image = tostring(EventDetail.[4].["#text"]), CommandLine = tostring(EventDetail.[10].["#text"]), Hashes = tostring(EventDetail.[17].["#text"])
  | extend Hashes = extract_all(@"(?P<key>\w+)=(?P<value>[a-zA-Z0-9]+)", dynamic(["key","value"]), Hashes)
  | extend Hashes = column_ifexists("Hashes", dynamic(["", ""])), CommandLine = column_ifexists("CommandLine", "")
  | mv-expand Hashes
  | where Hashes[0] =~ "SHA256" and Hashes[1] has_any (sha256Hashes)  
  | project TimeGenerated, EventDetail, UserName, Computer, Type, Source, ProcessId, Hashes, CommandLine, Image
  | extend Type = strcat(Type, ": ", Source)
  | extend AccountNT = UserName, InitiatingProcessId = ProcessId
  | extend Process = tostring(split(Image, '\\', -1)[-1]), Algorithm = "SHA256", FileHash = tostring(Hashes[1]) 
  ),
  (DeviceEvents
  | where InitiatingProcessSHA256 has_any (sha256Hashes) or SHA256 has_any (sha256Hashes)
  | project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessSHA256, Type
  | extend AccountNT = InitiatingProcessAccountName, Computer = DeviceName
  | extend Algorithm = "SHA256", FileHash = tostring(InitiatingProcessSHA256), CommandLine = InitiatingProcessCommandLine, Image = InitiatingProcessFolderPath
  ),
  (DeviceFileEvents
  | where SHA256 has_any (sha256Hashes)
  | project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessSHA256, Type
  | extend AccountNT = InitiatingProcessAccountName, Computer = DeviceName
  | extend Algorithm = "SHA256", FileHash = tostring(InitiatingProcessSHA256), CommandLine = InitiatingProcessCommandLine, Image = InitiatingProcessFolderPath
  ),
  (DeviceImageLoadEvents
  | where SHA256 has_any (sha256Hashes)
  | project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessSHA256, Type
  | extend AccountNT = InitiatingProcessAccountName, Computer = DeviceName
  | extend Algorithm = "SHA256", FileHash = tostring(InitiatingProcessSHA256), CommandLine = InitiatingProcessCommandLine, Image = InitiatingProcessFolderPath
  ),
  (SecurityAlert
  | where ProductName == "Microsoft Defender Advanced Threat Protection"
  | extend ThreatName = tostring(parse_json(ExtendedProperties).ThreatName)
  | where isnotempty(ThreatName)
  | where ThreatName has_any (signames)
  | extend Computer = tostring(parse_json(Entities)[0].HostName)
  )
  )
  | extend AccountNTName = tostring(split(AccountNT, "\\")[0]), AccountNTDomain = tostring(split(AccountNT, "\\")[1])
  | extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
  | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
  | project-away DomainIndex
entityMappings:
  - entityType: FileHash
    fieldMappings:
      - identifier: Algorithm
        columnName: Algorithm
      - identifier: Value
        columnName: FileHash
  - entityType: Process
    fieldMappings:
      - identifier: ProcessId
        columnName: InitiatingProcessId
      - identifier: CommandLine
        columnName: CommandLine
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: AccountNT
      - identifier: Name
        columnName: AccountNTName
      - identifier: UPNSuffix
        columnName: AccountNTDomain
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: Computer
      - identifier: HostName
        columnName: HostName
      - identifier: NTDomain
        columnName: HostNameDomain
version: 1.0.4
kind: Scheduled
metadata:
    source:
        kind: Community
    author:
        name: Microsoft Security Research
    support:
        tier: Community
    categories:
        domains: [ "Security - Others" ]

Stages and Predicates

Parameters

let signames = dynamic(["Ransom:Win32/Prestige"]);

Let binding: sha256Hashes

let sha256Hashes = dynamic(["5dd1ca0d471dee41eb3ea0b6ea117810f228354fc3b7b47400a812573d40d91d", "5fc44c7342b84f50f24758e39c8848b2f0991e8817ef5465844f5f2ff6085a57", "6cff0bbd62efe99f381e5cc0c4182b0fb7a9a34e4be9ce68ee6b0d0ea3eee39c"]);

union isfuzzy=true (7 sources)

Each leg below queries one source; the rule matches if any leg does. Sources: CommonSecurityLog, imFileEvent, Event, DeviceEvents, DeviceFileEvents, DeviceImageLoadEvents, SecurityAlert

Leg 1: CommonSecurityLog

CommonSecurityLog
| where FileHash in (sha256Hashes)
| project TimeGenerated, Message, SourceUserID, FileHash, Type
| extend timestamp = TimeGenerated, Algorithm = "SHA256", AccountNTName = SourceUserID

Leg 2: imFileEvent

imFileEvent
| where TargetFileSHA256 has_any (sha256Hashes)
| extend AccountNT = ActorUsername, Computer = DvcHostname, IPAddress = SrcIpAddr, CommandLine = ActingProcessCommandLine, FileHash = TargetFileSHA256
| project Type, TimeGenerated, Computer, AccountNT, IPAddress, CommandLine, FileHash, Algorithm = "SHA256"

Leg 3: Event

Event
| where Source =~ "Microsoft-Windows-Sysmon"
| where EventID == 1
| extend EvData = parse_xml(EventData)
| extend EventDetail = EvData.DataItem.EventData.Data
| extend ProcessId = tolong(EventDetail.[3].["#text"]), Image = tostring(EventDetail.[4].["#text"]), CommandLine = tostring(EventDetail.[10].["#text"]), Hashes = tostring(EventDetail.[17].["#text"])
| extend Hashes = extract_all(@"(?P<key>\w+)=(?P<value>[a-zA-Z0-9]+)", dynamic(["key","value"]), Hashes)
| extend Hashes = column_ifexists("Hashes", dynamic(["", ""])), CommandLine = column_ifexists("CommandLine", "")
| mv-expand Hashes
| where Hashes[0] =~ "SHA256" and Hashes[1] has_any (sha256Hashes)  
| project TimeGenerated, EventDetail, UserName, Computer, Type, Source, ProcessId, Hashes, CommandLine, Image
| extend Type = strcat(Type, ": ", Source)
| extend AccountNT = UserName, InitiatingProcessId = ProcessId
| extend Process = tostring(split(Image, '\\', -1)[-1]), Algorithm = "SHA256", FileHash = tostring(Hashes[1])

Leg 4: DeviceEvents

DeviceEvents
| where InitiatingProcessSHA256 has_any (sha256Hashes) or SHA256 has_any (sha256Hashes)
| project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessSHA256, Type
| extend AccountNT = InitiatingProcessAccountName, Computer = DeviceName
| extend Algorithm = "SHA256", FileHash = tostring(InitiatingProcessSHA256), CommandLine = InitiatingProcessCommandLine, Image = InitiatingProcessFolderPath

Leg 5: DeviceFileEvents

DeviceFileEvents
| where SHA256 has_any (sha256Hashes)
| project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessSHA256, Type
| extend AccountNT = InitiatingProcessAccountName, Computer = DeviceName
| extend Algorithm = "SHA256", FileHash = tostring(InitiatingProcessSHA256), CommandLine = InitiatingProcessCommandLine, Image = InitiatingProcessFolderPath

Leg 6: DeviceImageLoadEvents

DeviceImageLoadEvents
| where SHA256 has_any (sha256Hashes)
| project TimeGenerated, ActionType, DeviceId, DeviceName, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, InitiatingProcessFolderPath, InitiatingProcessId, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessSHA256, Type
| extend AccountNT = InitiatingProcessAccountName, Computer = DeviceName
| extend Algorithm = "SHA256", FileHash = tostring(InitiatingProcessSHA256), CommandLine = InitiatingProcessCommandLine, Image = InitiatingProcessFolderPath

Leg 7: SecurityAlert

SecurityAlert
| where ProductName == "Microsoft Defender Advanced Threat Protection"
| extend ThreatName = tostring(parse_json(ExtendedProperties).ThreatName)
| where isnotempty(ThreatName)
| where ThreatName has_any (signames)
| extend Computer = tostring(parse_json(Entities)[0].HostName)

Applied to the combined result

| extend AccountNTName = tostring(split(AccountNT, "\\")[0]), AccountNTDomain = tostring(split(AccountNT, "\\")[1])
| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
| project-away DomainIndex

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventIDeq
  • 1 corpus 241 (splunk 225, kusto 15, elastic 1)
field:"EventID" kind:eq value:"1"
FileHashin
  • 5dd1ca0d471dee41eb3ea0b6ea117810f228354fc3b7b47400a812573d40d91d
  • 5fc44c7342b84f50f24758e39c8848b2f0991e8817ef5465844f5f2ff6085a57
  • 6cff0bbd62efe99f381e5cc0c4182b0fb7a9a34e4be9ce68ee6b0d0ea3eee39c
field:"FileHash" kind:in
Hashes[0]eq
  • SHA256 corpus 3 (kusto 3)
field:"Hashes[0]" kind:eq value:"SHA256"
Hashes[1]match
  • 5dd1ca0d471dee41eb3ea0b6ea117810f228354fc3b7b47400a812573d40d91d transforms: term
  • 5fc44c7342b84f50f24758e39c8848b2f0991e8817ef5465844f5f2ff6085a57 transforms: term
  • 6cff0bbd62efe99f381e5cc0c4182b0fb7a9a34e4be9ce68ee6b0d0ea3eee39c transforms: term
field:"Hashes[1]" kind:match
InitiatingProcessSHA256match
  • 5dd1ca0d471dee41eb3ea0b6ea117810f228354fc3b7b47400a812573d40d91d transforms: term
  • 5fc44c7342b84f50f24758e39c8848b2f0991e8817ef5465844f5f2ff6085a57 transforms: term
  • 6cff0bbd62efe99f381e5cc0c4182b0fb7a9a34e4be9ce68ee6b0d0ea3eee39c transforms: term
field:"InitiatingProcessSHA256" kind:match
ProductNameeq
  • Microsoft Defender Advanced Threat Protection
field:"ProductName" kind:eq value:"Microsoft Defender Advanced Threat Protection"
SHA256match
  • 5dd1ca0d471dee41eb3ea0b6ea117810f228354fc3b7b47400a812573d40d91d transforms: term
  • 5fc44c7342b84f50f24758e39c8848b2f0991e8817ef5465844f5f2ff6085a57 transforms: term
  • 6cff0bbd62efe99f381e5cc0c4182b0fb7a9a34e4be9ce68ee6b0d0ea3eee39c transforms: term
field:"sha256" kind:match
TargetFileSHA256match
  • 5dd1ca0d471dee41eb3ea0b6ea117810f228354fc3b7b47400a812573d40d91d transforms: term
  • 5fc44c7342b84f50f24758e39c8848b2f0991e8817ef5465844f5f2ff6085a57 transforms: term
  • 6cff0bbd62efe99f381e5cc0c4182b0fb7a9a34e4be9ce68ee6b0d0ea3eee39c transforms: term
field:"sha256" kind:match
ThreatNameis_not_null
  • (no value, null check)
field:"ThreatName" kind:is_not_null
ThreatNamematch
  • signames transforms: term
field:"ThreatName" kind:match value:"signames"

Output fields

These fields are emitted when the rule matches.

FieldSource
ActionTypeproject
DeviceIdproject
DeviceNameproject
InitiatingProcessAccountDomainproject
InitiatingProcessAccountNameproject
InitiatingProcessCommandLineproject
InitiatingProcessFileNameproject
InitiatingProcessFolderPathproject
InitiatingProcessIdproject
InitiatingProcessParentFileNameproject
InitiatingProcessSHA256project
TimeGeneratedproject
Typeproject
AccountNTextend
Computerextend
Algorithmextend
CommandLineextend
FileHashextend
Imageextend
ThreatNameextend
AccountNTDomainextend
AccountNTNameextend
HostNameextend
HostNameDomainextend