Back
Id3094e036-e5ae-4d6e-8626-b0f86ebc71f2
RulenameUser Sign in from different countries
DescriptionThis query searches for successful user logins from different countries within 30 mins.
SeverityMedium
TacticsInitialAccess
TechniquesT1078
Required data connectorsSalesforceServiceCloudCCPDefinition
KindScheduled
Query frequency1h
Query period1h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Salesforce%20Service%20Cloud/Analytic%20Rules/Salesforce-SigninsMultipleCountries.yaml
Version1.0.4
Arm template3094e036-e5ae-4d6e-8626-b0f86ebc71f2.json
Deploy To Azure
let threshold = 2;
let Countrydb = externaldata(Network:string, geoname_id:string, continent_code:string, continent_name:string, country_iso_code:string, country_name:string)
[@"https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv"];
let UsersLocation = SalesforceServiceCloud
| where EventType =~ 'Login' and LoginStatus=~'LOGIN_NO_ERROR'
| project TimeGenerated, TimestampDerived, ClientIp, UserId, User, UserType ;
UsersLocation
| extend Dummy=1
| extend TimestampDerived = todatetime(TimestampDerived)
| summarize count() by Hour=bin(TimestampDerived,30m), ClientIp,User, Dummy
| partition by Hour(
                lookup (Countrydb|extend Dummy=1) on Dummy
              | where ipv4_is_match(ClientIp, Network)
              )
| summarize NumOfCountries = dcount(country_name) by User, Hour
| where NumOfCountries >= threshold
name: User Sign in from different countries
triggerOperator: gt
query: |
  let threshold = 2;
  let Countrydb = externaldata(Network:string, geoname_id:string, continent_code:string, continent_name:string, country_iso_code:string, country_name:string)
  [@"https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv"];
  let UsersLocation = SalesforceServiceCloud
  | where EventType =~ 'Login' and LoginStatus=~'LOGIN_NO_ERROR'
  | project TimeGenerated, TimestampDerived, ClientIp, UserId, User, UserType ;
  UsersLocation
  | extend Dummy=1
  | extend TimestampDerived = todatetime(TimestampDerived)
  | summarize count() by Hour=bin(TimestampDerived,30m), ClientIp,User, Dummy
  | partition by Hour(
                  lookup (Countrydb|extend Dummy=1) on Dummy
                | where ipv4_is_match(ClientIp, Network)
                )
  | summarize NumOfCountries = dcount(country_name) by User, Hour
  | where NumOfCountries >= threshold
queryFrequency: 1h
description: |
  'This query searches for successful user logins from different countries within 30 mins.'
id: 3094e036-e5ae-4d6e-8626-b0f86ebc71f2
triggerThreshold: 0
queryPeriod: 1h
version: 1.0.4
kind: Scheduled
status: Available
severity: Medium
requiredDataConnectors:
- connectorId: SalesforceServiceCloudCCPDefinition
  dataTypes:
  - SalesforceServiceCloud
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Salesforce%20Service%20Cloud/Analytic%20Rules/Salesforce-SigninsMultipleCountries.yaml
relevantTechniques:
- T1078
tactics:
- InitialAccess
entityMappings:
- fieldMappings:
  - identifier: AadUserId
    columnName: User
  entityType: Account
{
  "$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/3094e036-e5ae-4d6e-8626-b0f86ebc71f2')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/3094e036-e5ae-4d6e-8626-b0f86ebc71f2')]",
      "properties": {
        "alertRuleTemplateName": "3094e036-e5ae-4d6e-8626-b0f86ebc71f2",
        "customDetails": null,
        "description": "'This query searches for successful user logins from different countries within 30 mins.'\n",
        "displayName": "User Sign in from different countries",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "User",
                "identifier": "AadUserId"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Salesforce%20Service%20Cloud/Analytic%20Rules/Salesforce-SigninsMultipleCountries.yaml",
        "query": "let threshold = 2;\nlet Countrydb = externaldata(Network:string, geoname_id:string, continent_code:string, continent_name:string, country_iso_code:string, country_name:string)\n[@\"https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv\"];\nlet UsersLocation = SalesforceServiceCloud\n| where EventType =~ 'Login' and LoginStatus=~'LOGIN_NO_ERROR'\n| project TimeGenerated, TimestampDerived, ClientIp, UserId, User, UserType ;\nUsersLocation\n| extend Dummy=1\n| extend TimestampDerived = todatetime(TimestampDerived)\n| summarize count() by Hour=bin(TimestampDerived,30m), ClientIp,User, Dummy\n| partition by Hour(\n                lookup (Countrydb|extend Dummy=1) on Dummy\n              | where ipv4_is_match(ClientIp, Network)\n              )\n| summarize NumOfCountries = dcount(country_name) by User, Hour\n| where NumOfCountries >= threshold\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "PT1H",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "InitialAccess"
        ],
        "techniques": [
          "T1078"
        ],
        "templateVersion": "1.0.4",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}