Back
Id122fbc6a-57ab-4aa7-b9a9-51ac4970cac1
RulenameCross-Cloud Unauthorized Credential Access Detection From AWS RDS Login
DescriptionThis detection correlates AWS GuardDuty Credential Access alerts related to Amazon Relational Database Service (RDS) activity with Azure portal sign-in activities. It identifies successful and failed logins, anomalous behavior, and malicious IP access. By joining these datasets on network entities and IP addresses, it detects unauthorized credential access attempts across AWS and Azure resources, enhancing cross-cloud security monitoring.
SeverityMedium
TacticsCredentialAccess
InitialAccess
TechniquesT1557
T1110
T1110.003
T1110.004
T1606
T1556
T1133
Required data connectorsAWSS3
AzureActiveDirectory
KindScheduled
Query frequency1d
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Multi%20Cloud%20Attack%20Coverage%20Essentials%20-%20Resource%20Abuse/Analytic%20Rules/CrossCloudUnauthorizedCredentialsAccessDetection.yaml
Version1.0.3
Arm template122fbc6a-57ab-4aa7-b9a9-51ac4970cac1.json
Deploy To Azure
// Define variable 'AwsAlert' to collect AWS GuardDuty CredentialAccess alerts related to Amazon Relational Database Service (RDS) activity
let AwsAlert = materialize (
    AWSGuardDuty
    | where ActivityType has_any (
        "CredentialAccess:RDS/TorIPCaller.SuccessfulLogin",
        "CredentialAccess:RDS/TorIPCaller.FailedLogin",
        "CredentialAccess:RDS/AnomalousBehavior.SuccessfulBruteForce",
        "CredentialAccess:RDS/AnomalousBehavior.SuccessfulLogin",
        "CredentialAccess:RDS/MaliciousIPCaller.SuccessfulLogin",
        "CredentialAccess:RDS/MaliciousIPCaller.FailedLogin"
        )
    | extend
        AWSAlertId = Id, 
        AWSAlertTitle = Title,
        AWSAlertDescription = Description,
        AWSresourceType = tostring(parse_json(ResourceDetails).resourceType),
        AWSNetworkEntity = tostring(parse_json(ServiceDetails).action.rdsLoginAttemptAction.remoteIpDetails.ipAddressV4),
        RDSInstanceId = tostring(parse_json(ResourceDetails).rdsDbInstanceDetails.dbInstanceIdentifier),
        RDSUser = tostring(parse_json(ResourceDetails).rdsDbUserDetails.user),
        RDSApplication = tostring(parse_json(ResourceDetails).rdsDbUserDetails.application),
        RDSactionType = tostring(parse_json(ServiceDetails).action.actionType),
        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")
    | distinct
        AWSAlertTime,
        ActivityType,
        AWSAlertId,
        AWSAlertLink,
        AWSAlertTitle,
        AWSAlertDescription,
        AWSresourceType,
        Arn,
        Severity,
        RDSactionType,
        RDSApplication,
        RDSInstanceId,
        RDSUser,
        AWSNetworkEntity
    );
  // Define variable 'Azure_sigin' to collect Azure portal sign-in activities
  let Azure_sigin = materialize (
      SigninLogs
      | where AppDisplayName == "Azure Portal"
      | where isnotempty(OriginalRequestId)
      | summarize 
          AzureSuccessfulEvent = countif(ResultType == 0), 
          AzureFailedEvent = countif(ResultType != 0), 
          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
requiredDataConnectors:
- connectorId: AzureActiveDirectory
  dataTypes:
  - SigninLogs
- connectorId: AWSS3
  dataTypes:
  - AWSGuardDuty
customDetails:
  AWSArn: Arn
  AWSAplicationName: RDSApplication
  AzureRiskDetail: RiskDetail
  AzureOperationName: OperationName
  AWSAlertUserName: RDSUser
  AzAuthRequirement: AuthenticationRequirement
  AzureUser: UserPrincipalName
  AWSresourceType: AWSresourceType
  AzConditionalAccess: ConditionalAccessStatus
  AzureUserAgent: UserAgent
  alertSeverity: Severity
  AzureClientAppUsed: ClientAppUsed
  AWSInstanceType: RDSactionType
  AWSInstanceId: RDSInstanceId
description: |
  'This detection correlates AWS GuardDuty Credential Access alerts related to Amazon Relational Database Service (RDS) activity with Azure portal sign-in activities. It identifies successful and failed logins, anomalous behavior, and malicious IP access. By joining these datasets on network entities and IP addresses, it detects unauthorized credential access attempts across AWS and Azure resources, enhancing cross-cloud security monitoring.'
version: 1.0.3
name: Cross-Cloud Unauthorized Credential Access Detection From AWS RDS Login
kind: Scheduled
queryPeriod: 1d
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Multi%20Cloud%20Attack%20Coverage%20Essentials%20-%20Resource%20Abuse/Analytic%20Rules/CrossCloudUnauthorizedCredentialsAccessDetection.yaml
alertDetailsOverride:
  alertDescriptionFormat: |-
    This detection correlates AWS GuardDuty Credential Access alert described '{{AWSAlertDescription}}' related to Amazon Relational Database Service (RDS) activity with Azure portal sign-in activities. It identifies successful and failed logins, anomalous behavior, and malicious IP access. By joining these datasets on network entities and IP addresses, it detects unauthorized credential access attempts across AWS and Azure resources, enhancing cross-cloud security monitoring. 

     AWS ALert Link : '{{AWSAlertLink}}' 

     Find More Details :https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-active.html
  alertDynamicProperties:
  - value: AWSAlertLink
    alertProperty: AlertLink
  - value: AWS
    alertProperty: ProviderName
  - value: AWSGuardDuty
    alertProperty: ProductName
  - value: AWSGuardDuty
    alertProperty: ProductComponentName
  alertDisplayNameFormat: IP address {{IPAddress}} in {{AWSAlertTitle}} seen in Azure Signin Logs with {{UserPrincipalName}}
  alertSeverityColumnName: Severity
entityMappings:
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: IPAddress
- entityType: Account
  fieldMappings:
  - identifier: FullName
    columnName: UserPrincipalName
  - identifier: Name
    columnName: Name
  - identifier: UPNSuffix
    columnName: UPNSuffix
relevantTechniques:
- T1557
- T1110
- T1110.003
- T1110.004
- T1606
- T1556
- T1133
query: |
  // Define variable 'AwsAlert' to collect AWS GuardDuty CredentialAccess alerts related to Amazon Relational Database Service (RDS) activity
  let AwsAlert = materialize (
      AWSGuardDuty
      | where ActivityType has_any (
          "CredentialAccess:RDS/TorIPCaller.SuccessfulLogin",
          "CredentialAccess:RDS/TorIPCaller.FailedLogin",
          "CredentialAccess:RDS/AnomalousBehavior.SuccessfulBruteForce",
          "CredentialAccess:RDS/AnomalousBehavior.SuccessfulLogin",
          "CredentialAccess:RDS/MaliciousIPCaller.SuccessfulLogin",
          "CredentialAccess:RDS/MaliciousIPCaller.FailedLogin"
          )
      | extend
          AWSAlertId = Id, 
          AWSAlertTitle = Title,
          AWSAlertDescription = Description,
          AWSresourceType = tostring(parse_json(ResourceDetails).resourceType),
          AWSNetworkEntity = tostring(parse_json(ServiceDetails).action.rdsLoginAttemptAction.remoteIpDetails.ipAddressV4),
          RDSInstanceId = tostring(parse_json(ResourceDetails).rdsDbInstanceDetails.dbInstanceIdentifier),
          RDSUser = tostring(parse_json(ResourceDetails).rdsDbUserDetails.user),
          RDSApplication = tostring(parse_json(ResourceDetails).rdsDbUserDetails.application),
          RDSactionType = tostring(parse_json(ServiceDetails).action.actionType),
          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")
      | distinct
          AWSAlertTime,
          ActivityType,
          AWSAlertId,
          AWSAlertLink,
          AWSAlertTitle,
          AWSAlertDescription,
          AWSresourceType,
          Arn,
          Severity,
          RDSactionType,
          RDSApplication,
          RDSInstanceId,
          RDSUser,
          AWSNetworkEntity
      );
    // Define variable 'Azure_sigin' to collect Azure portal sign-in activities
    let Azure_sigin = materialize (
        SigninLogs
        | where AppDisplayName == "Azure Portal"
        | where isnotempty(OriginalRequestId)
        | summarize 
            AzureSuccessfulEvent = countif(ResultType == 0), 
            AzureFailedEvent = countif(ResultType != 0), 
            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
id: 122fbc6a-57ab-4aa7-b9a9-51ac4970cac1
triggerOperator: gt
queryFrequency: 1d
tactics:
- CredentialAccess
- InitialAccess
severity: Medium
triggerThreshold: 0
{
  "$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/122fbc6a-57ab-4aa7-b9a9-51ac4970cac1')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/122fbc6a-57ab-4aa7-b9a9-51ac4970cac1')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "This detection correlates AWS GuardDuty Credential Access alert described '{{AWSAlertDescription}}' related to Amazon Relational Database Service (RDS) activity with Azure portal sign-in activities. It identifies successful and failed logins, anomalous behavior, and malicious IP access. By joining these datasets on network entities and IP addresses, it detects unauthorized credential access attempts across AWS and Azure resources, enhancing cross-cloud security monitoring. \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": "IP address {{IPAddress}} in {{AWSAlertTitle}} seen in Azure Signin Logs with {{UserPrincipalName}}",
          "alertDynamicProperties": [
            {
              "alertProperty": "AlertLink",
              "value": "AWSAlertLink"
            },
            {
              "alertProperty": "ProviderName",
              "value": "AWS"
            },
            {
              "alertProperty": "ProductName",
              "value": "AWSGuardDuty"
            },
            {
              "alertProperty": "ProductComponentName",
              "value": "AWSGuardDuty"
            }
          ],
          "alertSeverityColumnName": "Severity"
        },
        "alertRuleTemplateName": "122fbc6a-57ab-4aa7-b9a9-51ac4970cac1",
        "customDetails": {
          "alertSeverity": "Severity",
          "AWSAlertUserName": "RDSUser",
          "AWSAplicationName": "RDSApplication",
          "AWSArn": "Arn",
          "AWSInstanceId": "RDSInstanceId",
          "AWSInstanceType": "RDSactionType",
          "AWSresourceType": "AWSresourceType",
          "AzAuthRequirement": "AuthenticationRequirement",
          "AzConditionalAccess": "ConditionalAccessStatus",
          "AzureClientAppUsed": "ClientAppUsed",
          "AzureOperationName": "OperationName",
          "AzureRiskDetail": "RiskDetail",
          "AzureUser": "UserPrincipalName",
          "AzureUserAgent": "UserAgent"
        },
        "description": "'This detection correlates AWS GuardDuty Credential Access alerts related to Amazon Relational Database Service (RDS) activity with Azure portal sign-in activities. It identifies successful and failed logins, anomalous behavior, and malicious IP access. By joining these datasets on network entities and IP addresses, it detects unauthorized credential access attempts across AWS and Azure resources, enhancing cross-cloud security monitoring.'\n",
        "displayName": "Cross-Cloud Unauthorized Credential Access Detection From AWS RDS Login",
        "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%20Cloud%20Attack%20Coverage%20Essentials%20-%20Resource%20Abuse/Analytic%20Rules/CrossCloudUnauthorizedCredentialsAccessDetection.yaml",
        "query": "// Define variable 'AwsAlert' to collect AWS GuardDuty CredentialAccess alerts related to Amazon Relational Database Service (RDS) activity\nlet AwsAlert = materialize (\n    AWSGuardDuty\n    | where ActivityType has_any (\n        \"CredentialAccess:RDS/TorIPCaller.SuccessfulLogin\",\n        \"CredentialAccess:RDS/TorIPCaller.FailedLogin\",\n        \"CredentialAccess:RDS/AnomalousBehavior.SuccessfulBruteForce\",\n        \"CredentialAccess:RDS/AnomalousBehavior.SuccessfulLogin\",\n        \"CredentialAccess:RDS/MaliciousIPCaller.SuccessfulLogin\",\n        \"CredentialAccess:RDS/MaliciousIPCaller.FailedLogin\"\n        )\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.rdsLoginAttemptAction.remoteIpDetails.ipAddressV4),\n        RDSInstanceId = tostring(parse_json(ResourceDetails).rdsDbInstanceDetails.dbInstanceIdentifier),\n        RDSUser = tostring(parse_json(ResourceDetails).rdsDbUserDetails.user),\n        RDSApplication = tostring(parse_json(ResourceDetails).rdsDbUserDetails.application),\n        RDSactionType = tostring(parse_json(ServiceDetails).action.actionType),\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    | distinct\n        AWSAlertTime,\n        ActivityType,\n        AWSAlertId,\n        AWSAlertLink,\n        AWSAlertTitle,\n        AWSAlertDescription,\n        AWSresourceType,\n        Arn,\n        Severity,\n        RDSactionType,\n        RDSApplication,\n        RDSInstanceId,\n        RDSUser,\n        AWSNetworkEntity\n    );\n  // Define variable 'Azure_sigin' to collect Azure portal sign-in activities\n  let Azure_sigin = materialize (\n      SigninLogs\n      | where AppDisplayName == \"Azure Portal\"\n      | where isnotempty(OriginalRequestId)\n      | summarize \n          AzureSuccessfulEvent = countif(ResultType == 0), \n          AzureFailedEvent = countif(ResultType != 0), \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",
          "InitialAccess"
        ],
        "techniques": [
          "T1110",
          "T1133",
          "T1556",
          "T1557",
          "T1606"
        ],
        "templateVersion": "1.0.3",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}