Back
Ide36c6bd6-f86a-4282-93a5-b4a1b48dd849
RulenameDevice Registration from Malicious IP
DescriptionThis rule identifies successful Okta device registration events that originate from IP addresses also observed by Okta ThreatInsight as malicious or suspicious.
SeverityHigh
TacticsPersistence
TechniquesT1098.005
Required data connectorsOktaSSO
OktaSSOv2
KindScheduled
Query frequency1h
Query period1h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Okta%20Single%20Sign-On/Analytic%20Rules/DeviceRegistrationMaliciousIP.yaml
Version1.1.2
Arm templatee36c6bd6-f86a-4282-93a5-b4a1b48dd849.json
Deploy To Azure
let Events = dynamic(["device.enrollment.create"]);
let ThreatInsightOperations = dynamic(["security.threat.detected", "security.attack.start", "security.attack.end" ]);
// Adjust list of allowed IPs to reduce false positives
let AllowedIPs = dynamic([]);
let DeviceRegistrations =  OktaSSO
| where eventType_s in (Events)
| where outcome_result_s == "SUCCESS"
| where isnotempty(client_ipAddress_s) and client_ipAddress_s !in (AllowedIPs)
| extend oktaDeviceId_ = tostring(parse_json(tostring(parse_json(target_s)[0].detailEntry)).oktaDeviceId), NewDevice_osPlatform = tostring(parse_json(tostring(parse_json(target_s)[0].detailEntry)).osPlatform),  NewDevice_osVersion = tostring(parse_json(tostring(parse_json(target_s)[0].detailEntry)).osVersion), displayName_ = tostring(parse_json(target_s)[0].displayName)
| extend Location = strcat(client_geographicalContext_city_s,  " | ", client_geographicalContext_state_s," | ", client_geographicalContext_country_s)
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by actor_alternateId_s, actor_displayName_s, client_userAgent_os_s, client_ipAddress_s, displayMessage_s, outcome_result_s,
outcome_reason_s, column_ifexists('debugContext_debugData_logOnlySecurityData_s', ""), column_ifexists('debugContext_debugData_threatSuspected_s',""), client_userAgent_rawUserAgent_s,client_userAgent_browser_s, severity_s, NewDevice_osPlatform, NewDevice_osVersion, eventType_s, Location ;
let ThreatInsightEvents = OktaSSO
| where eventType_s in (ThreatInsightOperations)
| extend SuspiciousIP = actor_displayName_s
| project TimeGenerated, column_ifexists('debugContext_debugData_threatDetections_s', ""), client_userAgent_rawUserAgent_s, severity_s, outcome_result_s, eventType_s, displayMessage_s, SuspiciousIP, transaction_id_s;
DeviceRegistrations 
| join kind=inner (ThreatInsightEvents) on $left.client_ipAddress_s == $right.SuspiciousIP
| project TimeGenerated, actor_alternateId_s, actor_displayName_s, client_ipAddress_s, client_userAgent_os_s, client_userAgent_rawUserAgent_s, client_userAgent_browser_s, displayMessage_s, outcome_result_s, outcome_reason_s, severity_s, NewDevice_osPlatform, NewDevice_osVersion, eventType_s, Location, SuspiciousIP, transaction_id_s
| extend AccountName = tostring(split(actor_alternateId_s, "@")[0]), AccountUPNSuffix = tostring(split(actor_alternateId_s, "@")[1])
triggerThreshold: 0
version: 1.1.2
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: AccountUPNSuffix
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: client_ipAddress_s
query: |
  let Events = dynamic(["device.enrollment.create"]);
  let ThreatInsightOperations = dynamic(["security.threat.detected", "security.attack.start", "security.attack.end" ]);
  // Adjust list of allowed IPs to reduce false positives
  let AllowedIPs = dynamic([]);
  let DeviceRegistrations =  OktaSSO
  | where eventType_s in (Events)
  | where outcome_result_s == "SUCCESS"
  | where isnotempty(client_ipAddress_s) and client_ipAddress_s !in (AllowedIPs)
  | extend oktaDeviceId_ = tostring(parse_json(tostring(parse_json(target_s)[0].detailEntry)).oktaDeviceId), NewDevice_osPlatform = tostring(parse_json(tostring(parse_json(target_s)[0].detailEntry)).osPlatform),  NewDevice_osVersion = tostring(parse_json(tostring(parse_json(target_s)[0].detailEntry)).osVersion), displayName_ = tostring(parse_json(target_s)[0].displayName)
  | extend Location = strcat(client_geographicalContext_city_s,  " | ", client_geographicalContext_state_s," | ", client_geographicalContext_country_s)
  | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by actor_alternateId_s, actor_displayName_s, client_userAgent_os_s, client_ipAddress_s, displayMessage_s, outcome_result_s,
  outcome_reason_s, column_ifexists('debugContext_debugData_logOnlySecurityData_s', ""), column_ifexists('debugContext_debugData_threatSuspected_s',""), client_userAgent_rawUserAgent_s,client_userAgent_browser_s, severity_s, NewDevice_osPlatform, NewDevice_osVersion, eventType_s, Location ;
  let ThreatInsightEvents = OktaSSO
  | where eventType_s in (ThreatInsightOperations)
  | extend SuspiciousIP = actor_displayName_s
  | project TimeGenerated, column_ifexists('debugContext_debugData_threatDetections_s', ""), client_userAgent_rawUserAgent_s, severity_s, outcome_result_s, eventType_s, displayMessage_s, SuspiciousIP, transaction_id_s;
  DeviceRegistrations 
  | join kind=inner (ThreatInsightEvents) on $left.client_ipAddress_s == $right.SuspiciousIP
  | project TimeGenerated, actor_alternateId_s, actor_displayName_s, client_ipAddress_s, client_userAgent_os_s, client_userAgent_rawUserAgent_s, client_userAgent_browser_s, displayMessage_s, outcome_result_s, outcome_reason_s, severity_s, NewDevice_osPlatform, NewDevice_osVersion, eventType_s, Location, SuspiciousIP, transaction_id_s
  | extend AccountName = tostring(split(actor_alternateId_s, "@")[0]), AccountUPNSuffix = tostring(split(actor_alternateId_s, "@")[1])
