GCP Audit Logs - Open Firewall Rule Created or Modified
| Id | 8061c611-55f1-4ee5-a8f8-8f19f2c7aab2 |
| Rulename | GCP Audit Logs - Open Firewall Rule Created or Modified |
| Description | Detects when a Google Cloud Platform firewall rule is created or modified to allow traffic from any source (0.0.0.0/0 or 0.0.0.0). Open firewall rules expose resources to the internet and can significantly increase the attack surface of cloud infrastructure. This may indicate a misconfiguration, lack of security awareness, or malicious activity to create backdoor access. Adversaries may create or modify firewall rules to enable persistent access or facilitate lateral movement. This rule monitors firewall insert and patch operations where sourceRanges include unrestricted access patterns. |
| Severity | High |
| Tactics | DefenseEvasion Persistence InitialAccess |
| Techniques | T1562.004 T1133 T1562.001 |
| Required data connectors | GCPAuditLogsDefinition |
| Kind | Scheduled |
| Query frequency | 1h |
| Query period | 1h |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google Cloud Platform Audit Logs/Analytic Rules/GCPOpenFirewallRuleCreated.yaml |
| Version | 1.0.0 |
| Arm template | 8061c611-55f1-4ee5-a8f8-8f19f2c7aab2.json |
GCPAuditLogs
| where ServiceName == "compute.googleapis.com"
| where MethodName has_any ("firewalls.insert", "firewalls.patch")
| where GCPResourceType == "gce_firewall_rule"
| where Severity == "NOTICE"
| extend
RequestJson = parse_json(Request),
RequestMetadataJson = parse_json(RequestMetadata),
AuthInfoJson = parse_json(AuthenticationInfo)
| extend
SourceRanges = RequestJson.sourceRanges,
Alloweds = RequestJson.alloweds,
Direction = tostring(RequestJson.direction),
RuleName = tostring(RequestJson.name),
Network = tostring(RequestJson.network),
Priority = tostring(RequestJson.priority),
LogConfig = RequestJson.logConfig,
Disabled = tobool(RequestJson.disabled)
| mv-expand SourceRange = SourceRanges
| extend SourceRangeStr = tostring(SourceRange)
| where SourceRangeStr in ("0.0.0.0/0", "0.0.0.0")
| extend
FirewallRuleName = extract(@"firewalls/([^/]+)$", 1, GCPResourceName),
CallerIpAddress = tostring(RequestMetadataJson.callerIp),
UserAgent = tostring(RequestMetadataJson.callerSuppliedUserAgent),
AuthEmail = tostring(AuthInfoJson.principalEmail)
| mv-expand Allowed = Alloweds
| extend
AllowedProtocol = tostring(Allowed.IPProtocol),
AllowedPorts = tostring(Allowed.ports),
OperationType = case(
MethodName has "insert", "Created",
MethodName has "patch", "Modified",
"Unknown")
| summarize
AllowedProtocols = make_set(AllowedProtocol, 30),
AllowedPortsList = make_set(AllowedPorts, 100),
SourceRangesList = make_set(SourceRangeStr, 100)
by TimeGenerated, PrincipalEmail, AuthEmail, ProjectId, FirewallRuleName,
GCPResourceName, Direction, Priority, Network, CallerIpAddress, UserAgent,
MethodName, ServiceName, Severity, OperationType, LogName, InsertId
| extend
AccountName = tostring(split(PrincipalEmail, "@")[0]),
AccountUPNSuffix = tostring(split(PrincipalEmail, "@")[1])
| project TimeGenerated,
PrincipalEmail,
AuthEmail,
ProjectId,
FirewallRuleName,
ResourceName = GCPResourceName,
OperationType,
Direction,
SourceRangesList,
AllowedProtocols,
AllowedPortsList,
Priority,
Network,
CallerIpAddress,
UserAgent,
MethodName,
ServiceName,
Severity,
LogName,
InsertId,
AccountName,
AccountUPNSuffix
tags:
- GCP
- Firewall
- Network Security
- Misconfiguration
triggerOperator: gt
tactics:
- DefenseEvasion
- Persistence
- InitialAccess
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google Cloud Platform Audit Logs/Analytic Rules/GCPOpenFirewallRuleCreated.yaml
alertDetailsOverride:
alertDescriptionFormat: |-
User {{PrincipalEmail}} created/modified firewall rule {{FirewallRuleName}} in project {{ProjectId}} to allow traffic from unrestricted sources (0.0.0.0/0).
This configuration exposes resources to the internet and significantly increases attack surface. Investigate immediately to determine if this was authorized and assess potential security exposure. Consider restricting source ranges to specific trusted IP addresses or networks.
alertDisplayNameFormat: GCP Open Firewall Rule {{OperationType}} - {{FirewallRuleName}} by {{PrincipalEmail}}
version: 1.0.0
query: |
GCPAuditLogs
| where ServiceName == "compute.googleapis.com"
| where MethodName has_any ("firewalls.insert", "firewalls.patch")
| where GCPResourceType == "gce_firewall_rule"
| where Severity == "NOTICE"
| extend
RequestJson = parse_json(Request),
RequestMetadataJson = parse_json(RequestMetadata),
AuthInfoJson = parse_json(AuthenticationInfo)
| extend
SourceRanges = RequestJson.sourceRanges,
Alloweds = RequestJson.alloweds,
Direction = tostring(RequestJson.direction),
RuleName = tostring(RequestJson.name),
Network = tostring(RequestJson.network),
Priority = tostring(RequestJson.priority),
LogConfig = RequestJson.logConfig,
Disabled = tobool(RequestJson.disabled)
| mv-expand SourceRange = SourceRanges
| extend SourceRangeStr = tostring(SourceRange)
| where SourceRangeStr in ("0.0.0.0/0", "0.0.0.0")
| extend
FirewallRuleName = extract(@"firewalls/([^/]+)$", 1, GCPResourceName),
CallerIpAddress = tostring(RequestMetadataJson.callerIp),
UserAgent = tostring(RequestMetadataJson.callerSuppliedUserAgent),
AuthEmail = tostring(AuthInfoJson.principalEmail)
| mv-expand Allowed = Alloweds
| extend
AllowedProtocol = tostring(Allowed.IPProtocol),
AllowedPorts = tostring(Allowed.ports),
OperationType = case(
MethodName has "insert", "Created",
MethodName has "patch", "Modified",
"Unknown")
| summarize
AllowedProtocols = make_set(AllowedProtocol, 30),
AllowedPortsList = make_set(AllowedPorts, 100),
SourceRangesList = make_set(SourceRangeStr, 100)
by TimeGenerated, PrincipalEmail, AuthEmail, ProjectId, FirewallRuleName,
GCPResourceName, Direction, Priority, Network, CallerIpAddress, UserAgent,
MethodName, ServiceName, Severity, OperationType, LogName, InsertId
| extend
AccountName = tostring(split(PrincipalEmail, "@")[0]),
AccountUPNSuffix = tostring(split(PrincipalEmail, "@")[1])
| project TimeGenerated,
PrincipalEmail,
AuthEmail,
ProjectId,
FirewallRuleName,
ResourceName = GCPResourceName,
OperationType,
Direction,
SourceRangesList,
AllowedProtocols,
AllowedPortsList,
Priority,
Network,
CallerIpAddress,
UserAgent,
MethodName,
ServiceName,
Severity,
LogName,
InsertId,
AccountName,
AccountUPNSuffix
triggerThreshold: 0
relevantTechniques:
- T1562.004
- T1133
- T1562.001
queryPeriod: 1h
status: Available
severity: High
kind: Scheduled
customDetails:
Network: Network
ProjectId: ProjectId
AllowedPorts: AllowedPortsList
OperationType: OperationType
ResourceName: ResourceName
FirewallRuleName: FirewallRuleName
SourceRanges: SourceRangesList
AllowedProtocols: AllowedProtocols
Direction: Direction
name: GCP Audit Logs - Open Firewall Rule Created or Modified
queryFrequency: 1h
id: 8061c611-55f1-4ee5-a8f8-8f19f2c7aab2
description: |
'Detects when a Google Cloud Platform firewall rule is created or modified to allow traffic from any source (0.0.0.0/0 or 0.0.0.0).
Open firewall rules expose resources to the internet and can significantly increase the attack surface of cloud infrastructure.
This may indicate a misconfiguration, lack of security awareness, or malicious activity to create backdoor access.
Adversaries may create or modify firewall rules to enable persistent access or facilitate lateral movement.
This rule monitors firewall insert and patch operations where sourceRanges include unrestricted access patterns.'
requiredDataConnectors:
- dataTypes:
- GCPAuditLogs
connectorId: GCPAuditLogsDefinition
entityMappings:
- fieldMappings:
- columnName: PrincipalEmail
identifier: FullName
- columnName: AccountName
identifier: Name
- columnName: AccountUPNSuffix
identifier: UPNSuffix
entityType: Account
- fieldMappings:
- columnName: CallerIpAddress
identifier: Address
entityType: IP
- fieldMappings:
- columnName: ProjectId
identifier: Name
- columnName: ResourceName
identifier: InstanceName
entityType: CloudApplication