Detection rules › Kusto

Dataverse - Login by a sensitive privileged user

Status
available
Severity
high
Time window
14d
Group by
UserId, UserPrincipalName
Source
github.com/Azure/Azure-Sentinel

Identifies Dataverse and Dynamics 365 logons by sensitive users.

MITRE ATT&CK coverage

Telemetry coverage

Rule body

id: f327816b-9328-4b17-9290-a02adc2f4928
kind: Scheduled
name: Dataverse - Login by a sensitive privileged user
description: Identifies Dataverse and Dynamics 365 logons by sensitive users.
severity: High
status: Available
requiredDataConnectors:
  - connectorId: Dataverse
    dataTypes:
      - DataverseActivity
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - InitialAccess
  - CredentialAccess
  - PrivilegeEscalation
relevantTechniques:
  - T1133
  - T1190
  - T1078
  - T1212
query: |
  # Sensitive users are marked in the VIP Users watchlist using the Tags field.
  # Enter the tags values to monitor
  let monitored_tags = dynamic(["DataverseSensitive"]);
  let query_frequency = 1h;
  let sensitive_users = MSBizAppsVIPUsers()
      | where Tags in (monitored_tags);
  sensitive_users
  | join kind=inner (DataverseActivity
      | where TimeGenerated >= ago(query_frequency)
      | where Message == "UserSignIn")
      on $left.UserPrincipalName == $right.UserId
  | summarize FirstSeen = arg_max(TimeGenerated, *) by UserId
  | extend
      CloudAppId = int(32780),
      AccountName = tostring(split(UserId, '@')[0]),
      UPNSuffix = tostring(split(UserId, '@')[1])
  | project
      FirstSeen,
      UserId,
      ClientIp,
      UserAgent,
      InstanceUrl,
      CloudAppId,
      AccountName,
      UPNSuffix
eventGroupingSettings:
  aggregationKind: SingleAlert
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: AccountName
      - identifier: UPNSuffix
        columnName: UPNSuffix
  - entityType: CloudApplication
    fieldMappings:
      - identifier: AppId
        columnName: CloudAppId
      - identifier: InstanceName
        columnName: InstanceUrl
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: ClientIp
alertDetailsOverride:
  alertDisplayNameFormat: 'Dataverse - Sensitive user logged in in at {{InstanceUrl}} '
  alertDescriptionFormat: A user marked as sensitive for Dataverse in the VIPUsers
    watchlist signed in at {{InstanceUrl}}.
version: 3.2.0

Stages and Predicates

Parameters

let monitored_tags = dynamic(["DataverseSensitive"]);
let query_frequency = 1h;

let sensitive_users is inlined into the numbered stages below.

Stages 1 to 2 define let sensitive_users (the rule's main pipeline source); stages 3 to 6 run on it.

Stage 1: source

MSBizAppsVIPUsers()

Stage 2: where

| where Tags in (monitored_tags)

Stage 3: join

sensitive_users
| join kind=inner (DataverseActivity
    | where TimeGenerated >= ago(query_frequency)
    | where Message == "UserSignIn")
    on $left.UserPrincipalName == $right.UserId

Stage 4: summarize

| summarize FirstSeen = arg_max(TimeGenerated, *) by UserId

Stage 5: extend

| extend
    CloudAppId = int(32780),
    AccountName = tostring(split(UserId, '@')[0]),
    UPNSuffix = tostring(split(UserId, '@')[1])

Stage 6: project

| project
    FirstSeen,
    UserId,
    ClientIp,
    UserAgent,
    InstanceUrl,
    CloudAppId,
    AccountName,
    UPNSuffix

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
AccountNameproject
ClientIpproject
CloudAppIdproject
FirstSeenproject
InstanceUrlproject
UPNSuffixproject
UserAgentproject
UserIdproject