Analytic rule catalog
GCP Audit Logs - Open Firewall Rule Created or Modified
Back
| 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%20Cloud%20Platform%20Audit%20Logs/Analytic%20Rules/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
entityMappings:
- entityType: Account
fieldMappings:
- columnName: PrincipalEmail
identifier: FullName
- columnName: AccountName
identifier: Name
- columnName: AccountUPNSuffix
identifier: UPNSuffix
- entityType: IP
fieldMappings:
- columnName: CallerIpAddress
identifier: Address
- entityType: CloudApplication
fieldMappings:
- columnName: ProjectId
identifier: Name
- columnName: ResourceName
identifier: InstanceName
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
id: 8061c611-55f1-4ee5-a8f8-8f19f2c7aab2
queryFrequency: 1h
alertDetailsOverride:
alertDisplayNameFormat: GCP Open Firewall Rule {{OperationType}} - {{FirewallRuleName}} by {{PrincipalEmail}}
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.
status: Available
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google%20Cloud%20Platform%20Audit%20Logs/Analytic%20Rules/GCPOpenFirewallRuleCreated.yaml
version: 1.0.0
severity: High
relevantTechniques:
- T1562.004
- T1133
- T1562.001
name: GCP Audit Logs - Open Firewall Rule Created or Modified
tags:
- GCP
- Firewall
- Network Security
- Misconfiguration
kind: Scheduled
tactics:
- DefenseEvasion
- Persistence
- InitialAccess
requiredDataConnectors:
- dataTypes:
- GCPAuditLogs
connectorId: GCPAuditLogsDefinition
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.'
customDetails:
Direction: Direction
FirewallRuleName: FirewallRuleName
OperationType: OperationType
ResourceName: ResourceName
AllowedPorts: AllowedPortsList
ProjectId: ProjectId
SourceRanges: SourceRangesList
Network: Network
AllowedProtocols: AllowedProtocols
triggerOperator: gt
triggerThreshold: 0
queryPeriod: 1h
{
"$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/8061c611-55f1-4ee5-a8f8-8f19f2c7aab2')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/8061c611-55f1-4ee5-a8f8-8f19f2c7aab2')]",
"properties": {
"alertDetailsOverride": {
"alertDescriptionFormat": "User {{PrincipalEmail}} created/modified firewall rule {{FirewallRuleName}} in project {{ProjectId}} to allow traffic from unrestricted sources (0.0.0.0/0).\nThis 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}}"
},
"alertRuleTemplateName": "8061c611-55f1-4ee5-a8f8-8f19f2c7aab2",
"customDetails": {
"AllowedPorts": "AllowedPortsList",
"AllowedProtocols": "AllowedProtocols",
"Direction": "Direction",
"FirewallRuleName": "FirewallRuleName",
"Network": "Network",
"OperationType": "OperationType",
"ProjectId": "ProjectId",
"ResourceName": "ResourceName",
"SourceRanges": "SourceRangesList"
},
"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).\nOpen firewall rules expose resources to the internet and can significantly increase the attack surface of cloud infrastructure.\nThis may indicate a misconfiguration, lack of security awareness, or malicious activity to create backdoor access.\nAdversaries may create or modify firewall rules to enable persistent access or facilitate lateral movement.\nThis rule monitors firewall insert and patch operations where sourceRanges include unrestricted access patterns.'\n",
"displayName": "GCP Audit Logs - Open Firewall Rule Created or Modified",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "PrincipalEmail",
"identifier": "FullName"
},
{
"columnName": "AccountName",
"identifier": "Name"
},
{
"columnName": "AccountUPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "CallerIpAddress",
"identifier": "Address"
}
]
},
{
"entityType": "CloudApplication",
"fieldMappings": [
{
"columnName": "ProjectId",
"identifier": "Name"
},
{
"columnName": "ResourceName",
"identifier": "InstanceName"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google%20Cloud%20Platform%20Audit%20Logs/Analytic%20Rules/GCPOpenFirewallRuleCreated.yaml",
"query": "GCPAuditLogs\n| where ServiceName == \"compute.googleapis.com\"\n| where MethodName has_any (\"firewalls.insert\", \"firewalls.patch\")\n| where GCPResourceType == \"gce_firewall_rule\"\n| where Severity == \"NOTICE\"\n| extend \n RequestJson = parse_json(Request),\n RequestMetadataJson = parse_json(RequestMetadata),\n AuthInfoJson = parse_json(AuthenticationInfo)\n| extend \n SourceRanges = RequestJson.sourceRanges,\n Alloweds = RequestJson.alloweds,\n Direction = tostring(RequestJson.direction),\n RuleName = tostring(RequestJson.name),\n Network = tostring(RequestJson.network),\n Priority = tostring(RequestJson.priority),\n LogConfig = RequestJson.logConfig,\n Disabled = tobool(RequestJson.disabled)\n| mv-expand SourceRange = SourceRanges\n| extend SourceRangeStr = tostring(SourceRange)\n| where SourceRangeStr in (\"0.0.0.0/0\", \"0.0.0.0\")\n| extend \n FirewallRuleName = extract(@\"firewalls/([^/]+)$\", 1, GCPResourceName),\n CallerIpAddress = tostring(RequestMetadataJson.callerIp),\n UserAgent = tostring(RequestMetadataJson.callerSuppliedUserAgent),\n AuthEmail = tostring(AuthInfoJson.principalEmail)\n| mv-expand Allowed = Alloweds\n| extend \n AllowedProtocol = tostring(Allowed.IPProtocol),\n AllowedPorts = tostring(Allowed.ports),\n OperationType = case(\n MethodName has \"insert\", \"Created\",\n MethodName has \"patch\", \"Modified\",\n \"Unknown\")\n| summarize \n AllowedProtocols = make_set(AllowedProtocol, 30),\n AllowedPortsList = make_set(AllowedPorts, 100),\n SourceRangesList = make_set(SourceRangeStr, 100)\n by TimeGenerated, PrincipalEmail, AuthEmail, ProjectId, FirewallRuleName, \n GCPResourceName, Direction, Priority, Network, CallerIpAddress, UserAgent, \n MethodName, ServiceName, Severity, OperationType, LogName, InsertId\n| extend\n AccountName = tostring(split(PrincipalEmail, \"@\")[0]), \n AccountUPNSuffix = tostring(split(PrincipalEmail, \"@\")[1])\n| project TimeGenerated,\n PrincipalEmail,\n AuthEmail,\n ProjectId,\n FirewallRuleName,\n ResourceName = GCPResourceName,\n OperationType,\n Direction,\n SourceRangesList,\n AllowedProtocols,\n AllowedPortsList,\n Priority,\n Network,\n CallerIpAddress,\n UserAgent,\n MethodName,\n ServiceName,\n Severity,\n LogName,\n InsertId,\n AccountName,\n AccountUPNSuffix\n",
"queryFrequency": "PT1H",
"queryPeriod": "PT1H",
"severity": "High",
"status": "Available",
"subTechniques": [
"T1562.004",
"T1562.001"
],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"DefenseEvasion",
"InitialAccess",
"Persistence"
],
"tags": [
"GCP",
"Firewall",
"Network Security",
"Misconfiguration"
],
"techniques": [
"T1133",
"T1562"
],
"templateVersion": "1.0.0",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}