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

Unauthorized user access across AWS and Azure

Back
Id60f31001-018a-42bf-8045-a92e1f361b7b
RulenameUnauthorized user access across AWS and Azure
Description

This detection compiles and correlates unauthorized user access alerts originating from AWS GuardDuty with Azure portal sign-in activities. It focuses on AWS GuardDuty alerts related to unauthorized user access, specifically targeting network IP associations tied to activities such as logins from malicious IP addresses or instance credential exfiltration attempts. The ditection leverages these common network IP advisories to detect and pinpoint unauthorized users attempting to access both AWS and Azure resources.
SeverityMedium
TacticsCredentialAccess
Exfiltration
Discovery
TechniquesT1557
T1110
T1110.003
T1110.004
T1212
T1048
T1087
T1580
Required data connectorsAWSS3
AzureActiveDirectory
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/Unauthorized_user_access_across_AWS_and_Azure.yaml
Version1.0.2
Arm template60f31001-018a-42bf-8045-a92e1f361b7b.json
Deploy To Azure
// Define a variable 'AwsAlert' to collect Unauthorized user access alerts from AWS GuardDuty table
let AwsAlert = materialize (
    AWSGuardDuty
    | where ActivityType has_any ("UnauthorizedAccess:IAMUser/TorIPCaller", "UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom", 
    "UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS", "UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.InsideAWS",
    "UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B","UnauthorizedAccess:IAMUser/MaliciousIPCaller")
    | extend
        AWSAlertId = Id, 
        AWSAlertTitle = Title,
        AWSAlertDescription = Description,
        AWSresourceType = tostring(parse_json(ResourceDetails).resourceType),
        AWSNetworkEntity = tostring(parse_json(ServiceDetails).action.awsApiCallAction.remoteIpDetails.ipAddressV4),
        AWSAlertUserNameEntity = tostring(parse_json(ResourceDetails).accessKeyDetails.userName),
        InstanceType = tostring(parse_json(ResourceDetails).instanceDetails.instanceType),
        AWSTargetingService = parse_json(ServiceDetails).additionalInfo.apiCalls,
        AWSAlertTime = TimeCreated,
        AWSAlertLink= tostring(strcat('https://us-east-1.console.aws.amazon.com/guardduty/home?region=us-east-1#/findings?macros=current&fId=',Id)),
        Severity = 
  case (
    Severity >= 7.0, "High",
    Severity between (4.0 .. 6.9), "Medium",
    Severity between (1.0 .. 3.9), "Low",
    "Unknown")
    | mv-apply AIPCall = AWSTargetingService on 
        ( 
        where AIPCall has "name"    
        | extend APICallName = tostring(AIPCall.name), APICallCount = tostring(AIPCall["count"])
        ) 
    | distinct
        AWSAlertTime,
        ActivityType,
        Severity,
        AWSAlertId,
        AWSAlertTitle,
        AWSAlertDescription,
        AWSAlertLink,
        Arn,
        AWSresourceType,
        AWSNetworkEntity,
        AWSAlertUserNameEntity,
        InstanceType,
        APICallName,
        APICallCount      
    );
    // Define a variable 'Azure_sigin' to collect Azure portal Signing activity from SigninLogs Table
    let Azure_sigin = materialize (SigninLogs
        | where AppDisplayName == "Azure Portal"
        | where isnotempty(OriginalRequestId)
        | summarize 
            totalAzureLoginEventId = dcount(OriginalRequestId), 
            AzureFailedEventsCount = dcountif(OriginalRequestId, ResultType != 0), 
            AzureSuccessfulEventsCount = dcountif(OriginalRequestId, ResultType == 0),
            AzureSetOfFailedEvents = makeset(iff(ResultType != 0, OriginalRequestId, ""), 5), 
            AzureSetOfSuccessfulEvents = makeset(iff(ResultType == 0, OriginalRequestId, ""), 5) 
        by 
            IPAddress, 
            UserPrincipalName, 
            bin(TimeGenerated, 1min), 
            UserAgent,
            ConditionalAccessStatus,
            OperationName,
            RiskDetail,
            AuthenticationRequirement,
            ClientAppUsed 
        // Extracting the name and UPN suffix from UserPrincipalName
        | extend
            Name = tostring(split(UserPrincipalName, "@")[0]),
            UPNSuffix = tostring(split(UserPrincipalName, "@")[1])
    );
    // Join 'AwsAlert' and 'Azure_sigin' on the AWS Network Entity and Azure IP Address
    AwsAlert
    | join kind=inner Azure_sigin on $left.AWSNetworkEntity == $right.IPAddress
