Analytic rule catalog
Delinea - Privileged account access anomaly secret-access volume vs baseline
Back
| Id | e1bfca9b-7980-469f-a57c-16e81451861b |
| Rulename | Delinea - Privileged account access anomaly (secret-access volume vs baseline) |
| Description | Detects when a user’s secret-access volume for the current day significantly exceeds their own recent baseline (per-user daily average plus a standard-deviation factor over the prior ~14 days). A sudden spike relative to a principal’s normal behaviour can indicate a compromised privileged account or insider misuse. Tune ‘factor’ and ‘minDaily’ to balance noise against coverage. |
| Severity | Medium |
| Tactics | CredentialAccess |
| Techniques | T1555 T1212 |
| Required data connectors | DelineaPlatformConnector |
| Kind | Scheduled |
| Query frequency | 1d |
| Query period | 14d |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Delinea%20Platform/Analytic%20Rules/DelineaPrivilegedAccessAnomaly.yaml |
| Version | 1.1.1 |
| Arm template | e1bfca9b-7980-469f-a57c-16e81451861b.json |
let factor = 3.0;
let minDaily = 10;
let minBaselineDays = 3;
let secretViews = DelineaAuditEvents_CL
| where TimeGenerated > ago(14d)
| where Level == "PrivilegedActivity"
| extend d = parse_json(RawData)
| where tostring(d.eventType.name) == "Delinea.Vault.Secret.Viewed"
| extend Actor = tostring(d.actor.name), SrcIP = tostring(d.source.host.network.ipAddress)
| where isnotempty(Actor);
let baseline = secretViews
| where TimeGenerated < ago(1d)
| summarize Accesses = count() by Actor, Day = bin(TimeGenerated, 1d)
| summarize BaselineAvg = avg(Accesses), BaselineStdev = stdev(Accesses), BaselineMax = max(Accesses), DaysObserved = count() by Actor;
secretViews
| where TimeGenerated >= ago(1d)
| summarize TodayAccesses = count(), DistinctSecrets = dcount(SecretId), Secrets = make_set(SecretId, 50),
SourceIPs = make_set(SrcIP, 20), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by Actor
| join kind=inner baseline on Actor
| where DaysObserved >= minBaselineDays
| extend AnomalyThreshold = round(BaselineAvg + factor * BaselineStdev, 1)
| where TodayAccesses > AnomalyThreshold and TodayAccesses >= minDaily
| extend DeviationFactor = round(todouble(TodayAccesses) / (BaselineAvg + 1), 1)
| extend SrcIP = tostring(SourceIPs[0])
| project Actor, TodayAccesses, DistinctSecrets, BaselineAvg = round(BaselineAvg, 1), BaselineStdev = round(BaselineStdev, 1),
BaselineMax, AnomalyThreshold, DeviationFactor, DaysObserved, Secrets, SrcIP, StartTime, EndTime
| sort by DeviationFactor desc
incidentConfiguration:
groupingConfiguration:
lookbackDuration: P1D
reopenClosedIncident: false
groupByEntities:
- Account
matchingMethod: Selected
enabled: true
createIncident: true
triggerOperator: gt
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Delinea%20Platform/Analytic%20Rules/DelineaPrivilegedAccessAnomaly.yaml
triggerThreshold: 0
id: e1bfca9b-7980-469f-a57c-16e81451861b
kind: Scheduled
relevantTechniques:
- T1555
- T1212
version: 1.1.1
tactics:
- CredentialAccess
queryPeriod: 14d
queryFrequency: 1d
severity: Medium
name: Delinea - Privileged account access anomaly (secret-access volume vs baseline)
customDetails:
DeviationFactor: DeviationFactor
BaselineAvg: BaselineAvg
AnomalyThreshold: AnomalyThreshold
TodayAccesses: TodayAccesses
DistinctSecrets: DistinctSecrets
requiredDataConnectors:
- connectorId: DelineaPlatformConnector
dataTypes:
- DelineaAuditEvents_CL
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: Actor
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SrcIP
description: |
Detects when a user's secret-access volume for the current day significantly exceeds their own
recent baseline (per-user daily average plus a standard-deviation factor over the prior ~14 days).
A sudden spike relative to a principal's normal behaviour can indicate a compromised privileged
account or insider misuse. Tune 'factor' and 'minDaily' to balance noise against coverage.
eventGroupingSettings:
aggregationKind: AlertPerResult
status: Available
query: |
let factor = 3.0;
let minDaily = 10;
let minBaselineDays = 3;
let secretViews = DelineaAuditEvents_CL
| where TimeGenerated > ago(14d)
| where Level == "PrivilegedActivity"
| extend d = parse_json(RawData)
| where tostring(d.eventType.name) == "Delinea.Vault.Secret.Viewed"
| extend Actor = tostring(d.actor.name), SrcIP = tostring(d.source.host.network.ipAddress)
| where isnotempty(Actor);
let baseline = secretViews
| where TimeGenerated < ago(1d)
| summarize Accesses = count() by Actor, Day = bin(TimeGenerated, 1d)
| summarize BaselineAvg = avg(Accesses), BaselineStdev = stdev(Accesses), BaselineMax = max(Accesses), DaysObserved = count() by Actor;
secretViews
| where TimeGenerated >= ago(1d)
| summarize TodayAccesses = count(), DistinctSecrets = dcount(SecretId), Secrets = make_set(SecretId, 50),
SourceIPs = make_set(SrcIP, 20), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by Actor
| join kind=inner baseline on Actor
| where DaysObserved >= minBaselineDays
| extend AnomalyThreshold = round(BaselineAvg + factor * BaselineStdev, 1)
| where TodayAccesses > AnomalyThreshold and TodayAccesses >= minDaily
| extend DeviationFactor = round(todouble(TodayAccesses) / (BaselineAvg + 1), 1)
| extend SrcIP = tostring(SourceIPs[0])
| project Actor, TodayAccesses, DistinctSecrets, BaselineAvg = round(BaselineAvg, 1), BaselineStdev = round(BaselineStdev, 1),
BaselineMax, AnomalyThreshold, DeviationFactor, DaysObserved, Secrets, SrcIP, StartTime, EndTime
| sort by DeviationFactor desc
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/e1bfca9b-7980-469f-a57c-16e81451861b')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/e1bfca9b-7980-469f-a57c-16e81451861b')]",
"properties": {
"alertRuleTemplateName": "e1bfca9b-7980-469f-a57c-16e81451861b",
"customDetails": {
"AnomalyThreshold": "AnomalyThreshold",
"BaselineAvg": "BaselineAvg",
"DeviationFactor": "DeviationFactor",
"DistinctSecrets": "DistinctSecrets",
"TodayAccesses": "TodayAccesses"
},
"description": "Detects when a user's secret-access volume for the current day significantly exceeds their own\nrecent baseline (per-user daily average plus a standard-deviation factor over the prior ~14 days).\nA sudden spike relative to a principal's normal behaviour can indicate a compromised privileged\naccount or insider misuse. Tune 'factor' and 'minDaily' to balance noise against coverage.\n",
"displayName": "Delinea - Privileged account access anomaly (secret-access volume vs baseline)",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "Actor",
"identifier": "Name"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "SrcIP",
"identifier": "Address"
}
]
}
],
"eventGroupingSettings": {
"aggregationKind": "AlertPerResult"
},
"incidentConfiguration": {
"createIncident": true,
"groupingConfiguration": {
"enabled": true,
"groupByEntities": [
"Account"
],
"lookbackDuration": "P1D",
"matchingMethod": "Selected",
"reopenClosedIncident": false
}
},
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Delinea%20Platform/Analytic%20Rules/DelineaPrivilegedAccessAnomaly.yaml",
"query": "let factor = 3.0;\nlet minDaily = 10;\nlet minBaselineDays = 3;\nlet secretViews = DelineaAuditEvents_CL\n | where TimeGenerated > ago(14d)\n | where Level == \"PrivilegedActivity\"\n | extend d = parse_json(RawData)\n | where tostring(d.eventType.name) == \"Delinea.Vault.Secret.Viewed\"\n | extend Actor = tostring(d.actor.name), SrcIP = tostring(d.source.host.network.ipAddress)\n | where isnotempty(Actor);\nlet baseline = secretViews\n | where TimeGenerated < ago(1d)\n | summarize Accesses = count() by Actor, Day = bin(TimeGenerated, 1d)\n | summarize BaselineAvg = avg(Accesses), BaselineStdev = stdev(Accesses), BaselineMax = max(Accesses), DaysObserved = count() by Actor;\nsecretViews\n| where TimeGenerated >= ago(1d)\n| summarize TodayAccesses = count(), DistinctSecrets = dcount(SecretId), Secrets = make_set(SecretId, 50),\n SourceIPs = make_set(SrcIP, 20), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by Actor\n| join kind=inner baseline on Actor\n| where DaysObserved >= minBaselineDays\n| extend AnomalyThreshold = round(BaselineAvg + factor * BaselineStdev, 1)\n| where TodayAccesses > AnomalyThreshold and TodayAccesses >= minDaily\n| extend DeviationFactor = round(todouble(TodayAccesses) / (BaselineAvg + 1), 1)\n| extend SrcIP = tostring(SourceIPs[0])\n| project Actor, TodayAccesses, DistinctSecrets, BaselineAvg = round(BaselineAvg, 1), BaselineStdev = round(BaselineStdev, 1),\n BaselineMax, AnomalyThreshold, DeviationFactor, DaysObserved, Secrets, SrcIP, StartTime, EndTime\n| sort by DeviationFactor desc\n",
"queryFrequency": "P1D",
"queryPeriod": "P14D",
"severity": "Medium",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"CredentialAccess"
],
"techniques": [
"T1212",
"T1555"
],
"templateVersion": "1.1.1",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}