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

Cross-Cloud Suspicious user activity observed in GCP Envourment

Back
Id58e306fe-1c49-4b8f-9b0e-15f25e8f0cd7
RulenameCross-Cloud Suspicious user activity observed in GCP Envourment
Description

This detection query aims to correlate potentially suspicious user activities logged in Google Cloud Platform (GCP) Audit Logs with security alerts originating from Microsoft Security products. This correlation facilitates the identification of potential cross-cloud security incidents. By summarizing these findings, the query provides valuable insights into cross-cloud identity threats and their associated details, enabling organizations to respond promptly and mitigate potential risks effectively.
SeverityMedium
TacticsInitialAccess
Execution
Persistence
PrivilegeEscalation
CredentialAccess
Discovery
TechniquesT1566
T1059
T1078
T1046
T1547
T1548
T1069
T1552
Required data connectorsAzureActiveDirectoryIdentityProtection
GCPAuditLogsDefinition
MicrosoftCloudAppSecurity
MicrosoftDefenderAdvancedThreatProtection
MicrosoftThreatProtection
KindScheduled
Query frequency1d
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Multi Cloud Attack Coverage Essentials - Resource Abuse/Analytic Rules/CrossCloudSuspiciousUserActivityObservedInGCPEnvourment.yaml
Version1.0.1
Arm template58e306fe-1c49-4b8f-9b0e-15f25e8f0cd7.json
Deploy To Azure
// Filter GCP Audit Logs to exclude service accounts
GCPAuditLogs 
| where PrincipalEmail !endswith "gserviceaccount.com"
// Exclude system-related authentication information
| where AuthenticationInfo !has ("system:")
// Extract GCP request name and relevant attributes
| extend GCPRequestName= parse_json(Request).name
| extend
    GCPAccoutType= tostring(split(GCPRequestName, "/")[2]),
    GCPUserIdentity = iff(isempty(tostring(split(GCPRequestName, "/")[3])), tostring(parse_json(AuthenticationInfo).principalEmail), "na"), 
    GCPUserIp = tostring(parse_json(RequestMetadata).callerIp),
    GCPCallerUA = tostring(parse_json(RequestMetadata).callerSuppliedUserAgent)
// Filter out empty or service account identities
| where isnotempty(GCPUserIdentity) and GCPUserIdentity !endswith "gserviceaccount.com"
// Select relevant attributes for further analysis
| project
    PrincipalEmail,
    GCPUserIdentity,
    GCPAccoutType,
    GCPRequestName,
    GCPCallerUA,
    Request,
    RequestMetadata,
    GCPUserIp,
    MethodName,
    ServiceName,
    GCPEventTime= TimeGenerated,
    ProjectId
