Detection rules › Panther
GCP Workforce Pool Created or Updated
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence | T1098.003 Account Manipulation: Additional Cloud Roles, T1136.003 Create Account: Cloud Account |
| Privilege Escalation | T1098.003 Account Manipulation: Additional Cloud Roles |
Rule body yaml
AnalysisType: rule
Filename: gcp_workforce_pool_created_or_updated.py
RuleID: "GCP.Workforce.Pool.Created.or.Updated"
DisplayName: "GCP Workforce Pool Created or Updated"
Enabled: true
LogTypes:
- GCP.AuditLog
Tags:
- Account Manipulation
- Additional Cloud Roles
- GCP
- Privilege Escalation
Reports:
MITRE ATT&CK:
- TA0003:T1136.003
- TA0003:T1098.003
- TA0004:T1098.003
Severity: High
DedupPeriodMinutes: 60
Threshold: 1
Runbook: >
Ensure that the Workforce Pool creation or modification was expected. Adversaries may use this to persist or allow additional access or escalate their privilege.
Reference: https://medium.com/google-cloud/detection-of-inbound-sso-persistence-techniques-in-gcp-c56f7b2a588b
Tests:
- Name: DeleteWorkforcePool-False
ExpectedResult: false
Log:
insertId: 1plwiv7e2lay7
logName: organizations/123456789012/logs/cloudaudit.googleapis.com%2Factivity
operation:
first: true
id: locations/global/workforcePools/test-pool/operations/bigar3hp32vamefaukfkaaq000000000
producer: iam.googleapis.com
protoPayload:
"@type": type.googleapis.com/google.cloud.audit.AuditLog
authenticationInfo:
principalEmail: user@example.com
authorizationInfo:
- granted: true
permission: iam.workforcePools.delete
resource: locations/global/workforcePools/test-pool
resourceAttributes: {}
methodName: google.iam.admin.v1.WorkforcePools.DeleteWorkforcePool
request:
"@type": type.googleapis.com/google.iam.admin.v1.DeleteWorkforcePoolRequest
name: locations/global/workforcePools/test-pool
requestMetadata:
callerIp: 07da:0994:97fb:8db1:c68f:c109:fcdd:d594
callerSuppliedUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/119.0,gzip(gfe),gzip(gfe)
destinationAttributes: {}
requestAttributes:
auth: {}
reason: 8uSywAYQGg5Db2xpc2V1bSBGbG93cw
time: "2023-11-17T18:58:52.165673889Z"
resourceName: locations/global/workforcePools/test-pool
serviceName: iam.googleapis.com
receiveTimestamp: "2023-11-17T18:58:52.901258022Z"
resource:
labels:
method: google.iam.admin.v1.WorkforcePools.DeleteWorkforcePool
service: iam.googleapis.com
type: audited_resource
severity: NOTICE
timestamp: "2023-11-17T18:58:52.158942930Z"
- Name: UpdateWorkforcePool-True
ExpectedResult: true
Log:
insertId: 1h09dxwe33hgu
logName: organizations/123456789012/logs/cloudaudit.googleapis.com%2Factivity
operation:
first: true
id: locations/global/workforcePools/test-pool/operations/bigarg7n32vamefy6ximiaq000000000
producer: iam.googleapis.com
protoPayload:
"@type": type.googleapis.com/google.cloud.audit.AuditLog
authenticationInfo:
principalEmail: user@example.com
authorizationInfo:
- granted: true
permission: iam.workforcePools.update
resource: locations/global/workforcePools/test-pool
resourceAttributes: {}
methodName: google.iam.admin.v1.WorkforcePools.UpdateWorkforcePool
request:
"@type": type.googleapis.com/google.iam.admin.v1.UpdateWorkforcePoolRequest
updateMask: description,sessionDuration,disabled,displayName
workforcePool:
description: Test pool to facilitate detection writing
displayName: Test Pool
name: locations/global/workforcePools/test-pool
sessionDuration: 43200s
requestMetadata:
callerIp: 07da:0994:97fb:8db1:c68f:c109:fcdd:d594
callerSuppliedUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/119.0,gzip(gfe),gzip(gfe)
destinationAttributes: {}
requestAttributes:
auth: {}
reason: 8uSywAYQGg5Db2xpc2V1bSBGbG93cw
time: "2023-11-17T18:53:15.208909504Z"
resourceName: locations/global/workforcePools/test-pool
serviceName: iam.googleapis.com
receiveTimestamp: "2023-11-17T18:53:16.523653141Z"
resource:
labels:
method: google.iam.admin.v1.WorkforcePools.UpdateWorkforcePool
service: iam.googleapis.com
type: audited_resource
severity: NOTICE
timestamp: "2023-11-17T18:53:15.200613481Z"
- Name: CreateWorkforcePool-True
ExpectedResult: true
Log:
insertId: 6432zre32u1v
logName: organizations/123456789012/logs/cloudaudit.googleapis.com%2Factivity
operation:
first: true
id: locations/global/workforcePools/test-pool/operations/bifqrwxk32vamegiyoqaoeab00000000
producer: iam.googleapis.com
protoPayload:
"@type": type.googleapis.com/google.cloud.audit.AuditLog
authenticationInfo:
principalEmail: user@example.com
authorizationInfo:
- granted: true
permission: iam.workforcePools.create
resource: organizations/123456789012
resourceAttributes: {}
methodName: google.iam.admin.v1.WorkforcePools.CreateWorkforcePool
request:
"@type": type.googleapis.com/google.iam.admin.v1.CreateWorkforcePoolRequest
location: locations/global
workforcePool:
description: Test pool
displayName: Test Pool
name: locations/global/workforcePools/test-pool
parent: organizations/325169835352
sessionDuration: 3600s
state: ACTIVE
workforcePoolId: test-pool
requestMetadata:
callerIp: 07da:0994:97fb:8db1:c68f:c109:fcdd:d594
callerSuppliedUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/119.0,gzip(gfe),gzip(gfe)
destinationAttributes: {}
requestAttributes:
auth: {}
reason: 8uSywAYQGg5Db2xpc2V1bSBGbG93cw
time: "2023-11-17T18:47:53.284817626Z"
resourceName: organizations/325169835352
serviceName: iam.googleapis.com
receiveTimestamp: "2023-11-17T18:47:54.138395349Z"
resource:
labels:
method: google.iam.admin.v1.WorkforcePools.CreateWorkforcePool
service: iam.googleapis.com
type: audited_resource
severity: NOTICE
timestamp: "2023-11-17T18:47:53.276929945Z"
Detection logic
Condition
protoPayload.methodName in ["google.iam.admin.v1.WorkforcePools.CreateWorkforcePool", "google.iam.admin.v1.WorkforcePools.UpdateWorkforcePool"]
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
protoPayload.methodName | in |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
principalEmail | protoPayload.authenticationInfo.principalEmail |