Detection rules › Kusto
Prestige ransomware IOCs Oct 2022
'This query looks for file hashes and AV signatures associated with Prestige ransomware payload.'
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Execution | T1203 Exploitation for Client Execution |
Rule body kusto
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
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
EventID | eq |
|
FileHash | in |
|
Hashes[0] | eq |
|
Hashes[1] | match |
|
InitiatingProcessSHA256 | match |
|
ProductName | eq |
|
SHA256 | match |
|
TargetFileSHA256 | match |
|
ThreatName | is_not_null | |
ThreatName | match |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
ActionType | project |
DeviceId | project |
DeviceName | project |
InitiatingProcessAccountDomain | project |
InitiatingProcessAccountName | project |
InitiatingProcessCommandLine | project |
InitiatingProcessFileName | project |
InitiatingProcessFolderPath | project |
InitiatingProcessId | project |
InitiatingProcessParentFileName | project |
InitiatingProcessSHA256 | project |
TimeGenerated | project |
Type | project |
AccountNT | extend |
Computer | extend |
Algorithm | extend |
CommandLine | extend |
FileHash | extend |
Image | extend |
ThreatName | extend |
AccountNTDomain | extend |
AccountNTName | extend |
HostName | extend |
HostNameDomain | extend |