Cross-Cloud Suspicious Compute resource creation in GCP
Id | 5c847e47-0a07-4c01-ab99-5817ad6cb11e |
Rulename | Cross-Cloud Suspicious Compute resource creation in GCP |
Description | This detection identifies potential suspicious activity across multi-cloud environments by combining AWS GuardDuty findings with GCP Audit Logs. It focuses on AWS activities related to unauthorized access, credential abuse, and unusual behaviors, as well as GCP instances creation with non-Google service account users. The query aims to provide a comprehensive view of cross-cloud security incidents for proactive threat detection and response. |
Severity | Low |
Tactics | InitialAccess Execution Persistence PrivilegeEscalation CredentialAccess Discovery LateralMovement |
Techniques | T1566 T1059 T1078 T1547 T1548 T1069 T1552 |
Required data connectors | AWSS3 GCPAuditLogsDefinition |
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/Cross-CloudSuspiciousComputeResourcecreationinGCP.yaml |
Version | 1.0.2 |
Arm template | 5c847e47-0a07-4c01-ab99-5817ad6cb11e.json |
// Materialize AWS GuardDuty findings
let AwsAlert = materialize (
AWSGuardDuty
// Filter for specific activity types in AWS GuardDuty
| where ActivityType has_any (
"Backdoor:EC2/DenialOfService.UnusualProtocol",
"CredentialAccess:Kubernetes/MaliciousIPCaller",
"CredentialAccess:Kubernetes/SuccessfulAnonymousAccess",
"CredentialAccess:Kubernetes/TorIPCaller",
"CredentialAccess:RDS/AnomalousBehavior.SuccessfulBruteForce",
"CredentialAccess:RDS/TorIPCaller.FailedLogin",
"CredentialAccess:RDS/TorIPCaller.SuccessfulLogin",
"Discovery:Kubernetes/MaliciousIPCaller",
"Recon:IAMUser/MaliciousIPCaller.Custom",
"UnauthorizedAccess:EC2/TorClient",
"UnauthorizedAccess:IAMUser/TorIPCaller",
"UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom",
"UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS",
"UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.InsideAWS",
"UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B"
)
// Extract and transform AWS GuardDuty attributes
| 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"
)
// Extract API call details and count
| mv-apply AIPCall = AWSTargetingService on
(
where AIPCall has "name"
| extend APICallName = tostring(AIPCall.name), APICallCount = tostring(AIPCall["count"])
)
// Select distinct attributes for further analysis
| distinct
AWSAlertTime,
ActivityType,
Severity,
AWSAlertId,
AWSAlertTitle,
AWSAlertDescription,
AWSAlertLink,
Arn,
AWSresourceType,
AWSNetworkEntity,
AWSAlertUserNameEntity,
InstanceType,
APICallName,
APICallCount
);
// Materialize GCP Audit Logs related to VM instance creation
let GCPVMActivity= materialize(
GCPAuditLogs
// Filter for Compute Engine instances insertions
| where ServiceName == "compute.googleapis.com" and MethodName endswith "instances.insert"
// Extract and transform relevant GCP Audit Log attributes
| extend
GCPUserUPN= tostring(parse_json(AuthenticationInfo).principalEmail),
GCPUserIp = tostring(parse_json(RequestMetadata).callerIp),
GCPUserUA= tostring(parse_json(RequestMetadata).callerSuppliedUserAgent),
VMDetails= parse_json(AuthorizationInfo),
VMStatus = tostring(parse_json(Response).status),
VMOperation=tostring(parse_json(Response).operationType),
VMName= tostring(parse_json(Request).name),
VMDescription= tostring(parse_json(Request).description),
VMType = tostring(split(parse_json(Request).machineType, "/")[-1]),
Tags= tostring(parse_json(Request).tags),
RequestJS = parse_json(Request)
// Filter out service account-related activities and private IP addresses
| where GCPUserUPN !has "gserviceaccount.com"
| extend Name = tostring(split(GCPUserUPN, "@")[0]), UPNSuffix = tostring(split(GCPUserUPN, "@")[1])
| where VMOperation == "insert" and isnotempty(GCPUserIp) and GCPUserIp != "private"
// Select relevant attributes for further analysis
| project
GCPOperationTime=TimeGenerated,
VMName,
VMStatus,
MethodName,
GCPUserUPN,
ProjectId,
GCPUserIp,
GCPUserUA,
VMOperation,
VMType,
Name,
UPNSuffix
);
// Join AWS and GCP activities based on matching IP addresses
AwsAlert
| join kind= inner (GCPVMActivity)
on
$left.AWSNetworkEntity == $right.GCPUserIp
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: GCPUserIp
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: GCPUserUPN
- identifier: Name
columnName: Name
- identifier: UPNSuffix
columnName: UPNSuffix
queryFrequency: 1d
name: Cross-Cloud Suspicious Compute resource creation in GCP
severity: Low
kind: Scheduled
tactics:
- InitialAccess
- Execution
- Persistence
- PrivilegeEscalation
- CredentialAccess
- Discovery
- LateralMovement
triggerThreshold: 0
query: |
// Materialize AWS GuardDuty findings
let AwsAlert = materialize (
AWSGuardDuty
// Filter for specific activity types in AWS GuardDuty
| where ActivityType has_any (
"Backdoor:EC2/DenialOfService.UnusualProtocol",
"CredentialAccess:Kubernetes/MaliciousIPCaller",
"CredentialAccess:Kubernetes/SuccessfulAnonymousAccess",
"CredentialAccess:Kubernetes/TorIPCaller",
"CredentialAccess:RDS/AnomalousBehavior.SuccessfulBruteForce",
"CredentialAccess:RDS/TorIPCaller.FailedLogin",
"CredentialAccess:RDS/TorIPCaller.SuccessfulLogin",
"Discovery:Kubernetes/MaliciousIPCaller",
"Recon:IAMUser/MaliciousIPCaller.Custom",
"UnauthorizedAccess:EC2/TorClient",
"UnauthorizedAccess:IAMUser/TorIPCaller",
"UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom",
"UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS",
"UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.InsideAWS",
"UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B"
)
// Extract and transform AWS GuardDuty attributes
| 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"
)
// Extract API call details and count
| mv-apply AIPCall = AWSTargetingService on
(
where AIPCall has "name"
| extend APICallName = tostring(AIPCall.name), APICallCount = tostring(AIPCall["count"])
)
// Select distinct attributes for further analysis
| distinct
AWSAlertTime,
ActivityType,
Severity,
AWSAlertId,
AWSAlertTitle,
AWSAlertDescription,
AWSAlertLink,
Arn,
AWSresourceType,
AWSNetworkEntity,
AWSAlertUserNameEntity,
InstanceType,
APICallName,
APICallCount
);
// Materialize GCP Audit Logs related to VM instance creation
let GCPVMActivity= materialize(
GCPAuditLogs
// Filter for Compute Engine instances insertions
| where ServiceName == "compute.googleapis.com" and MethodName endswith "instances.insert"
// Extract and transform relevant GCP Audit Log attributes
| extend
GCPUserUPN= tostring(parse_json(AuthenticationInfo).principalEmail),
GCPUserIp = tostring(parse_json(RequestMetadata).callerIp),
GCPUserUA= tostring(parse_json(RequestMetadata).callerSuppliedUserAgent),
VMDetails= parse_json(AuthorizationInfo),
VMStatus = tostring(parse_json(Response).status),
VMOperation=tostring(parse_json(Response).operationType),
VMName= tostring(parse_json(Request).name),
VMDescription= tostring(parse_json(Request).description),
VMType = tostring(split(parse_json(Request).machineType, "/")[-1]),
Tags= tostring(parse_json(Request).tags),
RequestJS = parse_json(Request)
// Filter out service account-related activities and private IP addresses
| where GCPUserUPN !has "gserviceaccount.com"
| extend Name = tostring(split(GCPUserUPN, "@")[0]), UPNSuffix = tostring(split(GCPUserUPN, "@")[1])
| where VMOperation == "insert" and isnotempty(GCPUserIp) and GCPUserIp != "private"
// Select relevant attributes for further analysis
| project
GCPOperationTime=TimeGenerated,
VMName,
VMStatus,
MethodName,
GCPUserUPN,
ProjectId,
GCPUserIp,
GCPUserUA,
VMOperation,
VMType,
Name,
UPNSuffix
);
// Join AWS and GCP activities based on matching IP addresses
AwsAlert
| join kind= inner (GCPVMActivity)
on
$left.AWSNetworkEntity == $right.GCPUserIp
triggerOperator: gt
customDetails:
GCPProjectId: ProjectId
AWSAPICallCount: APICallCount
AWSArn: Arn
AWSInstanceType: InstanceType
GCPVMType: VMType
CorrelationWith: GCPAuditLogs
AWSAlertUserName: AWSAlertUserNameEntity
GCPUserAgent: GCPUserUA
GCPVMName: VMName
AWSresourceType: AWSresourceType
AWSAPICallName: APICallName
queryPeriod: 1d
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Multi Cloud Attack Coverage Essentials - Resource Abuse/Analytic Rules/Cross-CloudSuspiciousComputeResourcecreationinGCP.yaml
relevantTechniques:
- T1566
- T1059
- T1078
- T1547
- T1548
- T1069
- T1552
alertDetailsOverride:
alertDynamicProperties:
- alertProperty: AlertLink
value: AWSAlertLink
- alertProperty: ProviderName
value: AWS
- alertProperty: ProductComponentName
value: AWSGuarduty
alertDisplayNameFormat: '{{AWSNetworkEntity}} from {{AWSAlertTitle}} observed in GCP compute activity with {{GCPUserUPN}}'
alertDescriptionFormat: |2-
This detection compiles and correlates unauthorized user access alerts originating from AWS GuardDuty With Alert Description '{{AWSAlertDescription}}' assocated with GCP compute 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
alertSeverityColumnName: Severity
id: 5c847e47-0a07-4c01-ab99-5817ad6cb11e
requiredDataConnectors:
- connectorId: GCPAuditLogsDefinition
dataTypes:
- GCPAuditLogs
- connectorId: AWSS3
dataTypes:
- AWSGuardDuty
version: 1.0.2
description: |
'This detection identifies potential suspicious activity across multi-cloud environments by combining AWS GuardDuty findings with GCP Audit Logs. It focuses on AWS activities related to unauthorized access, credential abuse, and unusual behaviors, as well as GCP instances creation with non-Google service account users. The query aims to provide a comprehensive view of cross-cloud security incidents for proactive threat detection and response.'
{
"$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/5c847e47-0a07-4c01-ab99-5817ad6cb11e')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/5c847e47-0a07-4c01-ab99-5817ad6cb11e')]",
"properties": {
"alertDetailsOverride": {
"alertDescriptionFormat": " This detection compiles and correlates unauthorized user access alerts originating from AWS GuardDuty With Alert Description '{{AWSAlertDescription}}' assocated with GCP compute 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 GCP compute activity with {{GCPUserUPN}}",
"alertDynamicProperties": [
{
"alertProperty": "AlertLink",
"value": "AWSAlertLink"
},
{
"alertProperty": "ProviderName",
"value": "AWS"
},
{
"alertProperty": "ProductComponentName",
"value": "AWSGuarduty"
}
],
"alertSeverityColumnName": "Severity"
},
"alertRuleTemplateName": "5c847e47-0a07-4c01-ab99-5817ad6cb11e",
"customDetails": {
"AWSAlertUserName": "AWSAlertUserNameEntity",
"AWSAPICallCount": "APICallCount",
"AWSAPICallName": "APICallName",
"AWSArn": "Arn",
"AWSInstanceType": "InstanceType",
"AWSresourceType": "AWSresourceType",
"CorrelationWith": "GCPAuditLogs",
"GCPProjectId": "ProjectId",
"GCPUserAgent": "GCPUserUA",
"GCPVMName": "VMName",
"GCPVMType": "VMType"
},
"description": "'This detection identifies potential suspicious activity across multi-cloud environments by combining AWS GuardDuty findings with GCP Audit Logs. It focuses on AWS activities related to unauthorized access, credential abuse, and unusual behaviors, as well as GCP instances creation with non-Google service account users. The query aims to provide a comprehensive view of cross-cloud security incidents for proactive threat detection and response.'\n",
"displayName": "Cross-Cloud Suspicious Compute resource creation in GCP",
"enabled": true,
"entityMappings": [
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "GCPUserIp",
"identifier": "Address"
}
]
},
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "GCPUserUPN",
"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/Cross-CloudSuspiciousComputeResourcecreationinGCP.yaml",
"query": "// Materialize AWS GuardDuty findings\nlet AwsAlert = materialize (\n AWSGuardDuty\n // Filter for specific activity types in AWS GuardDuty\n | where ActivityType has_any (\n \"Backdoor:EC2/DenialOfService.UnusualProtocol\",\n \"CredentialAccess:Kubernetes/MaliciousIPCaller\",\n \"CredentialAccess:Kubernetes/SuccessfulAnonymousAccess\",\n \"CredentialAccess:Kubernetes/TorIPCaller\",\n \"CredentialAccess:RDS/AnomalousBehavior.SuccessfulBruteForce\",\n \"CredentialAccess:RDS/TorIPCaller.FailedLogin\",\n \"CredentialAccess:RDS/TorIPCaller.SuccessfulLogin\",\n \"Discovery:Kubernetes/MaliciousIPCaller\",\n \"Recon:IAMUser/MaliciousIPCaller.Custom\",\n \"UnauthorizedAccess:EC2/TorClient\",\n \"UnauthorizedAccess:IAMUser/TorIPCaller\",\n \"UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom\",\n \"UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS\",\n \"UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.InsideAWS\",\n \"UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B\"\n )\n // Extract and transform AWS GuardDuty attributes\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,\n \"High\",\n Severity between (4.0 .. 6.9),\n \"Medium\",\n Severity between (1.0 .. 3.9),\n \"Low\",\n \"Unknown\"\n)\n // Extract API call details and count\n | mv-apply AIPCall = AWSTargetingService on \n ( \n where AIPCall has \"name\" \n | extend APICallName = tostring(AIPCall.name), APICallCount = tostring(AIPCall[\"count\"])\n ) \n // Select distinct attributes for further analysis\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// Materialize GCP Audit Logs related to VM instance creation\nlet GCPVMActivity= materialize(\n GCPAuditLogs \n // Filter for Compute Engine instances insertions\n | where ServiceName == \"compute.googleapis.com\" and MethodName endswith \"instances.insert\"\n // Extract and transform relevant GCP Audit Log attributes\n | extend\n GCPUserUPN= tostring(parse_json(AuthenticationInfo).principalEmail),\n GCPUserIp = tostring(parse_json(RequestMetadata).callerIp),\n GCPUserUA= tostring(parse_json(RequestMetadata).callerSuppliedUserAgent),\n VMDetails= parse_json(AuthorizationInfo),\n VMStatus = tostring(parse_json(Response).status),\n VMOperation=tostring(parse_json(Response).operationType),\n VMName= tostring(parse_json(Request).name),\n VMDescription= tostring(parse_json(Request).description),\n VMType = tostring(split(parse_json(Request).machineType, \"/\")[-1]),\n Tags= tostring(parse_json(Request).tags),\n RequestJS = parse_json(Request)\n // Filter out service account-related activities and private IP addresses\n | where GCPUserUPN !has \"gserviceaccount.com\"\n | extend Name = tostring(split(GCPUserUPN, \"@\")[0]), UPNSuffix = tostring(split(GCPUserUPN, \"@\")[1])\n | where VMOperation == \"insert\" and isnotempty(GCPUserIp) and GCPUserIp != \"private\"\n // Select relevant attributes for further analysis\n | project\n GCPOperationTime=TimeGenerated,\n VMName,\n VMStatus,\n MethodName,\n GCPUserUPN,\n ProjectId,\n GCPUserIp,\n GCPUserUA,\n VMOperation,\n VMType,\n Name,\n UPNSuffix\n );\n// Join AWS and GCP activities based on matching IP addresses\nAwsAlert\n| join kind= inner (GCPVMActivity)\n on\n $left.AWSNetworkEntity == $right.GCPUserIp\n",
"queryFrequency": "P1D",
"queryPeriod": "P1D",
"severity": "Low",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"CredentialAccess",
"Discovery",
"Execution",
"InitialAccess",
"LateralMovement",
"Persistence",
"PrivilegeEscalation"
],
"techniques": [
"T1059",
"T1069",
"T1078",
"T1547",
"T1548",
"T1552",
"T1566"
],
"templateVersion": "1.0.2",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}