Microsoft Sentinel medium experimental kql

Cross-Cloud Unauthorized Credential Access Detection From AWS RDS Login

'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.'

View Source

Detection Logic

// 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

Field Validations

Loading…

Comments (0)

Loading comments...