// Join GCP Audit Logs with SecurityAlert data based on user identity and IP
| join kind=inner (    
    SecurityAlert 
    // Exclude alerts from Azure Sentinel
    | where ProductName !in ("Azure Sentinel")
    // Extract IP entities from alert data
    | extend AlertIPEntity=  tostring(extract(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", 0, Entities))
    | extend
        AlertUserUPN = tostring(extract(@'\b[\w\.\-]+@[\w\.\-]+\b', 0, Entities)),
        AlertTime= TimeGenerated
    // Filter out empty user identities and IP entities
    | where isnotempty(AlertIPEntity) and isnotempty(AlertUserUPN)
    )
    on $left.GCPUserIdentity == $right.AlertUserUPN and $left.GCPUserIp == $right.AlertIPEntity
// Summarize the data, calculating time differences and aggregating attributes
| summarize
    FirstAlert=min(AlertTime),
    LastAlert=max(AlertTime),
    TimeDiff=datetime_diff('minute', min(AlertTime), min(GCPEventTime)),
    MethodName=make_set(MethodName),
    ServiceName= make_set(ServiceName),
    GCPProjctId=make_set(ProjectId),
    Request=make_set(Request),
    GCPCallerUA=make_set(GCPCallerUA)
    by
    AlertUserUPN,
    AlertIPEntity,
    GCPUserIp,
    GCPUserIdentity,
    AlertSeverity,
    AlertName,
    AlertLink,
    Description,
    Tactics,
    ProductName,
    SystemAlertId,
    GCPAccoutType
// Extend the data with additional attributes
| extend
    Name = tostring(split(GCPUserIdentity, "@")[0]),
    UPNSuffix = tostring(split(GCPUserIdentity, "@")[1])
id: 58e306fe-1c49-4b8f-9b0e-15f25e8f0cd7
requiredDataConnectors:
- connectorId: GCPAuditLogsDefinition
  dataTypes:
  - GCPAuditLogs
- connectorId: AzureActiveDirectoryIdentityProtection
  dataTypes:
  - SecurityAlert (IPC)
- connectorId: MicrosoftThreatProtection
  dataTypes:
  - SecurityAlert
- connectorId: MicrosoftDefenderAdvancedThreatProtection
  dataTypes:
  - SecurityAlert (MDATP)
- connectorId: MicrosoftCloudAppSecurity
  dataTypes:
  - SecurityAlert
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Multi Cloud Attack Coverage Essentials - Resource Abuse/Analytic Rules/CrossCloudSuspiciousUserActivityObservedInGCPEnvourment.yaml
severity: Medium
description: |
  '
  This detection query aims to correlate potentially suspicious user activities logged in Google Cloud Platform (GCP) Audit Logs with security alerts originating from Microsoft Security products. This correlation facilitates the identification of potential cross-cloud security incidents. By summarizing these findings, the query provides valuable insights into cross-cloud identity threats and their associated details, enabling organizations to respond promptly and mitigate potential risks effectively.
  '  
relevantTechniques:
- T1566
- T1059
- T1078
- T1046
- T1547
- T1548
- T1069
- T1552
tactics:
- InitialAccess
- Execution
- Persistence
- PrivilegeEscalation
- CredentialAccess
- Discovery
triggerThreshold: 0
kind: Scheduled
query: |
  // Filter GCP Audit Logs to exclude service accounts
  GCPAuditLogs 
  | where PrincipalEmail !endswith "gserviceaccount.com"
  // Exclude system-related authentication information
  | where AuthenticationInfo !has ("system:")
  // Extract GCP request name and relevant attributes
  | extend GCPRequestName= parse_json(Request).name
  | extend
      GCPAccoutType= tostring(split(GCPRequestName, "/")[2]),
      GCPUserIdentity = iff(isempty(tostring(split(GCPRequestName, "/")[3])), tostring(parse_json(AuthenticationInfo).principalEmail), "na"), 
      GCPUserIp = tostring(parse_json(RequestMetadata).callerIp),
      GCPCallerUA = tostring(parse_json(RequestMetadata).callerSuppliedUserAgent)
  // Filter out empty or service account identities
  | where isnotempty(GCPUserIdentity) and GCPUserIdentity !endswith "gserviceaccount.com"
  // Select relevant attributes for further analysis
  | project
      PrincipalEmail,
      GCPUserIdentity,
      GCPAccoutType,
      GCPRequestName,
      GCPCallerUA,
      Request,
      RequestMetadata,
      GCPUserIp,
      MethodName,
      ServiceName,
      GCPEventTime= TimeGenerated,
      ProjectId
  // Join GCP Audit Logs with SecurityAlert data based on user identity and IP
  | join kind=inner (    
      SecurityAlert 
      // Exclude alerts from Azure Sentinel
      | where ProductName !in ("Azure Sentinel")
      // Extract IP entities from alert data
      | extend AlertIPEntity=  tostring(extract(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", 0, Entities))
      | extend
          AlertUserUPN = tostring(extract(@'\b[\w\.\-]+@[\w\.\-]+\b', 0, Entities)),
          AlertTime= TimeGenerated
      // Filter out empty user identities and IP entities
      | where isnotempty(AlertIPEntity) and isnotempty(AlertUserUPN)
      )
      on $left.GCPUserIdentity == $right.AlertUserUPN and $left.GCPUserIp == $right.AlertIPEntity
  // Summarize the data, calculating time differences and aggregating attributes
  | summarize
      FirstAlert=min(AlertTime),
      LastAlert=max(AlertTime),
      TimeDiff=datetime_diff('minute', min(AlertTime), min(GCPEventTime)),
      MethodName=make_set(MethodName),
      ServiceName= make_set(ServiceName),
      GCPProjctId=make_set(ProjectId),
      Request=make_set(Request),
      GCPCallerUA=make_set(GCPCallerUA)
      by
      AlertUserUPN,
      AlertIPEntity,
      GCPUserIp,
      GCPUserIdentity,
      AlertSeverity,
      AlertName,
      AlertLink,
      Description,
      Tactics,
      ProductName,
      SystemAlertId,
      GCPAccoutType
  // Extend the data with additional attributes
  | extend
      Name = tostring(split(GCPUserIdentity, "@")[0]),
      UPNSuffix = tostring(split(GCPUserIdentity, "@")[1])  
name: Cross-Cloud Suspicious user activity observed in GCP Envourment
version: 1.0.1
queryFrequency: 1d
entityMappings:
- fieldMappings:
  - identifier: Address
    columnName: GCPUserIp
  entityType: IP
- fieldMappings:
  - identifier: FullName
    columnName: GCPUserIdentity
  - identifier: Name
    columnName: Name
  - identifier: UPNSuffix
    columnName: UPNSuffix
  entityType: Account
customDetails:
  CorrelationWith: GCPAuditLogs
  LastAlert: LastAlert
  AlertUserUPN: AlertUserUPN
  TimeDiff: TimeDiff
  Request: Request
  AlertName: AlertName
  GCPProjctId: GCPProjctId
  Tactics: Tactics
  ServiceName: ServiceName
  GCPCallerUA: GCPCallerUA
  SystemAlertId: SystemAlertId
  FirstAlert: FirstAlert
  MethodName: MethodName
triggerOperator: gt
queryPeriod: 1d
alertDetailsOverride:
  alertDynamicProperties:
  - value: AlertLink
    alertProperty: AlertLink
  - value: ProductName
    alertProperty: ProviderName
  - value: Microsoft Security
    alertProperty: ProductComponentName
  alertDisplayNameFormat: A user {{GCPUserUPN}} has been linked to {{AlertName}}, and has potentially suspicious behavior within the GCP environment from, originating from the IP address {{GCPUserIp}}.
  alertSeverityColumnName: AlertSeverity
  alertDescriptionFormat: |2-
     This detection compiles and correlates unauthorized user access alerts originating from {{ProductName}} With Alert Description '{{Description}}' observed activity in GCP environmeny. It focuses on Microsoft Security, specifically targeting user bhaviour and network IP associations tied to activities such as logins from malicious IP addresses or instance credential exfiltration attempts. The detection leverages these common network IP advisories to detect and pinpoint users suspicious activity to access both Azure and GCP resources.  

     Microsoft Security ALert Link : '{{AlertLink}}'
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2023-02-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/58e306fe-1c49-4b8f-9b0e-15f25e8f0cd7')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/58e306fe-1c49-4b8f-9b0e-15f25e8f0cd7')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": " This detection compiles and correlates unauthorized user access alerts originating from {{ProductName}} With Alert Description '{{Description}}' observed activity in GCP environmeny. It focuses on Microsoft Security, specifically targeting user bhaviour and network IP associations tied to activities such as logins from malicious IP addresses or instance credential exfiltration attempts. The detection leverages these common network IP advisories to detect and pinpoint users suspicious activity to access both Azure and GCP resources.  \n\n Microsoft Security ALert Link : '{{AlertLink}}'",
          "alertDisplayNameFormat": "A user {{GCPUserUPN}} has been linked to {{AlertName}}, and has potentially suspicious behavior within the GCP environment from, originating from the IP address {{GCPUserIp}}.",
          "alertDynamicProperties": [
            {
              "alertProperty": "AlertLink",
              "value": "AlertLink"
            },
            {
              "alertProperty": "ProviderName",
              "value": "ProductName"
            },
            {
              "alertProperty": "ProductComponentName",
              "value": "Microsoft Security"
            }
          ],
          "alertSeverityColumnName": "AlertSeverity"
        },
        "alertRuleTemplateName": "58e306fe-1c49-4b8f-9b0e-15f25e8f0cd7",
        "customDetails": {
          "AlertName": "AlertName",
          "AlertUserUPN": "AlertUserUPN",
          "CorrelationWith": "GCPAuditLogs",
          "FirstAlert": "FirstAlert",
          "GCPCallerUA": "GCPCallerUA",
          "GCPProjctId": "GCPProjctId",
          "LastAlert": "LastAlert",
          "MethodName": "MethodName",
          "Request": "Request",
          "ServiceName": "ServiceName",
          "SystemAlertId": "SystemAlertId",
          "Tactics": "Tactics",
          "TimeDiff": "TimeDiff"
        },
        "description": "'\nThis detection query aims to correlate potentially suspicious user activities logged in Google Cloud Platform (GCP) Audit Logs with security alerts originating from Microsoft Security products. This correlation facilitates the identification of potential cross-cloud security incidents. By summarizing these findings, the query provides valuable insights into cross-cloud identity threats and their associated details, enabling organizations to respond promptly and mitigate potential risks effectively.\n'\n",
        "displayName": "Cross-Cloud Suspicious user activity observed in GCP Envourment",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "GCPUserIp",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "GCPUserIdentity",
                "identifier": "FullName"
              },
              {
                "columnName": "Name",
                "identifier": "Name"
              },
              {
                "columnName": "UPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Multi Cloud Attack Coverage Essentials - Resource Abuse/Analytic Rules/CrossCloudSuspiciousUserActivityObservedInGCPEnvourment.yaml",
        "query": "// Filter GCP Audit Logs to exclude service accounts\nGCPAuditLogs \n| where PrincipalEmail !endswith \"gserviceaccount.com\"\n// Exclude system-related authentication information\n| where AuthenticationInfo !has (\"system:\")\n// Extract GCP request name and relevant attributes\n| extend GCPRequestName= parse_json(Request).name\n| extend\n    GCPAccoutType= tostring(split(GCPRequestName, \"/\")[2]),\n    GCPUserIdentity = iff(isempty(tostring(split(GCPRequestName, \"/\")[3])), tostring(parse_json(AuthenticationInfo).principalEmail), \"na\"), \n    GCPUserIp = tostring(parse_json(RequestMetadata).callerIp),\n    GCPCallerUA = tostring(parse_json(RequestMetadata).callerSuppliedUserAgent)\n// Filter out empty or service account identities\n| where isnotempty(GCPUserIdentity) and GCPUserIdentity !endswith \"gserviceaccount.com\"\n// Select relevant attributes for further analysis\n| project\n    PrincipalEmail,\n    GCPUserIdentity,\n    GCPAccoutType,\n    GCPRequestName,\n    GCPCallerUA,\n    Request,\n    RequestMetadata,\n    GCPUserIp,\n    MethodName,\n    ServiceName,\n    GCPEventTime= TimeGenerated,\n    ProjectId\n// Join GCP Audit Logs with SecurityAlert data based on user identity and IP\n| join kind=inner (    \n    SecurityAlert \n    // Exclude alerts from Azure Sentinel\n    | where ProductName !in (\"Azure Sentinel\")\n    // Extract IP entities from alert data\n    | extend AlertIPEntity=  tostring(extract(@\"\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\", 0, Entities))\n    | extend\n        AlertUserUPN = tostring(extract(@'\\b[\\w\\.\\-]+@[\\w\\.\\-]+\\b', 0, Entities)),\n        AlertTime= TimeGenerated\n    // Filter out empty user identities and IP entities\n    | where isnotempty(AlertIPEntity) and isnotempty(AlertUserUPN)\n    )\n    on $left.GCPUserIdentity == $right.AlertUserUPN and $left.GCPUserIp == $right.AlertIPEntity\n// Summarize the data, calculating time differences and aggregating attributes\n| summarize\n    FirstAlert=min(AlertTime),\n    LastAlert=max(AlertTime),\n    TimeDiff=datetime_diff('minute', min(AlertTime), min(GCPEventTime)),\n    MethodName=make_set(MethodName),\n    ServiceName= make_set(ServiceName),\n    GCPProjctId=make_set(ProjectId),\n    Request=make_set(Request),\n    GCPCallerUA=make_set(GCPCallerUA)\n    by\n    AlertUserUPN,\n    AlertIPEntity,\n    GCPUserIp,\n    GCPUserIdentity,\n    AlertSeverity,\n    AlertName,\n    AlertLink,\n    Description,\n    Tactics,\n    ProductName,\n    SystemAlertId,\n    GCPAccoutType\n// Extend the data with additional attributes\n| extend\n    Name = tostring(split(GCPUserIdentity, \"@\")[0]),\n    UPNSuffix = tostring(split(GCPUserIdentity, \"@\")[1])\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P1D",
        "severity": "Medium",
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CredentialAccess",
          "Discovery",
          "Execution",
          "InitialAccess",
          "Persistence",
          "PrivilegeEscalation"
        ],
        "techniques": [
          "T1046",
          "T1059",
          "T1069",
          "T1078",
          "T1547",
          "T1548",
          "T1552",
          "T1566"
        ],
        "templateVersion": "1.0.1",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}