customDetails:
  AzureUser: UserPrincipalName
  AWSAPICallName: APICallName
  AWSInstanceType: InstanceType
  AzureOperationName: OperationName
  AzureUserAgent: UserAgent
  AWSArn: Arn
  AWSresourceType: AWSresourceType
  AzAuthRequirement: AuthenticationRequirement
  AWSAPICallCount: APICallCount
  AzureClientAppUsed: ClientAppUsed
  AzConditionalAccess: ConditionalAccessStatus
  AzureRiskDetail: RiskDetail
  alertSeverity: Severity
  AWSAlertUserName: AWSAlertUserNameEntity
alertDetailsOverride:
  alertDynamicProperties:
  - value: AWSAlertLink
    alertProperty: AlertLink
  - value: AWS
    alertProperty: ProviderName
  - value: AWSGuardDuty
    alertProperty: ProductName
  - value: AWSGuardDuty
    alertProperty: ProductComponentName
  alertDisplayNameFormat: '{{AWSNetworkEntity}} from {{AWSAlertTitle}} observed in Azure Singins with {{UserPrincipalName}}'
  alertSeverityColumnName: Severity
  alertDescriptionFormat: |2-
      This detection compiles and correlates unauthorized user access alerts originating from AWS GuardDuty With Alert Description '{{AWSAlertDescription}}' with Azure portal sign-in activities. It focuses on AWS GuardDuty alerts related to unauthorized user access, specifically targeting 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 unauthorized users attempting to access both AWS and Azure resources.  

     AWS ALert Link : '{{AWSAlertLink}}' 

     Find More Details :https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-active.html
triggerThreshold: 0
relevantTechniques:
- T1557
- T1110
- T1110.003
- T1110.004
- T1212
- T1048
- T1087
- T1580
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Multi Cloud Attack Coverage Essentials - Resource Abuse/Analytic Rules/Unauthorized_user_access_across_AWS_and_Azure.yaml
requiredDataConnectors:
- dataTypes:
  - SigninLogs
  connectorId: AzureActiveDirectory
- dataTypes:
  - AWSGuardDuty
  connectorId: AWSS3
queryPeriod: 1d
tactics:
- CredentialAccess
- Exfiltration
- Discovery
severity: Medium
triggerOperator: gt
description: |
  '
  This detection compiles and correlates unauthorized user access alerts originating from AWS GuardDuty with Azure portal sign-in activities. It focuses on AWS GuardDuty alerts related to unauthorized user access, specifically targeting network IP associations tied to activities such as logins from malicious IP addresses or instance credential exfiltration attempts. The ditection leverages these common network IP advisories to detect and pinpoint unauthorized users attempting to access both AWS and Azure resources.
  '  
