Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"Name": "GoogleCloudSCC",
"Properties": [
{
"Name": "TimeGenerated",
"Type": "DateTime"
},
{
"Name": "TenantId",
"Type": "String"
},
{
"Name": "Findings",
"Type": "Dynamic"
},
{
"Name": "FindingsResource",
"Type": "Dynamic"
},
{
"Name": "SourceProperties",
"Type": "Dynamic"
},
{
"Name": "SourceSystem",
"Type": "String"
},
{
"Name": "Type",
"Type": "String"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
"Fortinet",
"FortiWeb",
"GCPDNSDataConnector",
"GoogleSCCDefinition",
"GWorkspaceRAPI",
"GoogleWorkspaceReportsAPI",
"GreyNoise2SentinelAPI",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
id: d8e30113-373a-4f49-a0ad-1a5d8b95b729
name: GCP Security Command Center - Detect Open/Unrestricted API Keys
description: |
Detects Google Cloud projects that have API keys with unrestricted API access using Security Command Center API_KEY_APIS_UNRESTRICTED findings.
These findings indicate API keys that are not restricted to specific APIs and may allow broader access than intended.
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: GoogleSCCDefinition
dataTypes:
- GoogleCloudSCC
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
- CredentialAccess
relevantTechniques:
- T1190
- T1552
tags:
- CIS GCP Foundation 3.0 1.14
- NIST 800-53 R5 PL-8, SA-8
- PCI-DSS v4.0 2.2.2, 6.2.1
- ISO-27001 v2022 A.8.27
- Cloud Controls Matrix 4 DSP-07
- NIST Cybersecurity Framework 1.0 PR-IP-2
- CIS Controls 8.0 16.10
query: |
GoogleCloudSCC
| where tostring(Findings.state) == "ACTIVE"
| extend FindingCategory = tostring(Findings.category)
| where FindingCategory == "API_KEY_APIS_UNRESTRICTED"
| extend FindingsJson = parse_json(Findings), FindingsResourceJson = parse_json(FindingsResource)
| extend ResourceName = tostring(FindingsJson.resourceName)
| extend ProjectId = extract(@"projects/([^/]+)", 1, ResourceName)
| extend ProjectName = tostring(FindingsResourceJson.displayName)
| extend Severity = tostring(FindingsJson.severity),
FindingName = tostring(FindingsJson.name),
ExternalUri = tostring(FindingsJson.externalUri),
Description = tostring(FindingsJson.description)
// produce one row per project that has unrestricted API key findings
| summarize TimeGenerated = max(TimeGenerated),
FindingsCount = count(),
ExternalUri = any(ExternalUri),
Description = any(Description)
by ProjectId, ProjectName, Severity, ResourceName
| project TimeGenerated, ProjectId, ProjectName, ResourceName, Severity, ExternalUri, Description
entityMappings:
- entityType: CloudApplication
fieldMappings:
- identifier: Name
columnName: ProjectName
- identifier: AppId
columnName: ProjectId
customDetails:
ResourceName: ResourceName
ExternalUri: ExternalUri
Description: Description
alertDetailsOverride:
alertDisplayNameFormat: "GCP project {{ProjectName}} has unrestricted API key(s)"
alertDescriptionFormat: |-
Project {{ProjectName}} ({{ProjectId}}) has {{ResourceName}} with unrestricted API keys (API_KEY_APIS_UNRESTRICTED). Review API key restrictions, rotate or remove keys as appropriate, and apply API restrictions to keys.
version: 1.0.0
kind: Scheduled
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
id: 395f3ced-3923-4b83-b05d-8d077fd48c1e
name: GCP Security Command Center - Detect projects with API Keys present
description: |
Detects Google Cloud projects that have API Keys present using Security Command Center API_KEY_EXISTS findings.
Projects with API Keys may expose credentials that enable unauthorized access if keys are leaked.
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: GoogleSCCDefinition
dataTypes:
- GoogleCloudSCC
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
relevantTechniques:
- T1552
tags:
- CIS GCP Foundation 3.0 1.12
- NIST 800-53 R5 PL-8, SA-8
- PCI-DSS v4.0 2.2.2, 6.2.1
- ISO-27001 v2022 A.8.27
- Cloud Controls Matrix 4 DSP-07
- NIST Cybersecurity Framework 1.0 PR-IP-2
- CIS Controls 8.0 16.10
query: |
GoogleCloudSCC
| where tostring(Findings.state) == "ACTIVE"
| extend FindingCategory = tostring(Findings.category)
| where FindingCategory == "API_KEY_EXISTS"
| extend FindingsJson = parse_json(Findings), FindingsResourceJson = parse_json(FindingsResource)
| extend ResourceName = tostring(FindingsJson.resourceName)
| extend ProjectId = extract(@"projects/([^/]+)", 1, ResourceName)
| extend ProjectName = tostring(FindingsResourceJson.displayName)
| extend Severity = tostring(FindingsJson.severity),
FindingName = tostring(FindingsJson.name),
ExternalUri = tostring(FindingsJson.externalUri),
Description = tostring(FindingsJson.description)
// Produce one row per project with an API key finding
| summarize TimeGenerated = max(TimeGenerated),
FindingsCount = count(),
ExternalUri = any(ExternalUri),
Description = any(Description)
by ProjectId, ProjectName, Severity, ResourceName
| project TimeGenerated, ProjectId, ProjectName, ResourceName, FindingsCount, Severity, ExternalUri, Description
entityMappings:
- entityType: CloudApplication
fieldMappings:
- identifier: Name
columnName: ProjectName
- identifier: AppId
columnName: ProjectId
customDetails:
ProjectId: ProjectId
ProjectName: ProjectName
FindingsCount: FindingsCount
SampleExternalUri: ExternalUri
SampleDescription: Description
alertDetailsOverride:
alertDisplayNameFormat: "GCP project {{ProjectName}} has API key(s) present"
alertDescriptionFormat: |-
Project {{ProjectName}} ({{ProjectId}}) has {{FindingsCount}} API key finding(s). Review API keys and consider rotating or removing keys and using IAM-based authentication.
version: 1.0.0
kind: Scheduled
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
id: a9c7a4be-b7e7-4045-8028-0d1ffaa049af
name: GCP Security Command Center - Detect DNSSEC disabled for DNS zones
description: |
Detects Google Cloud DNS zones where DNSSEC is disabled using Security Command Center findings (DNSSEC_DISABLED).
Disabling DNSSEC increases risk of DNS hijacking and man-in-the-middle attacks. This analytic rule alerts on findings where DNSSEC is reported as disabled for a managed zone.
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: GoogleSCCDefinition
dataTypes:
- GoogleCloudSCC
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- Collection
- CommandAndControl
- DefenseEvasion
relevantTechniques:
- T1557
- T1071.004
- T1562.001
tags:
- CIS GCP Foundation 3.0 3.3
- NIST 800-53 R5 AC-18, CM-2, CM-6, CM-7, CM-9
- PCI-DSS v4.0 1.1.1, 1.2.1, 1.2.6, 1.2.7, 1.4.2, 1.5.1, 2.1.1, 2.2.1
- ISO-27001 v2022 A.8.9
- Cloud Controls Matrix 4 IVS-04
- NIST Cybersecurity Framework 1.0 PR-IP-1
- SOC2 v2017 CC5.2.2
- CIS Controls 8.0 4.2
query: |
GoogleCloudSCC
| where tostring(Findings.state) == "ACTIVE"
| extend FindingsJson = parse_json(Findings)
| extend FindingCategory = tostring(FindingsJson.category)
| where FindingCategory == "DNSSEC_DISABLED"
| extend ResourceName = tostring(FindingsJson.resourceName)
| extend
ResourceType = tostring(FindingsResource.type),
ExternalUri = tostring(FindingsJson.externalUri),
SourceProps = parse_json(tostring(FindingsJson.sourceProperties)),
GcpResource = parse_json(tostring(FindingsJson.resource))
// Extract project and managed zone from resourceName like //dns.googleapis.com/projects/PROJECT/managedZones/ZONE
| extend ProjectName = extract(@"projects/([^/]+)", 1, ResourceName)
| extend ManagedZone = extract(@"managedZones/([^/]+)", 1, ResourceName)
| extend Severity = tostring(FindingsJson.severity)
| summarize
TimeGenerated = max(TimeGenerated)
by ProjectName, ManagedZone, ResourceType, ResourceName, Severity, ExternalUri
entityMappings:
- entityType: CloudApplication
fieldMappings:
- identifier: Name
columnName: ResourceName
customDetails:
ProjectName: ProjectName
ManagedZone: ManagedZone
ExternalUri: ExternalUri
alertDetailsOverride:
alertDisplayNameFormat: "GCP DNS zone {{ManagedZone}} has DNSSEC disabled"
alertDescriptionFormat: |-
DNSSEC is disabled for managed zone {{ManagedZone}} in project {{ProjectName}}. Review the zone configuration and enable DNSSEC where appropriate.
version: 1.0.0
kind: Scheduled
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
id: f4f92ca4-6ebe-4f2a-90e5-b0d04b709651
name: GCP Security Command Center - Detect Firewall rules allowing unrestricted high-risk ports
description: |
This query detects GCP Firewall rules that allow unrestricted (0.0.0.0/0) ingress to high-risk ports using Google Cloud Security Command Center OPEN_FIREWALL findings.
Publicly exposed management, database, and service ports (e.g., RDP 3389, SSH 22, SQL 1433/3306) significantly increase the risk of brute-force attacks, exploitation, and lateral movement.
severity: High
status: Available
requiredDataConnectors:
- connectorId: GoogleSCCDefinition
dataTypes:
- GoogleCloudSCC
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
- LateralMovement
- Discovery
relevantTechniques:
- T1133
- T1021
- T1046
tags:
- PCI-DSS v3.2.1 1.2.1
query: |
let HighRiskPorts = dynamic([3389,20,23,110,143,3306,8080,1433,9200,9300,25,445,135,21,1434,4333,5432,5500,5601,22,3000,5000,8088,8888]);
GoogleCloudSCC
| where tostring(Findings.state) == "ACTIVE"
| extend FindingCategory = tostring(Findings.category)
| where FindingCategory == "OPEN_FIREWALL"
| extend FindingsJson = parse_json(Findings)
| extend SourcePropertiesJson = parse_json(tostring(FindingsJson.sourceProperties))
| extend IpRulesJson = parse_json(tostring(FindingsJson.ipRules))
| where tostring(FindingsJson.state) == "ACTIVE"
| where tostring(SourcePropertiesJson.ExternalSourceRanges) contains "0.0.0.0/0"
| extend AllowedIpRules = parse_json(tostring(IpRulesJson.allowed.ipRules))
| mv-expand IpRule = AllowedIpRules
| extend PortRanges = parse_json(tostring(IpRule.portRanges))
| mv-expand PortRange = PortRanges
| extend MinPort = toint(PortRange.min), MaxPort = toint(PortRange.max)
| where MinPort in (HighRiskPorts) or MaxPort in (HighRiskPorts)
| extend
ResourceName = tostring(FindingsJson.resourceName),
FindingName = tostring(FindingsJson.name),
Protocol = tostring(IpRule.protocol),
Severity = tostring(FindingsJson.severity),
Description = tostring(FindingsJson.description),
ExternalUri = tostring(FindingsJson.externalUri),
AttackExposureScore = todouble(FindingsJson.attackExposure.score),
ProjectName = extract(@"projects/([^/]+)", 1, tostring(FindingsJson.resourceName)),
FirewallName = extract(@"firewalls/([^/]+)", 1, tostring(FindingsJson.resourceName))
| extend PortInfo = case(
MinPort == MaxPort, tostring(MinPort),
strcat(tostring(MinPort), "-", tostring(MaxPort))
)
| summarize
TimeGenerated = max(TimeGenerated),
OpenHighRiskPorts = make_set(PortInfo),
Protocols = make_set(Protocol),
AttackExposureScore = max(AttackExposureScore)
by ProjectName, FirewallName, ResourceName, FindingName, Severity, Description, ExternalUri
| extend OpenHighRiskPorts = strcat_array(OpenHighRiskPorts, ", ")
| extend Protocols = strcat_array(Protocols, ", ")
entityMappings:
- entityType: CloudApplication
fieldMappings:
- identifier: Name
columnName: ResourceName
customDetails:
ProjectName: ProjectName
FirewallName: FirewallName
FindingId: FindingName
OpenHighRiskPorts: OpenHighRiskPorts
Protocols: Protocols
AttackExposureScore: AttackExposureScore
ExternalUri: ExternalUri
alertDetailsOverride:
alertDisplayNameFormat: "GCP Firewall {{FirewallName}} allows unrestricted high-risk ports"
alertDescriptionFormat: |-
GCP Firewall {{FirewallName}} in project {{ProjectName}} allows unrestricted (0.0.0.0/0) ingress to high-risk ports: {{OpenHighRiskPorts}}.
version: 1.0.0
kind: Scheduled
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
id: d1fe8d30-4852-463a-b6ee-3b459788b75d
name: GCP Security Command Center - Detect Resources with Logging Disabled
description: |
Detects Google Cloud resources where logging is disabled for services like (Cloud Storage buckets, Firewall rules, Cloud DNS networks) based on Google Cloud Security Command Center findings.
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: GoogleSCCDefinition
dataTypes:
- GoogleCloudSCC
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- DefenseEvasion
relevantTechniques:
- T1562
tags:
- Logging
- GCP
query: |
GoogleCloudSCC
| where tostring(Findings.state) == "ACTIVE"
| extend FindingCategory = tostring(Findings.category)
| where FindingCategory in ("BUCKET_LOGGING_DISABLED", "FIREWALL_RULE_LOGGING_DISABLED", "DNS_LOGGING_DISABLED")
| extend FindingsJson = parse_json(Findings)
| extend Resource = tostring(FindingsJson.resourceName),
ExternalUri = tostring(FindingsJson.externalUri),
Description = tostring(FindingsJson.description),
Severity = tostring(FindingsJson.severity),
ProjectName = extract(@"projects/([^/]+)", 1, tostring(FindingsJson.resourceName)),
ResourceType = extract(@"//([a-z0-9_.-]+)/", 1, tostring(FindingsJson.resourceName)),
SourceProps = parse_json(tostring(FindingsJson.sourceProperties))
// Normalize display-friendly resource id
| extend ResourceName = case(
Resource contains "firewalls/", extract(@"firewalls/([^/]+)", 1, Resource),
Resource contains "storage.googleapis.com/", extract(@'storage.googleapis.com/([^/\"]+)', 1, Resource),
Resource contains "networks/", extract(@"networks/([^/]+)", 1, Resource),
Resource
)
| project TimeGenerated, ProjectName, ResourceType, ResourceName, Resource, FindingCategory, Severity, ExternalUri, Description
entityMappings:
- entityType: CloudApplication
fieldMappings:
- identifier: Name
columnName: ResourceName
customDetails:
ProjectName: ProjectName
ResourceType: ResourceType
FindingCategory: FindingCategory
ExternalUri: ExternalUri
Description: Description
Severity: Severity
eventGroupingSettings:
aggregationKind: AlertPerResult
alertDetailsOverride:
alertDisplayNameFormat: "GCP resources with logging disabled: {{ProjectName}} ({{ResourceType}})"
alertDescriptionFormat: |-
Resource {{ResourceName}} in project {{ProjectName}} (type: {{ResourceType}}) has logging disabled.
version: 1.0.0
kind: Scheduled
Loading
Loading