Unauthorized user access across AWS and Azure
Id | 60f31001-018a-42bf-8045-a92e1f361b7b |
Rulename | Unauthorized 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. |
Severity | Medium |
Tactics | CredentialAccess Exfiltration Discovery |
Techniques | T1557 T1110 T1110.003 T1110.004 T1212 T1048 T1087 T1580 |
Required data connectors | AWSS3 AzureActiveDirectory |
Kind | Scheduled |
Query frequency | 1d |
Query period | 1d |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | 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 |
Version | 1.0.4 |
Arm template | 60f31001-018a-42bf-8045-a92e1f361b7b.json |
// 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
severity: Medium
relevantTechniques:
- T1557
- T1110
- T1110.003
- T1110.004
- T1212
- T1048
- T1087
- T1580
customDetails:
AzConditionalAccess: ConditionalAccessStatus
AWSAPICallCount: APICallCount
alertSeverity: Severity
AzureUser: UserPrincipalName
AzureUserAgent: UserAgent
AzureOperationName: OperationName
AWSArn: Arn
AWSInstanceType: InstanceType
AWSAPICallName: APICallName
AzureClientAppUsed: ClientAppUsed
AzAuthRequirement: AuthenticationRequirement
AzureRiskDetail: RiskDetail
AWSresourceType: AWSresourceType
AWSAlertUserName: AWSAlertUserNameEntity
queryFrequency: 1d
kind: Scheduled
version: 1.0.4
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.'
queryPeriod: 1d
id: 60f31001-018a-42bf-8045-a92e1f361b7b
alertDetailsOverride:
alertSeverityColumnName: Severity
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}}'
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
entityMappings:
- entityType: IP
fieldMappings:
- columnName: IPAddress
identifier: Address
- entityType: Account
fieldMappings:
- columnName: UserPrincipalName
identifier: FullName
- columnName: Name
identifier: Name
- columnName: UPNSuffix
identifier: UPNSuffix
tactics:
- CredentialAccess
- Exfiltration
- Discovery
name: Unauthorized user access across AWS and Azure
triggerThreshold: 0
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
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
requiredDataConnectors:
- dataTypes:
- SigninLogs
connectorId: AzureActiveDirectory
- dataTypes:
- AWSGuardDuty
connectorId: AWSS3
{
"$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": "'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",
"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"
}
]
}