alertDetailsOverride:
  alertDisplayNameFormat: Device registration from Malicious IP {{client_ipAddress_s}}
  alertDescriptionFormat: User {{actor_displayName_s}} ({{actor_alternateId_s}}) registered a device from {{client_ipAddress_s}} and the IP is associated with malicious activity in Okta ThreatInsight.
name: Device Registration from Malicious IP
kind: Scheduled
tactics:
- Persistence
id: e36c6bd6-f86a-4282-93a5-b4a1b48dd849
queryFrequency: 1h
customDetails:
  ActorDisplayName: actor_displayName_s
  ActorDeviceOSVersion: NewDevice_osVersion
  UserAgent: client_userAgent_rawUserAgent_s
  Location: Location
  ActorDeviceOS: NewDevice_osPlatform
description: |
  This rule identifies successful Okta device registration events that originate from IP addresses also observed by Okta ThreatInsight as malicious or suspicious.
requiredDataConnectors:
- connectorId: OktaSSO
  dataTypes:
  - Okta_CL
- connectorId: OktaSSOv2
  dataTypes:
  - OktaSSO
triggerOperator: gt
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Okta%20Single%20Sign-On/Analytic%20Rules/DeviceRegistrationMaliciousIP.yaml
relevantTechniques:
- T1098.005
status: Available
severity: High
queryPeriod: 1h
{
  "$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/e36c6bd6-f86a-4282-93a5-b4a1b48dd849')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/e36c6bd6-f86a-4282-93a5-b4a1b48dd849')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "User {{actor_displayName_s}} ({{actor_alternateId_s}}) registered a device from {{client_ipAddress_s}} and the IP is associated with malicious activity in Okta ThreatInsight.",
          "alertDisplayNameFormat": "Device registration from Malicious IP {{client_ipAddress_s}}"
        },
        "alertRuleTemplateName": "e36c6bd6-f86a-4282-93a5-b4a1b48dd849",
        "customDetails": {
          "ActorDeviceOS": "NewDevice_osPlatform",
          "ActorDeviceOSVersion": "NewDevice_osVersion",
          "ActorDisplayName": "actor_displayName_s",
          "Location": "Location",
          "UserAgent": "client_userAgent_rawUserAgent_s"
        },
        "description": "This rule identifies successful Okta device registration events that originate from IP addresses also observed by Okta ThreatInsight as malicious or suspicious.\n",
        "displayName": "Device Registration from Malicious IP",
        "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/DeviceRegistrationMaliciousIP.yaml",
        "query": "let Events = dynamic([\"device.enrollment.create\"]);\nlet ThreatInsightOperations = dynamic([\"security.threat.detected\", \"security.attack.start\", \"security.attack.end\" ]);\n// Adjust list of allowed IPs to reduce false positives\nlet AllowedIPs = dynamic([]);\nlet DeviceRegistrations =  OktaSSO\n| where eventType_s in (Events)\n| where outcome_result_s == \"SUCCESS\"\n| where isnotempty(client_ipAddress_s) and client_ipAddress_s !in (AllowedIPs)\n| extend oktaDeviceId_ = tostring(parse_json(tostring(parse_json(target_s)[0].detailEntry)).oktaDeviceId), NewDevice_osPlatform = tostring(parse_json(tostring(parse_json(target_s)[0].detailEntry)).osPlatform),  NewDevice_osVersion = tostring(parse_json(tostring(parse_json(target_s)[0].detailEntry)).osVersion), displayName_ = tostring(parse_json(target_s)[0].displayName)\n| extend Location = strcat(client_geographicalContext_city_s,  \" | \", client_geographicalContext_state_s,\" | \", client_geographicalContext_country_s)\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by actor_alternateId_s, actor_displayName_s, client_userAgent_os_s, client_ipAddress_s, displayMessage_s, outcome_result_s,\noutcome_reason_s, column_ifexists('debugContext_debugData_logOnlySecurityData_s', \"\"), column_ifexists('debugContext_debugData_threatSuspected_s',\"\"), client_userAgent_rawUserAgent_s,client_userAgent_browser_s, severity_s, NewDevice_osPlatform, NewDevice_osVersion, eventType_s, Location ;\nlet ThreatInsightEvents = OktaSSO\n| where eventType_s in (ThreatInsightOperations)\n| extend SuspiciousIP = actor_displayName_s\n| project TimeGenerated, column_ifexists('debugContext_debugData_threatDetections_s', \"\"), client_userAgent_rawUserAgent_s, severity_s, outcome_result_s, eventType_s, displayMessage_s, SuspiciousIP, transaction_id_s;\nDeviceRegistrations \n| join kind=inner (ThreatInsightEvents) on $left.client_ipAddress_s == $right.SuspiciousIP\n| project TimeGenerated, actor_alternateId_s, actor_displayName_s, client_ipAddress_s, client_userAgent_os_s, client_userAgent_rawUserAgent_s, client_userAgent_browser_s, displayMessage_s, outcome_result_s, outcome_reason_s, severity_s, NewDevice_osPlatform, NewDevice_osVersion, eventType_s, Location, SuspiciousIP, transaction_id_s\n| extend AccountName = tostring(split(actor_alternateId_s, \"@\")[0]), AccountUPNSuffix = tostring(split(actor_alternateId_s, \"@\")[1])\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "PT1H",
        "severity": "High",
        "status": "Available",
        "subTechniques": [
          "T1098.005"
        ],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Persistence"
        ],
        "techniques": [
          "T1098"
        ],
        "templateVersion": "1.1.2",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}