Detection rules › Kusto

1Password - Privileged vault permission change

Severity
high
Time window
5m
Source
github.com/Azure/Azure-Sentinel

This will alert when permissions have changed within a privileged vault. Once this analytics rule is triggered it will group all related future alerts for upto an hour when all related entities are the same. Ref: https://1password.com/ Ref: https://github.com/securehats/

MITRE ATT&CK coverage

TacticTechniques
Persistence

Telemetry coverage

Rule body

id: 76e386eb-f51a-4600-97d1-f0db3b7e41f1
name: 1Password - Privileged vault permission change
version: 1.0.0
kind: Scheduled
description: |-
  This will alert when permissions have changed within a privileged vault. Once this analytics rule is triggered it will group all related future alerts for upto an hour when all related entities are the same.

  Ref: https://1password.com/
  Ref: https://github.com/securehats/
severity: High
requiredDataConnectors:
  - connectorId: 1Password
    dataTypes:
      - OnePasswordEventLogs_CL
queryFrequency: 5m
queryPeriod: 5m
triggerOperator: gt
triggerThreshold: 0
tactics:
- Persistence
relevantTechniques:
- T1098
query: |-
  let watchlist =
      _GetWatchlist("PV1PW")
      | project SearchKey
  ;
  // Insert the vault UUIDs below when using the dynamic vaults list within the analytics rule itself
  let vaults = dynamic([""]);
  OnePasswordEventLogs_CL
  | where log_source == "auditevents"
  | where
      (action has_any("grant", "revoke", "update") and object_type == "uva") or
      (action has_any("grant", "revoke", "update") and object_type == "gva")
  // Enable the line below when using the "Privileged Vaults - 1PW" watchlist
  | where object_uuid in (watchlist)
  // Enable the line below when using the dynamic vaults list within the analytics rule itself
  // | where object_uuid in (vaults)
  | extend
      TargetUsername = case(isnotempty(aux_details), aux_details.email, "")
      , TargetGroupUUID = case(isempty(aux_details), aux_uuid, "")
      , ActorUsername = actor_details.email
      , SrcIpAddr = session.ip
suppressionEnabled: false
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: 1h
    matchingMethod: AllEntities
suppressionDuration: 5h
eventGroupingSettings:
  aggregationKind: SingleAlert
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: FullName
    columnName: ActorUsername
- entityType: Account
  fieldMappings:
  - identifier: FullName
    columnName: TargetUsername
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: SrcIpAddr

Stages and Predicates

Parameters

let vaults = dynamic([""]);

Let binding: watchlist used in Stage 4

let watchlist = _GetWatchlist("PV1PW")
    | project SearchKey;

Stage 1: source

OnePasswordEventLogs_CL

Stage 2: where

| where log_source == "auditevents"

Stage 3: where

| where
    (action has_any("grant", "revoke", "update") and object_type == "uva") or
    (action has_any("grant", "revoke", "update") and object_type == "gva")

Stage 4: where

| where object_uuid in (watchlist)

Stage 5: extend

| extend
    TargetUsername = case(isnotempty(aux_details), aux_details.email, "")
    , TargetGroupUUID = case(isempty(aux_details), aux_uuid, "")
    , ActorUsername = actor_details.email
    , SrcIpAddr = session.ip
TargetGroupUUID =
ifisempty(aux_details)aux_uuid
else""
TargetUsername =
ifisnotempty(aux_details)aux_details.email
else""

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
actionmatch
  • grant transforms: term
  • revoke transforms: term
  • update transforms: term
field:"action" kind:match
log_sourceeq
  • auditevents
field:"log_source" kind:eq value:"auditevents"
object_typeeq
  • gva
  • uva
field:"object_type" kind:eq
object_uuidin
  • watchlist
field:"object_uuid" kind:in value:"watchlist"

Output fields

These fields are emitted when the rule matches.

FieldSource
ActorUsernameextend
SrcIpAddrextend
TargetGroupUUIDextend
TargetUsernameextend