Detection rules › Kusto

1Password - Secret extraction post vault access change by administrator

Severity
high
Time window
1h
Source
github.com/Azure/Azure-Sentinel

This will alert when a secret extraction has occurred after an administrator has changed their own vault access permissions within that same vault. Ref: https://1password.com/ Ref: https://github.com/securehats/

MITRE ATT&CK coverage

TacticTechniques
Credential Access

Telemetry coverage

Rule body

id: 6711b747-16d7-4df4-9f61-8633617f45d7
name: 1Password - Secret extraction post vault access change by administrator
version: 1.0.0
kind: Scheduled
description: |-
  This will alert when a secret extraction has occurred after an administrator has changed their own vault access permissions within that same vault.
  Ref: https://1password.com/
  Ref: https://github.com/securehats/
severity: High
requiredDataConnectors:
  - connectorId: 1Password
    dataTypes:
      - OnePasswordEventLogs_CL
queryFrequency: 5m
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
relevantTechniques:
- T1555
query: |-
  let lookback = 1h;
  let secretExtractionActivity =
      OnePasswordEventLogs_CL
      | where TimeGenerated between (ago(lookback) .. now())
      | where log_source == "itemusages"
      | where action has_any("server-fetch", "reveal", "secure-copy")
  ;
  OnePasswordEventLogs_CL
  | where log_source == "auditevents"
  | where (action == "grant" and object_type  == "uva") or (action == "update" and object_type  == "uva")
  | where tostring(actor_details.uuid) == tostring(aux_details.uuid)
  | extend
      userUuid = tostring(actor_details.uuid)
      , vaultUuid = tostring(object_uuid)
  | join (
      secretExtractionActivity
      | extend
          userUuid = tostring(user.uuid)
          , vaultUuid = tostring(vault_uuid)
      )
      on $left.userUuid == $right.userUuid and $left.vaultUuid == $right.vaultUuid
  | extend
      auditevents = bag_pack("action", action, "object_type", object_type)
      , itemusages = bag_pack("action", action1, "object_type", object_type1)
      , vault_details = bag_pack("vault_uuid", vault_uuid1, "item_uuid", item_uuid1)
  | project
      TimeGenerated
      , actor_details
      , target_details = aux_details
      , location_details = location
      , client_details = client1
      , auditevents
      , itemusages
      , vault_details
      , TargetUsername = tostring(user1.email)
      , SrcIpAddr = tostring(client1.ip_address)
suppressionEnabled: false
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: 1h
    matchingMethod: AllEntities
suppressionDuration: 1h
eventGroupingSettings:
  aggregationKind: SingleAlert
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: FullName
    columnName: TargetUsername
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: SrcIpAddr

Stages and Predicates

Parameters

let lookback = 1h;

Let binding: secretExtractionActivity used in Stage 6

let secretExtractionActivity = OnePasswordEventLogs_CL
    | where TimeGenerated between (ago(lookback) .. now())
    | where log_source == "itemusages"
    | where action has_any("server-fetch", "reveal", "secure-copy");

Stage 1: source

OnePasswordEventLogs_CL

Stage 2: where

| where log_source == "auditevents"

Stage 3: where

| where (action == "grant" and object_type  == "uva") or (action == "update" and object_type  == "uva")

Stage 4: where

| where tostring(actor_details.uuid) == tostring(aux_details.uuid)

Stage 5: extend

| extend
    userUuid = tostring(actor_details.uuid)
    , vaultUuid = tostring(object_uuid)

Stage 6: join

| join (
    secretExtractionActivity
    | extend
        userUuid = tostring(user.uuid)
        , vaultUuid = tostring(vault_uuid)
    )
    on $left.userUuid == $right.userUuid and $left.vaultUuid == $right.vaultUuid

Stage 7: extend

| extend
    auditevents = bag_pack("action", action, "object_type", object_type)
    , itemusages = bag_pack("action", action1, "object_type", object_type1)
    , vault_details = bag_pack("vault_uuid", vault_uuid1, "item_uuid", item_uuid1)

Stage 8: project

| project
    TimeGenerated
    , actor_details
    , target_details = aux_details
    , location_details = location
    , client_details = client1
    , auditevents
    , itemusages
    , vault_details
    , TargetUsername = tostring(user1.email)
    , SrcIpAddr = tostring(client1.ip_address)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
actioneq
  • grant
  • update
field:"action" kind:eq
actionmatch
  • reveal transforms: term
  • secure-copy transforms: term
  • server-fetch transforms: term
field:"action" kind:match
log_sourceeq
  • auditevents
  • itemusages
field:"log_source" kind:eq
object_typeeq
  • uva
field:"object_type" kind:eq value:"uva"

Output fields

These fields are emitted when the rule matches.

FieldSource
SrcIpAddrproject
TargetUsernameproject
TimeGeneratedproject
actor_detailsproject
auditeventsproject
client_detailsproject
itemusagesproject
location_detailsproject
target_detailsproject
vault_detailsproject