Detection rules › Kusto

Sentinel One - Admin login from new location

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

'Detects admin user login from new location (IP address).'

MITRE ATT&CK coverage

TacticTechniques
Initial AccessT1078 Valid Accounts
Privilege EscalationT1078 Valid Accounts

Rule body kusto

id: 382f37b3-b49a-492f-b436-a4717c8c5c3e
name: Sentinel One - Admin login from new location
description: |
  'Detects admin user login from new location (IP address).'
severity: High
status: Available
requiredDataConnectors:
  - connectorId: SentinelOne
    dataTypes:
      - SentinelOne
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - InitialAccess
  - PrivilegeEscalation
relevantTechniques:
  - T1078
query: | 
  let lback_period = 14d;
  let lback_time = 1h;
  SentinelOne
  | where TimeGenerated between(ago(lback_period)..ago(lback_time))
  | where ActivityType == 27
  | where DataRole =~ 'Admin'
  | extend SrcIpAddr = extract(@'Address\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', 1, EventOriginalMessage)
  | where isnotempty(SrcIpAddr)
  | summarize ip_lst = makeset(SrcIpAddr) by SrcUserName
  | join (SentinelOne
          | where ActivityType == 27
          | where DataRole =~ 'Admin'
          | extend SrcIpAddr = extract(@'Address\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', 1, EventOriginalMessage)
          | where isnotempty(SrcIpAddr)) on SrcUserName
  | where ip_lst !has SrcIpAddr
  | extend AccountCustomEntity = SrcUserName, IPCustomEntity = SrcIpAddr
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: AccountCustomEntity
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: IPCustomEntity
version: 1.0.1
kind: Scheduled

Stages and Predicates

Parameters

let lback_period = 14d;
let lback_time = 1h;

Stage 1: source

SentinelOne

Stage 2: where

| where TimeGenerated between(ago(lback_period)..ago(lback_time))

Stage 3: where

| where ActivityType == 27

Stage 4: where

| where DataRole =~ 'Admin'

Stage 5: extend

| extend SrcIpAddr = extract(@'Address\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', 1, EventOriginalMessage)

Stage 6: where

| where isnotempty(SrcIpAddr)

Stage 7: summarize

| summarize ip_lst = makeset(SrcIpAddr) by SrcUserName

Stage 8: join

| join (SentinelOne
        | where ActivityType == 27
        | where DataRole =~ 'Admin'
        | extend SrcIpAddr = extract(@'Address\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', 1, EventOriginalMessage)
        | where isnotempty(SrcIpAddr)) on SrcUserName

Stage 9: where

| where ip_lst !has SrcIpAddr

Stage 10: extend

| extend AccountCustomEntity = SrcUserName, IPCustomEntity = SrcIpAddr

Exclusions

Top-level NOT(...) conjuncts: predicates this rule actively suppresses.

FieldKindExcluded values
ip_lstmatchSrcIpAddr

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
ActivityTypeeq
  • 27 transforms: cased
DataRoleeq
  • Admin
SrcIpAddris_not_null
  • (no value, null check)

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
SrcUserNamesummarize
ip_lstsummarize
AccountCustomEntityextend
IPCustomEntityextend