Detection rules › Kusto

1Password - Successful anomalous sign-in

Severity
low
Time window
14d
Source
github.com/Azure/Azure-Sentinel

This will alert when a new successful MFA confirmed sign-in has occurred from a location that was not seen within the last 14 days. Ref: https://1password.com/ Ref: https://github.com/securehats/

MITRE ATT&CK coverage

TacticTechniques
Initial Access

Telemetry coverage

PlatformRecord / event type
1Passwordcredentials_ok
1Passwordmfa_ok

Rule body

id: ceb20a5c-adce-4eba-9728-541361d47d87
name: 1Password - Successful anomalous sign-in
version: 1.0.0
kind: Scheduled
description: |-
  This will alert when a new successful MFA confirmed sign-in has occurred from a location that was not seen within the last 14 days.
  Ref: https://1password.com/
  Ref: https://github.com/securehats/
severity: Low
requiredDataConnectors:
  - connectorId: 1Password
    dataTypes:
      - OnePasswordEventLogs_CL
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
relevantTechniques:
- T1078
query: |-
  let rulefrequency = 1h;
  let lookback = 14d;
  let onePasswordSigninBaseline =
      OnePasswordEventLogs_CL
      | where TimeGenerated between (ago(lookback) .. now())
      | where log_source == "signinattempts"
      | where (category == "success" and action_type == "mfa_ok") or (category == "success" and action_type == "credentials_ok")
      | summarize count() by tostring(target_user.uuid), tostring(target_user.email), tostring(client.ip_address), tostring(location.country)
      | extend identifier = strcat(target_user_uuid, client_ip_address)
      | summarize make_list(identifier)
  ;
  OnePasswordEventLogs_CL
  | where TimeGenerated between (ago(rulefrequency) .. now())
  | where log_source == "signinattempts"
  | where (category == "success" and action_type == "mfa_ok") or (category == "success" and action_type == "credentials_ok")
  // limit the amount of incident triggers by enabling and adjusting the following in order to exclude country specific sign-ins
  // | where country !in~ ("CA", "US")
  | extend identifier = strcat(target_user.uuid, client.ip_address)
  | where identifier !in (onePasswordSigninBaseline)
  | extend
      TargetUsername = target_user.email
      , SrcIpAddr = client.ip_address
suppressionEnabled: false
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: false
    reopenClosedIncident: false
    lookbackDuration: 1h
    matchingMethod: AllEntities
suppressionDuration: 1h
eventGroupingSettings:
  aggregationKind: SingleAlert
alertDetailsOverride:
  alertDynamicProperties: []
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: FullName
    columnName: TargetUsername
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: SrcIpAddr

Stages and Predicates

Parameters

let rulefrequency = 1h;
let lookback = 14d;

Let binding: onePasswordSigninBaseline used in Stage 6

let onePasswordSigninBaseline = OnePasswordEventLogs_CL
    | where TimeGenerated between (ago(lookback) .. now())
    | where log_source == "signinattempts"
    | where (category == "success" and action_type == "mfa_ok") or (category == "success" and action_type == "credentials_ok")
    | summarize count() by tostring(target_user.uuid), tostring(target_user.email), tostring(client.ip_address), tostring(location.country)
    | extend identifier = strcat(target_user_uuid, client_ip_address)
    | summarize make_list(identifier);

Stage 1: source

OnePasswordEventLogs_CL

Stage 2: where

| where TimeGenerated between (ago(rulefrequency) .. now())

Stage 3: where

| where log_source == "signinattempts"

Stage 4: where

| where (category == "success" and action_type == "mfa_ok") or (category == "success" and action_type == "credentials_ok")

Stage 5: extend

| extend identifier = strcat(target_user.uuid, client.ip_address)

Stage 6: where

| where identifier !in (onePasswordSigninBaseline)

Stage 7: extend

| extend
    TargetUsername = target_user.email
    , SrcIpAddr = client.ip_address

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
identifiereqonePasswordSigninBaselineexcludes:identifier field:"identifier" value:"onePasswordSigninBaseline"

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
identifierextend
SrcIpAddrextend
TargetUsernameextend