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
DescriptionThis 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.4
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
relevantTechniques:
- T1557
- T1110
- T1110.003
- T1110.004
- T1212
- T1048
- T1087
- T1580
name: Unauthorized user access across AWS and Azure
requiredDataConnectors:
- dataTypes:
  - SigninLogs
  connectorId: AzureActiveDirectory
- dataTypes:
  - AWSGuardDuty
  connectorId: AWSS3
entityMappings:
- fieldMappings:
  - identifier: Address
    columnName: IPAddress
  entityType: IP
- fieldMappings:
  - identifier: FullName
    columnName: UserPrincipalName
  - identifier: Name
    columnName: Name
  - identifier: UPNSuffix
    columnName: UPNSuffix
  entityType: Account
triggerThreshold: 0
id: 60f31001-018a-42bf-8045-a92e1f361b7b
tactics:
- CredentialAccess
- Exfiltration
- Discovery
version: 1.0.4
customDetails:
  AzConditionalAccess: ConditionalAccessStatus
  AzureClientAppUsed: ClientAppUsed
  AzureUser: UserPrincipalName
  AWSresourceType: AWSresourceType
  AzAuthRequirement: AuthenticationRequirement
  AWSArn: Arn
  AzureUserAgent: UserAgent
  AzureRiskDetail: RiskDetail
  alertSeverity: Severity
  AzureOperationName: OperationName
  AWSAlertUserName: AWSAlertUserNameEntity
  AWSAPICallCount: APICallCount
  AWSAPICallName: APICallName
  AWSInstanceType: InstanceType
alertDetailsOverride:
  alertDynamicProperties:
  - alertProperty: AlertLink
    value: AWSAlertLink
  - alertProperty: ProviderName
    value: AWS
  - alertProperty: ProductName
    value: AWSGuardDuty
  - alertProperty: ProductComponentName
    value: AWSGuardDuty
  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
queryPeriod: 1d
kind: Scheduled
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
queryFrequency: 1d
severity: Medium
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  
triggerOperator: gt
{
  "$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/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": "'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.'\n",
        "displayName": "Unauthorized user access across AWS and Azure",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "IPAddress",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "UserPrincipalName",
                "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/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",
        "subTechniques": [
          "T1110.003",
          "T1110.004"
        ],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CredentialAccess",
          "Discovery",
          "Exfiltration"
        ],
        "techniques": [
          "T1048",
          "T1087",
          "T1110",
          "T1212",
          "T1557",
          "T1580"
        ],
        "templateVersion": "1.0.4",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}