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])
entityMappings:
- entityType: Account
  fieldMappings:
  - columnName: AccountName
    identifier: Name
  - columnName: AccountUPNSuffix
    identifier: UPNSuffix
- entityType: IP
  fieldMappings:
  - columnName: client_ipAddress_s
    identifier: Address
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])
id: e36c6bd6-f86a-4282-93a5-b4a1b48dd849
queryFrequency: 1h
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.
status: Available
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Okta%20Single%20Sign-On/Analytic%20Rules/DeviceRegistrationMaliciousIP.yaml
version: 1.1.2
severity: High
relevantTechniques:
- T1098.005
name: Device Registration from Malicious IP
kind: Scheduled
tactics:
- Persistence
requiredDataConnectors:
- dataTypes:
  - Okta_CL
  connectorId: OktaSSO
- dataTypes:
  - OktaSSO
  connectorId: OktaSSOv2
description: |
  This rule identifies successful Okta device registration events that originate from IP addresses also observed by Okta ThreatInsight as malicious or suspicious.
customDetails:
  UserAgent: client_userAgent_rawUserAgent_s
  Location: Location
  ActorDeviceOS: NewDevice_osPlatform
  ActorDisplayName: actor_displayName_s
  ActorDeviceOSVersion: NewDevice_osVersion
triggerOperator: gt
triggerThreshold: 0
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"
    }
  ]
}