Detection rules › Kusto
Jamf Protect - Alerts
This is a third-party alert feed, not a detection over modeled telemetry. The vendor product raised the finding; this rule forwards it into the SIEM. It is searchable for reference but is excluded from the detection-rule browse and the ATT&CK coverage matrix.
'Creates an incident based on Jamf Protect Alert data in Microsoft Sentinel'
Rule body kusto
id: 6098daa0-f05e-44d5-b5a0-913e63ba3179
name: Jamf Protect - Alerts
description: |
'Creates an incident based on Jamf Protect Alert data in Microsoft Sentinel'
severity: High
status: Available
requiredDataConnectors:
- connectorId: JamfProtect
dataTypes:
- jamfprotectalerts_CL
suppressionDuration: PT5H
suppressionEnabled: false
tactics:
relevantTechniques:
query: |
jamfprotectalerts_CL
| extend
algorithm = "SHA256",
Host_IPs = tostring(parse_json(DvcIpAddr)[0]),
Tags = parse_json(tostring(parse_json(tostring(input.match)).tags)),
Tactics = case(input.match.tags has "Execution", "Execution", input.match.tags has "Visibility", "Visibility", input.match.tags has "Persistence", "Persistence", input.match.tags has "LateralMovement", "LateralMovement", input.match.tags has "CredentialAccess", "CredentialAcccess", input.match.tags has "DefenseEvasion", "DefenseEvasion", input.match.tags has "PrivilegeEscalation", "PrivilegeEscalation", input.match.tags has "Impact", "Impact", input.match.tags has "CommandAndControl", "CommandandControl", input.match.tags has "Discovery", "Discovery", input.match.tags has "InitialAccess", "InitialAccess", ""),
Techniques = pack_array(extract(@"[A-Za-z]\d{4}", 0, tostring(input.match.tags))),
JamfPro = case(input.match.actions has "SmartGroup", "Workflow with Jamf Pro", input.match.actions has "Prevented", "No workflow, Prevented by Protect", "No workflow")
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: false
reopenClosedIncident: false
lookbackDuration: PT5H
matchingMethod: AllEntities
eventGroupingSettings:
aggregationKind: AlertPerResult
alertDetailsOverride:
alertDisplayNameFormat: "{{EventMessage}} detected on {{DvcHostname}}"
alertDescriptionFormat: "{{EventResultMessage}} - Please investigate"
alertTacticsColumnName: Tactics
alertSeverityColumnName: EventSeverity
alertDynamicProperties:
- alertProperty: ProviderName
value: EventVendor
- alertProperty: ProductName
value: EventProduct
- alertProperty: Techniques
value: Techniques
customDetails:
Protect_Event_Type: EventType
Protect_Analytic: EventMessage
Related_File_hash: TargetBinarySHA256
Related_Binaries: TargetBinaryFilePath
TargetBinarySignMsg: TargetBinarySigningInfoMessage
TargetbinarySign: TargetbinarySignerType
TargetBinarySigner: TargetBinarySigningTeamID
JamfPro_Status: JamfPro
Protect_Tags: Tags
entityMappings:
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: DvcHostname
- identifier: OSFamily
columnName: DvcOs
- identifier: OSVersion
columnName: DvcOsVersion
- entityType: IP
fieldMappings:
- identifier: Address
columnName: Host_IPs
- entityType: Process
fieldMappings:
- identifier: CommandLine
columnName: TargetProcessCurrentDirectory
- identifier: ProcessId
columnName: TargetProcessId
- entityType: FileHash
fieldMappings:
- identifier: Algorithm
columnName: algorithm
- identifier: Value
columnName: TargetBinarySHA256
version: 1.0.6
kind: NRT
Stages and Predicates
Stage 1: source
jamfprotectalerts_CL
Stage 2: extend
| extend
algorithm = "SHA256",
Host_IPs = tostring(parse_json(DvcIpAddr)[0]),
Tags = parse_json(tostring(parse_json(tostring(input.match)).tags)),
Tactics = case(input.match.tags has "Execution", "Execution", input.match.tags has "Visibility", "Visibility", input.match.tags has "Persistence", "Persistence", input.match.tags has "LateralMovement", "LateralMovement", input.match.tags has "CredentialAccess", "CredentialAcccess", input.match.tags has "DefenseEvasion", "DefenseEvasion", input.match.tags has "PrivilegeEscalation", "PrivilegeEscalation", input.match.tags has "Impact", "Impact", input.match.tags has "CommandAndControl", "CommandandControl", input.match.tags has "Discovery", "Discovery", input.match.tags has "InitialAccess", "InitialAccess", ""),
Techniques = pack_array(extract(@"[A-Za-z]\d{4}", 0, tostring(input.match.tags))),
JamfPro = case(input.match.actions has "SmartGroup", "Workflow with Jamf Pro", input.match.actions has "Prevented", "No workflow, Prevented by Protect", "No workflow")
JamfPro =actions has "SmartGroup""Workflow with Jamf Pro"actions has "Prevented""No workflow, Prevented by Protect""No workflow"Tactics =tags has "Execution""Execution"tags has "Visibility""Visibility"tags has "Persistence""Persistence"tags has "LateralMovement""LateralMovement"tags has "CredentialAccess""CredentialAcccess"tags has "DefenseEvasion""DefenseEvasion"tags has "PrivilegeEscalation""PrivilegeEscalation"tags has "Impact""Impact"tags has "CommandAndControl""CommandandControl"tags has "Discovery""Discovery"tags has "InitialAccess""InitialAccess"""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 |
|---|---|
Host_IPs | extend |
JamfPro | extend |
Tactics | extend |
Tags | extend |
Techniques | extend |
algorithm | extend |