query: |
  // Define a variable 'AwsAlert' to collect Unauthorized user access alerts from AWS GuardDuty table
  let AwsAlert = materialize (
      AWSGuardDuty
      | where ActivityType has_any ("UnauthorizedAccess:IAMUser/TorIPCaller", "UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom", 
      "UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS", "UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.InsideAWS",
      "UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B","UnauthorizedAccess:IAMUser/MaliciousIPCaller")
      | extend
          AWSAlertId = Id, 
          AWSAlertTitle = Title,
          AWSAlertDescription = Description,
          AWSresourceType = tostring(parse_json(ResourceDetails).resourceType),
          AWSNetworkEntity = tostring(parse_json(ServiceDetails).action.awsApiCallAction.remoteIpDetails.ipAddressV4),
          AWSAlertUserNameEntity = tostring(parse_json(ResourceDetails).accessKeyDetails.userName),
          InstanceType = tostring(parse_json(ResourceDetails).instanceDetails.instanceType),
          AWSTargetingService = parse_json(ServiceDetails).additionalInfo.apiCalls,
          AWSAlertTime = TimeCreated,
          AWSAlertLink= tostring(strcat('https://us-east-1.console.aws.amazon.com/guardduty/home?region=us-east-1#/findings?macros=current&fId=',Id)),
          Severity = 
    case (
      Severity >= 7.0, "High",
      Severity between (4.0 .. 6.9), "Medium",
      Severity between (1.0 .. 3.9), "Low",
      "Unknown")
      | mv-apply AIPCall = AWSTargetingService on 
          ( 
          where AIPCall has "name"    
          | extend APICallName = tostring(AIPCall.name), APICallCount = tostring(AIPCall["count"])
          ) 
      | distinct
          AWSAlertTime,
          ActivityType,
          Severity,
          AWSAlertId,
          AWSAlertTitle,
          AWSAlertDescription,
          AWSAlertLink,
          Arn,
          AWSresourceType,
          AWSNetworkEntity,
          AWSAlertUserNameEntity,
          InstanceType,
          APICallName,
          APICallCount      
      );
      // Define a variable 'Azure_sigin' to collect Azure portal Signing activity from SigninLogs Table
      let Azure_sigin = materialize (SigninLogs
          | where AppDisplayName == "Azure Portal"
          | where isnotempty(OriginalRequestId)
          | summarize 
              totalAzureLoginEventId = dcount(OriginalRequestId), 
              AzureFailedEventsCount = dcountif(OriginalRequestId, ResultType != 0), 
              AzureSuccessfulEventsCount = dcountif(OriginalRequestId, ResultType == 0),
              AzureSetOfFailedEvents = makeset(iff(ResultType != 0, OriginalRequestId, ""), 5), 
              AzureSetOfSuccessfulEvents = makeset(iff(ResultType == 0, OriginalRequestId, ""), 5) 
          by 
              IPAddress, 
              UserPrincipalName, 
              bin(TimeGenerated, 1min), 
              UserAgent,
              ConditionalAccessStatus,
              OperationName,
              RiskDetail,
              AuthenticationRequirement,
              ClientAppUsed 
          // Extracting the name and UPN suffix from UserPrincipalName
          | extend
              Name = tostring(split(UserPrincipalName, "@")[0]),
              UPNSuffix = tostring(split(UserPrincipalName, "@")[1])
      );
      // Join 'AwsAlert' and 'Azure_sigin' on the AWS Network Entity and Azure IP Address
      AwsAlert
      | join kind=inner Azure_sigin on $left.AWSNetworkEntity == $right.IPAddress  
name: Unauthorized user access across AWS and Azure
version: 1.0.2
kind: Scheduled
id: 60f31001-018a-42bf-8045-a92e1f361b7b
queryFrequency: 1d
entityMappings:
- entityType: IP
  fieldMappings:
  - columnName: IPAddress
    identifier: Address
