Analytic rule catalog
New DeviceLocation sign-in along with critical operation
Back
| Id | 41e843a8-92e7-444d-8d72-638f1145d1e1 |
| Rulename | New Device/Location sign-in along with critical operation |
| Description | This query identifies users seen login from a new geo location/country and a new device, then correlates that sign-in with successful risky operations such as policy changes, MFA changes, API token actions etc. This can be an indication of an attacker gaining access to a user’s credentials and then performing critical operations, which typically requires admin privileges. By detecting such patterns, organizations can quickly respond to potential security incidents and mitigate risks associated with unauthorized access and privilege escalation. |
| Severity | Medium |
| Tactics | InitialAccess Persistence PrivilegeEscalation |
| Techniques | T1078 T1556 T1098 |
| Required data connectors | OktaSSO OktaSSOv2 |
| Kind | Scheduled |
| Query frequency | 1h |
| Query period | 1h |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Okta%20Single%20Sign-On/Analytic%20Rules/NewDeviceLocationCriticalOperation.yaml |
| Version | 1.1.3 |
| Arm template | 41e843a8-92e7-444d-8d72-638f1145d1e1.json |
let timeframe = 1h;
let RiskyOperations = dynamic(["policy.rule.update","policy.rule.create","policy.rule.delete", "policy.rule.deactivate", "policy.lifecycle.update", "policy.rule.modify", "policy.lifecycle.create", "policy.lifecycle.delete", "policy.lifecycle.deactivate", "policy.lifecycle.modify", "network_zone.rule.disabled", "system.api_token.create", "system.api_token.revoke", "application.policy.sign_on.update", "application.policy.sign_on.rule.delete","user.mfa.factor.deactivate", "user.mfa.factor.reset_all", "system.mfa.factor.deactivate", "user.mfa.attempt_bypass"]);
let UserLoginNewCountryDevice = OktaSSO
| where eventType_s == "user.session.start"
| where outcome_result_s == "SUCCESS"
| extend debugContext_debugData_logOnlySecurityData_s = column_ifexists('debugContext_debugData_logOnlySecurityData_s', '{}')
| extend behaviors = parse_json(tostring(parse_json(debugContext_debugData_logOnlySecurityData_s).behaviors))
| where tostring(behaviors.["New Country"]) == "POSITIVE"
| where tostring(behaviors.["New Geo-Location"]) == "POSITIVE"
| where tostring(behaviors.["New Device"]) == "POSITIVE"
| summarize by timekey = bin(TimeGenerated, timeframe), actor_alternateId_s, actor_displayName_s, client_userAgent_os_s, client_userAgent_browser_s, client_device_s, client_userAgent_rawUserAgent_s, client_ipAddress_s, authenticationContext_externalSessionId_s, client_geographicalContext_country_s, client_geographicalContext_city_s, displayMessage_s, outcome_result_s, outcome_reason_s, column_ifexists('debugContext_debugData_logOnlySecurityData_s', ""), column_ifexists('debugContext_debugData_threatSuspected_s', ""), client_geographicalContext_geolocation_lat_d, client_geographicalContext_geolocation_lon_d
| extend Location = strcat(client_geographicalContext_city_s, "-", client_geographicalContext_country_s);
let RiskyOperationsObserved = OktaSSO
| where eventType_s in (RiskyOperations)
| where outcome_result_s == "SUCCESS"
| summarize by timekey = bin(TimeGenerated, timeframe), actor_alternateId_s, actor_displayName_s, client_userAgent_os_s, client_userAgent_browser_s, client_device_s, client_userAgent_rawUserAgent_s, client_ipAddress_s, authenticationContext_externalSessionId_s, client_geographicalContext_country_s, client_geographicalContext_city_s, displayMessage_s, outcome_result_s, outcome_reason_s, column_ifexists('debugContext_debugData_logOnlySecurityData_s', ""), column_ifexists('debugContext_debugData_threatSuspected_s', ""), client_geographicalContext_geolocation_lat_d, client_geographicalContext_geolocation_lon_d;
UserLoginNewCountryDevice
| join kind=inner (RiskyOperationsObserved) on timekey, actor_displayName_s, client_ipAddress_s
| project TimeGenerated = timekey, actor_alternateId_s, actor_displayName_s, client_userAgent_os_s, client_userAgent_browser_s, client_device_s, client_userAgent_rawUserAgent_s, client_ipAddress_s, authenticationContext_externalSessionId_s, client_geographicalContext_country_s, client_geographicalContext_city_s, displayMessage_s, outcome_result_s, outcome_reason_s, column_ifexists('debugContext_debugData_logOnlySecurityData_s', ""), column_ifexists('debugContext_debugData_threatSuspected_s', ""), client_geographicalContext_geolocation_lat_d, client_geographicalContext_geolocation_lon_d, Location
| extend AccountName = tostring(split(actor_alternateId_s, "@")[0]), AccountUPNSuffix = tostring(split(actor_alternateId_s, "@")[1])
name: New Device/Location sign-in along with critical operation
triggerOperator: gt
query: |
let timeframe = 1h;
let RiskyOperations = dynamic(["policy.rule.update","policy.rule.create","policy.rule.delete", "policy.rule.deactivate", "policy.lifecycle.update", "policy.rule.modify", "policy.lifecycle.create", "policy.lifecycle.delete", "policy.lifecycle.deactivate", "policy.lifecycle.modify", "network_zone.rule.disabled", "system.api_token.create", "system.api_token.revoke", "application.policy.sign_on.update", "application.policy.sign_on.rule.delete","user.mfa.factor.deactivate", "user.mfa.factor.reset_all", "system.mfa.factor.deactivate", "user.mfa.attempt_bypass"]);
let UserLoginNewCountryDevice = OktaSSO
| where eventType_s == "user.session.start"
| where outcome_result_s == "SUCCESS"
| extend debugContext_debugData_logOnlySecurityData_s = column_ifexists('debugContext_debugData_logOnlySecurityData_s', '{}')
| extend behaviors = parse_json(tostring(parse_json(debugContext_debugData_logOnlySecurityData_s).behaviors))
| where tostring(behaviors.["New Country"]) == "POSITIVE"
| where tostring(behaviors.["New Geo-Location"]) == "POSITIVE"
| where tostring(behaviors.["New Device"]) == "POSITIVE"
| summarize by timekey = bin(TimeGenerated, timeframe), actor_alternateId_s, actor_displayName_s, client_userAgent_os_s, client_userAgent_browser_s, client_device_s, client_userAgent_rawUserAgent_s, client_ipAddress_s, authenticationContext_externalSessionId_s, client_geographicalContext_country_s, client_geographicalContext_city_s, displayMessage_s, outcome_result_s, outcome_reason_s, column_ifexists('debugContext_debugData_logOnlySecurityData_s', ""), column_ifexists('debugContext_debugData_threatSuspected_s', ""), client_geographicalContext_geolocation_lat_d, client_geographicalContext_geolocation_lon_d
| extend Location = strcat(client_geographicalContext_city_s, "-", client_geographicalContext_country_s);
let RiskyOperationsObserved = OktaSSO
| where eventType_s in (RiskyOperations)
| where outcome_result_s == "SUCCESS"
| summarize by timekey = bin(TimeGenerated, timeframe), actor_alternateId_s, actor_displayName_s, client_userAgent_os_s, client_userAgent_browser_s, client_device_s, client_userAgent_rawUserAgent_s, client_ipAddress_s, authenticationContext_externalSessionId_s, client_geographicalContext_country_s, client_geographicalContext_city_s, displayMessage_s, outcome_result_s, outcome_reason_s, column_ifexists('debugContext_debugData_logOnlySecurityData_s', ""), column_ifexists('debugContext_debugData_threatSuspected_s', ""), client_geographicalContext_geolocation_lat_d, client_geographicalContext_geolocation_lon_d;
UserLoginNewCountryDevice
| join kind=inner (RiskyOperationsObserved) on timekey, actor_displayName_s, client_ipAddress_s
| project TimeGenerated = timekey, actor_alternateId_s, actor_displayName_s, client_userAgent_os_s, client_userAgent_browser_s, client_device_s, client_userAgent_rawUserAgent_s, client_ipAddress_s, authenticationContext_externalSessionId_s, client_geographicalContext_country_s, client_geographicalContext_city_s, displayMessage_s, outcome_result_s, outcome_reason_s, column_ifexists('debugContext_debugData_logOnlySecurityData_s', ""), column_ifexists('debugContext_debugData_threatSuspected_s', ""), client_geographicalContext_geolocation_lat_d, client_geographicalContext_geolocation_lon_d, Location
| extend AccountName = tostring(split(actor_alternateId_s, "@")[0]), AccountUPNSuffix = tostring(split(actor_alternateId_s, "@")[1])
queryFrequency: 1h
description: |
This query identifies users seen login from a new geo location/country and a new device, then correlates that sign-in with successful risky operations such as policy changes, MFA changes, API token actions etc. This can be an indication of an attacker gaining access to a user's credentials and then performing critical operations, which typically requires admin privileges. By detecting such patterns, organizations can quickly respond to potential security incidents and mitigate risks associated with unauthorized access and privilege escalation.
id: 41e843a8-92e7-444d-8d72-638f1145d1e1
triggerThreshold: 0
queryPeriod: 1h
version: 1.1.3
kind: Scheduled
customDetails:
ActorOS: client_userAgent_os_s
ActorDisplayName: actor_displayName_s
Location: Location
ActorDevice: client_device_s
UserAgent: client_userAgent_rawUserAgent_s
ActorBrowser: client_userAgent_browser_s
SessionId: authenticationContext_externalSessionId_s
status: Available
severity: Medium
requiredDataConnectors:
- connectorId: OktaSSO
dataTypes:
- Okta_CL
- connectorId: OktaSSOv2
dataTypes:
- OktaSSO
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Okta%20Single%20Sign-On/Analytic%20Rules/NewDeviceLocationCriticalOperation.yaml
alertDetailsOverride:
alertDescriptionFormat: |
This query identifies users seen login from new geo location/country {{Location}} as well as a new device and performing critical operations.
alertDisplayNameFormat: New Device/Location {{Location}} sign-in along with critical operation
relevantTechniques:
- T1078
- T1556
- T1098
tactics:
- InitialAccess
- Persistence
- PrivilegeEscalation
entityMappings:
- fieldMappings:
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
entityType: Account
- fieldMappings:
- identifier: Address
columnName: client_ipAddress_s
entityType: IP
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/41e843a8-92e7-444d-8d72-638f1145d1e1')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/41e843a8-92e7-444d-8d72-638f1145d1e1')]",
"properties": {
"alertDetailsOverride": {
"alertDescriptionFormat": "This query identifies users seen login from new geo location/country {{Location}} as well as a new device and performing critical operations.\n",
"alertDisplayNameFormat": "New Device/Location {{Location}} sign-in along with critical operation"
},
"alertRuleTemplateName": "41e843a8-92e7-444d-8d72-638f1145d1e1",
"customDetails": {
"ActorBrowser": "client_userAgent_browser_s",
"ActorDevice": "client_device_s",
"ActorDisplayName": "actor_displayName_s",
"ActorOS": "client_userAgent_os_s",
"Location": "Location",
"SessionId": "authenticationContext_externalSessionId_s",
"UserAgent": "client_userAgent_rawUserAgent_s"
},
"description": "This query identifies users seen login from a new geo location/country and a new device, then correlates that sign-in with successful risky operations such as policy changes, MFA changes, API token actions etc. This can be an indication of an attacker gaining access to a user's credentials and then performing critical operations, which typically requires admin privileges. By detecting such patterns, organizations can quickly respond to potential security incidents and mitigate risks associated with unauthorized access and privilege escalation.\n",
"displayName": "New Device/Location sign-in along with critical operation",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "AccountName",
"identifier": "Name"
},
{
"columnName": "AccountUPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "client_ipAddress_s",
"identifier": "Address"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Okta%20Single%20Sign-On/Analytic%20Rules/NewDeviceLocationCriticalOperation.yaml",
"query": "let timeframe = 1h;\nlet RiskyOperations = dynamic([\"policy.rule.update\",\"policy.rule.create\",\"policy.rule.delete\", \"policy.rule.deactivate\", \"policy.lifecycle.update\", \"policy.rule.modify\", \"policy.lifecycle.create\", \"policy.lifecycle.delete\", \"policy.lifecycle.deactivate\", \"policy.lifecycle.modify\", \"network_zone.rule.disabled\", \"system.api_token.create\", \"system.api_token.revoke\", \"application.policy.sign_on.update\", \"application.policy.sign_on.rule.delete\",\"user.mfa.factor.deactivate\", \"user.mfa.factor.reset_all\", \"system.mfa.factor.deactivate\", \"user.mfa.attempt_bypass\"]);\nlet UserLoginNewCountryDevice = OktaSSO\n| where eventType_s == \"user.session.start\"\n| where outcome_result_s == \"SUCCESS\"\n| extend debugContext_debugData_logOnlySecurityData_s = column_ifexists('debugContext_debugData_logOnlySecurityData_s', '{}')\n| extend behaviors = parse_json(tostring(parse_json(debugContext_debugData_logOnlySecurityData_s).behaviors))\n| where tostring(behaviors.[\"New Country\"]) == \"POSITIVE\"\n| where tostring(behaviors.[\"New Geo-Location\"]) == \"POSITIVE\"\n| where tostring(behaviors.[\"New Device\"]) == \"POSITIVE\"\n| summarize by timekey = bin(TimeGenerated, timeframe), actor_alternateId_s, actor_displayName_s, client_userAgent_os_s, client_userAgent_browser_s, client_device_s, client_userAgent_rawUserAgent_s, client_ipAddress_s, authenticationContext_externalSessionId_s, client_geographicalContext_country_s, client_geographicalContext_city_s, displayMessage_s, outcome_result_s, outcome_reason_s, column_ifexists('debugContext_debugData_logOnlySecurityData_s', \"\"), column_ifexists('debugContext_debugData_threatSuspected_s', \"\"), client_geographicalContext_geolocation_lat_d, client_geographicalContext_geolocation_lon_d\n| extend Location = strcat(client_geographicalContext_city_s, \"-\", client_geographicalContext_country_s);\nlet RiskyOperationsObserved = OktaSSO\n| where eventType_s in (RiskyOperations)\n| where outcome_result_s == \"SUCCESS\"\n| summarize by timekey = bin(TimeGenerated, timeframe), actor_alternateId_s, actor_displayName_s, client_userAgent_os_s, client_userAgent_browser_s, client_device_s, client_userAgent_rawUserAgent_s, client_ipAddress_s, authenticationContext_externalSessionId_s, client_geographicalContext_country_s, client_geographicalContext_city_s, displayMessage_s, outcome_result_s, outcome_reason_s, column_ifexists('debugContext_debugData_logOnlySecurityData_s', \"\"), column_ifexists('debugContext_debugData_threatSuspected_s', \"\"), client_geographicalContext_geolocation_lat_d, client_geographicalContext_geolocation_lon_d;\nUserLoginNewCountryDevice\n| join kind=inner (RiskyOperationsObserved) on timekey, actor_displayName_s, client_ipAddress_s\n| project TimeGenerated = timekey, actor_alternateId_s, actor_displayName_s, client_userAgent_os_s, client_userAgent_browser_s, client_device_s, client_userAgent_rawUserAgent_s, client_ipAddress_s, authenticationContext_externalSessionId_s, client_geographicalContext_country_s, client_geographicalContext_city_s, displayMessage_s, outcome_result_s, outcome_reason_s, column_ifexists('debugContext_debugData_logOnlySecurityData_s', \"\"), column_ifexists('debugContext_debugData_threatSuspected_s', \"\"), client_geographicalContext_geolocation_lat_d, client_geographicalContext_geolocation_lon_d, Location\n| extend AccountName = tostring(split(actor_alternateId_s, \"@\")[0]), AccountUPNSuffix = tostring(split(actor_alternateId_s, \"@\")[1])\n",
"queryFrequency": "PT1H",
"queryPeriod": "PT1H",
"severity": "Medium",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"InitialAccess",
"Persistence",
"PrivilegeEscalation"
],
"techniques": [
"T1078",
"T1098",
"T1556"
],
"templateVersion": "1.1.3",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}