Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

StealthTalk - Login outside work zone

Back
Ida7c3e9b1-4f5d-4e2a-9b8c-1d2e3f4a5b6c
RulenameStealthTalk - Login outside work zone
DescriptionIdentifies a single StealthTalk authentication originating from a country or city that does

not match the user’s assigned (expected) geographic zone. Each individual mismatch is

treated as an incident - there is no aggregation threshold, since a single login from an

unexpected country is high-confidence evidence of a credential issue.



An incident fires when LoginCountry differs from AssignedCountry OR LoginCity differs

from AssignedCity. Source IPv4, raw event ID, and both the observed and expected

geo-locations are surfaced as entities and custom details for the SOC analyst.
SeverityHigh
TacticsInitialAccess
DefenseEvasion
CredentialAccess
TechniquesT1078
Required data connectorsStealthTalkAnomalousAuth
KindScheduled
Query frequency15m
Query period1h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/StealthTalk/Analytic Rules/LoginOutsideWorkZone.yaml
Version1.0.0
Arm templatea7c3e9b1-4f5d-4e2a-9b8c-1d2e3f4a5b6c.json
Deploy To Azure
let LookbackPeriod = 1h;
StealthTalkAnomalousAuth_CL
| where TimeGenerated >= ago(LookbackPeriod)
| where EventType == "GeoAnomalyLogin"
| where LoginCountry != AssignedCountry
     or LoginCity    != AssignedCity
| extend
    CountryMismatch = LoginCountry != AssignedCountry,
    CityMismatch    = LoginCity    != AssignedCity,
    AlertName       = "LoginOutsideWorkZone",
    AlertDetails    = strcat(
        "User ", UserId,
        " logged in from ", LoginCity, " (", LoginCountry, ")",
        " - assigned zone: ", AssignedCity, " (", AssignedCountry, ").",
        " Source IP: ", IpAddress, ".",
        " Country mismatch: ", tostring(LoginCountry != AssignedCountry), ".",
        " City mismatch: ", tostring(LoginCity != AssignedCity), "."
    )
| project
    TimeGenerated, UserId, DeviceId,
    LoginCountry, LoginCity, AssignedCountry, AssignedCity,
    CountryMismatch, CityMismatch, IpAddress,
    AppVersion, RawEventId, AlertName, AlertDetails
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: Name
    columnName: UserId
- entityType: Host
  fieldMappings:
  - identifier: HostName
    columnName: DeviceId
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: IpAddress
tactics:
- InitialAccess
- DefenseEvasion
- CredentialAccess
suppressionEnabled: false
suppressionDuration: 1h
requiredDataConnectors:
- dataTypes:
  - StealthTalkAnomalousAuth_CL
  connectorId: StealthTalkAnomalousAuth
alertDetailsOverride:
  alertDisplayNameFormat: 'StealthTalk: Login Outside Work Zone - {{UserId}} from {{LoginCity}} ({{LoginCountry}})'
  alertDescriptionFormat: '{{AlertDetails}}'
incidentConfiguration:
  groupingConfiguration:
    reopenClosedIncident: false
    lookbackDuration: 5h
    groupByEntities:
    - Account
    enabled: true
    matchingMethod: Selected
  createIncident: true
id: a7c3e9b1-4f5d-4e2a-9b8c-1d2e3f4a5b6c
severity: High
status: Available
customDetails:
  AssignedCity: AssignedCity
  AppVersion: AppVersion
  LoginCountry: LoginCountry
  AssignedCountry: AssignedCountry
  EventReference: RawEventId
  CountryMismatch: CountryMismatch
  LoginCity: LoginCity
  CityMismatch: CityMismatch
query: |
  let LookbackPeriod = 1h;
  StealthTalkAnomalousAuth_CL
  | where TimeGenerated >= ago(LookbackPeriod)
  | where EventType == "GeoAnomalyLogin"
  | where LoginCountry != AssignedCountry
       or LoginCity    != AssignedCity
  | extend
      CountryMismatch = LoginCountry != AssignedCountry,
      CityMismatch    = LoginCity    != AssignedCity,
      AlertName       = "LoginOutsideWorkZone",
      AlertDetails    = strcat(
          "User ", UserId,
          " logged in from ", LoginCity, " (", LoginCountry, ")",
          " - assigned zone: ", AssignedCity, " (", AssignedCountry, ").",
          " Source IP: ", IpAddress, ".",
          " Country mismatch: ", tostring(LoginCountry != AssignedCountry), ".",
          " City mismatch: ", tostring(LoginCity != AssignedCity), "."
      )
  | project
      TimeGenerated, UserId, DeviceId,
      LoginCountry, LoginCity, AssignedCountry, AssignedCity,
      CountryMismatch, CityMismatch, IpAddress,
      AppVersion, RawEventId, AlertName, AlertDetails  
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/StealthTalk/Analytic Rules/LoginOutsideWorkZone.yaml
kind: Scheduled
queryPeriod: 1h
version: 1.0.0
name: StealthTalk - Login outside work zone
queryFrequency: 15m
triggerThreshold: 0
relevantTechniques:
- T1078
description: |
  Identifies a single StealthTalk authentication originating from a country or city that does
  not match the user's assigned (expected) geographic zone. Each individual mismatch is
  treated as an incident - there is no aggregation threshold, since a single login from an
  unexpected country is high-confidence evidence of a credential issue.

  An incident fires when LoginCountry differs from AssignedCountry OR LoginCity differs
  from AssignedCity. Source IPv4, raw event ID, and both the observed and expected
  geo-locations are surfaced as entities and custom details for the SOC analyst.  
triggerOperator: gt