- entityType: Account
  fieldMappings:
  - columnName: Name
    identifier: Name
  - columnName: UPNSuffix
    identifier: UPNSuffix
{
  "$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/60f31001-018a-42bf-8045-a92e1f361b7b')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/60f31001-018a-42bf-8045-a92e1f361b7b')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "  This detection compiles and correlates unauthorized user access alerts originating from AWS GuardDuty With Alert Description '{{AWSAlertDescription}}' with Azure portal sign-in activities. It focuses on AWS GuardDuty alerts related to unauthorized user access, specifically targeting 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 unauthorized users attempting to access both AWS and Azure resources.  \n\n AWS ALert Link : '{{AWSAlertLink}}' \n\n Find More Details :https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-active.html",
          "alertDisplayNameFormat": "{{AWSNetworkEntity}} from {{AWSAlertTitle}} observed in Azure Singins with {{UserPrincipalName}}",
          "alertDynamicProperties": [
            {
              "alertProperty": "AlertLink",
              "value": "AWSAlertLink"
            },
            {
              "alertProperty": "ProviderName",
              "value": "AWS"
            },
            {
              "alertProperty": "ProductName",
              "value": "AWSGuardDuty"
            },
            {
              "alertProperty": "ProductComponentName",
              "value": "AWSGuardDuty"
            }
          ],
          "alertSeverityColumnName": "Severity"
        },
        "alertRuleTemplateName": "60f31001-018a-42bf-8045-a92e1f361b7b",
        "customDetails": {
          "alertSeverity": "Severity",
          "AWSAlertUserName": "AWSAlertUserNameEntity",
          "AWSAPICallCount": "APICallCount",
          "AWSAPICallName": "APICallName",
          "AWSArn": "Arn",
          "AWSInstanceType": "InstanceType",
          "AWSresourceType": "AWSresourceType",
          "AzAuthRequirement": "AuthenticationRequirement",
          "AzConditionalAccess": "ConditionalAccessStatus",
          "AzureClientAppUsed": "ClientAppUsed",
          "AzureOperationName": "OperationName",
          "AzureRiskDetail": "RiskDetail",
          "AzureUser": "UserPrincipalName",
          "AzureUserAgent": "UserAgent"
        },
        "description": "'\nThis detection compiles and correlates unauthorized user access alerts originating from AWS GuardDuty with Azure portal sign-in activities. It focuses on AWS GuardDuty alerts related to unauthorized user access, specifically targeting network IP associations tied to activities such as logins from malicious IP addresses or instance credential exfiltration attempts. The ditection leverages these common network IP advisories to detect and pinpoint unauthorized users attempting to access both AWS and Azure resources.\n'\n",
        "displayName": "Unauthorized user access across AWS and Azure",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "IPAddress",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "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/Unauthorized_user_access_across_AWS_and_Azure.yaml",
        "query": "// Define a variable 'AwsAlert' to collect Unauthorized user access alerts from AWS GuardDuty table\nlet AwsAlert = materialize (\n    AWSGuardDuty\n    | where ActivityType has_any (\"UnauthorizedAccess:IAMUser/TorIPCaller\", \"UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom\", \n    \"UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS\", \"UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.InsideAWS\",\n    \"UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B\",\"UnauthorizedAccess:IAMUser/MaliciousIPCaller\")\n    | extend\n        AWSAlertId = Id, \n        AWSAlertTitle = Title,\n        AWSAlertDescription = Description,\n        AWSresourceType = tostring(parse_json(ResourceDetails).resourceType),\n        AWSNetworkEntity = tostring(parse_json(ServiceDetails).action.awsApiCallAction.remoteIpDetails.ipAddressV4),\n        AWSAlertUserNameEntity = tostring(parse_json(ResourceDetails).accessKeyDetails.userName),\n        InstanceType = tostring(parse_json(ResourceDetails).instanceDetails.instanceType),\n        AWSTargetingService = parse_json(ServiceDetails).additionalInfo.apiCalls,\n        AWSAlertTime = TimeCreated,\n        AWSAlertLink= tostring(strcat('https://us-east-1.console.aws.amazon.com/guardduty/home?region=us-east-1#/findings?macros=current&fId=',Id)),\n        Severity = \n  case (\n    Severity >= 7.0, \"High\",\n    Severity between (4.0 .. 6.9), \"Medium\",\n    Severity between (1.0 .. 3.9), \"Low\",\n    \"Unknown\")\n    | mv-apply AIPCall = AWSTargetingService on \n        ( \n        where AIPCall has \"name\"    \n        | extend APICallName = tostring(AIPCall.name), APICallCount = tostring(AIPCall[\"count\"])\n        ) \n    | distinct\n        AWSAlertTime,\n        ActivityType,\n        Severity,\n        AWSAlertId,\n        AWSAlertTitle,\n        AWSAlertDescription,\n        AWSAlertLink,\n        Arn,\n        AWSresourceType,\n        AWSNetworkEntity,\n        AWSAlertUserNameEntity,\n        InstanceType,\n        APICallName,\n        APICallCount      \n    );\n    // Define a variable 'Azure_sigin' to collect Azure portal Signing activity from SigninLogs Table\n    let Azure_sigin = materialize (SigninLogs\n        | where AppDisplayName == \"Azure Portal\"\n        | where isnotempty(OriginalRequestId)\n        | summarize \n            totalAzureLoginEventId = dcount(OriginalRequestId), \n            AzureFailedEventsCount = dcountif(OriginalRequestId, ResultType != 0), \n            AzureSuccessfulEventsCount = dcountif(OriginalRequestId, ResultType == 0),\n            AzureSetOfFailedEvents = makeset(iff(ResultType != 0, OriginalRequestId, \"\"), 5), \n            AzureSetOfSuccessfulEvents = makeset(iff(ResultType == 0, OriginalRequestId, \"\"), 5) \n        by \n            IPAddress, \n            UserPrincipalName, \n            bin(TimeGenerated, 1min), \n            UserAgent,\n            ConditionalAccessStatus,\n            OperationName,\n            RiskDetail,\n            AuthenticationRequirement,\n            ClientAppUsed \n        // Extracting the name and UPN suffix from UserPrincipalName\n        | extend\n            Name = tostring(split(UserPrincipalName, \"@\")[0]),\n            UPNSuffix = tostring(split(UserPrincipalName, \"@\")[1])\n    );\n    // Join 'AwsAlert' and 'Azure_sigin' on the AWS Network Entity and Azure IP Address\n    AwsAlert\n    | join kind=inner Azure_sigin on $left.AWSNetworkEntity == $right.IPAddress\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P1D",
        "severity": "Medium",
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CredentialAccess",
          "Discovery",
          "Exfiltration"
        ],
        "techniques": [
          "T1048",
          "T1087",
          "T1110",
          "T1212",
          "T1557",
          "T1580"
        ],
        "templateVersion": "1.0.2",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}