Detection rules › Panther
GCP IAM serviceAccounts getAccessToken Privilege Escalation
The Identity and Access Management (IAM) service manages authorization and authentication for a GCP environment. This means that there are very likely multiple privilege escalation methods that use the IAM service and/or its permissions.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation | T1548 Abuse Elevation Control Mechanism |
Rule body yaml
AnalysisType: rule
Filename: gcp_iam_service_accounts_get_access_token_privilege_escalation.py
RuleID: "GCP.IAM.serviceAccounts.getAccessToken.Privilege.Escalation"
DisplayName: "GCP IAM serviceAccounts getAccessToken Privilege Escalation"
Enabled: true
LogTypes:
- GCP.AuditLog
Reports:
MITRE ATT&CK:
- TA0004:T1548
Severity: High
Description:
The Identity and Access Management (IAM) service manages authorization and authentication for a GCP environment.
This means that there are very likely multiple privilege escalation methods that use the IAM service and/or its permissions.
Reference: https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/
Tests:
- Name: iam.serviceAccounts.getAccessToken granted
ExpectedResult: true
Log:
{
"p_log_type": "GCP.AuditLog",
"protoPayload":
{
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"status": {},
"authenticationInfo":
{
"principalEmail": "some-project@company.iam.gserviceaccount.com",
"serviceAccountKeyName": "//iam.googleapis.com/projects/some-project/serviceAccounts/some-project@company.iam.gserviceaccount.com/keys/a378358365ff3d22e9c1a72fecf4605ddff76b47",
"principalSubject": "serviceAccount:some-project@company.iam.gserviceaccount.com",
},
"requestMetadata":
{
"callerIp": "1.2.3.4",
"requestAttributes":
{ "time": "2024-02-26T17:15:16.327542536Z", "auth": {} },
"destinationAttributes": {},
},
"serviceName": "iamcredentials.googleapis.com",
"methodName": "SignJwt",
"authorizationInfo":
[
{
"permission": "iam.serviceAccounts.getAccessToken",
"granted": true,
"resourceAttributes": {},
},
],
"resourceName": "projects/-/serviceAccounts/114885146936855121342",
"request":
{
"name": "projects/-/serviceAccounts/some-project@company.iam.gserviceaccount.com",
"@type": "type.googleapis.com/google.iam.credentials.v1.SignJwtRequest",
},
},
"insertId": "1hu88qbef4d2o",
"resource":
{
"type": "service_account",
"labels":
{
"project_id": "some-project",
"unique_id": "114885146936855121342",
"email_id": "some-project@company.iam.gserviceaccount.com",
},
},
"timestamp": "2024-02-26T17:15:16.314854637Z",
"severity": "INFO",
"logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Fdata_access",
"receiveTimestamp": "2024-02-26T17:15:17.100020459Z",
}
- Name: iam.serviceAccounts.getAccessToken not granted
ExpectedResult: false
Log:
{
"p_log_type": "GCP.AuditLog",
"protoPayload":
{
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"status": {},
"authenticationInfo":
{
"principalEmail": "some-project@company.iam.gserviceaccount.com",
"serviceAccountKeyName": "//iam.googleapis.com/projects/some-project/serviceAccounts/some-project@company.iam.gserviceaccount.com/keys/a378358365ff3d22e9c1a72fecf4605ddff76b47",
"principalSubject": "serviceAccount:some-project@company.iam.gserviceaccount.com",
},
"requestMetadata":
{
"callerIp": "1.2.3.4",
"requestAttributes":
{ "time": "2024-02-26T17:15:16.327542536Z", "auth": {} },
"destinationAttributes": {},
},
"serviceName": "iamcredentials.googleapis.com",
"methodName": "SignJwt",
"authorizationInfo":
[
{
"permission": "iam.serviceAccounts.getAccessToken",
"granted": false,
"resourceAttributes": {},
},
],
"resourceName": "projects/-/serviceAccounts/114885146936855121342",
"request":
{
"name": "projects/-/serviceAccounts/some-project@company.iam.gserviceaccount.com",
"@type": "type.googleapis.com/google.iam.credentials.v1.SignJwtRequest",
},
},
"insertId": "1hu88qbef4d2o",
"resource":
{
"type": "service_account",
"labels":
{
"project_id": "some-project",
"unique_id": "114885146936855121342",
"email_id": "some-project@company.iam.gserviceaccount.com",
},
},
"timestamp": "2024-02-26T17:15:16.314854637Z",
"severity": "INFO",
"logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Fdata_access",
"receiveTimestamp": "2024-02-26T17:15:17.100020459Z",
}
- Name: Principal Subject Used
ExpectedResult: true
Log:
{
"p_log_type": "GCP.AuditLog",
"insertId": "1dy9ihte4iyjz",
"logName": "projects/mylogs/logs/cloudaudit.googleapis.com%2Fdata_access",
"operation": {
"first": true,
"id": "10172500524907939495",
"last": true,
"producer": "iamcredentials.googleapis.com"
},
"protoPayload": {
"at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
"authenticationInfo": {
"principalSubject": "example_principal_subject",
"serviceAccountDelegationInfo": [
{}
]
},
"authorizationInfo": [
{
"granted": true,
"permission": "iam.serviceAccounts.getAccessToken",
"resourceAttributes": {}
}
],
"metadata": {
"identityDelegationChain": [
"projects/-/serviceAccounts/xxxxx.iam.gserviceaccount.com"
]
},
"methodName": "GenerateAccessToken",
"request": {
"@type": "type.googleapis.com/google.iam.credentials.v1.GenerateAccessTokenRequest",
"name": "projects/-/serviceAccounts/xxxxx.iam.gserviceaccount.com"
},
"requestMetadata": {
"callerIP": "gce-internal-ip",
"callerSuppliedUserAgent": "google-api-go-client/0.5 gke-metadata-server,gzip(gfe)",
"destinationAttributes": {},
"requestAttributes": {
"auth": {},
"time": "2024-08-29T19:30:36.353462175Z"
}
},
"resourceName": "projects/-/serviceAccounts/11111222223333444455",
"serviceName": "iamcredentials.googleapis.com",
"status": {}
},
"receiveTimestamp": "2024-08-29 19:30:36.424542070",
"resource": {
"labels": {
"email_id": "sample@email.com",
"project_id": "sample_project_id",
"unique_id": "11111222223333444455"
},
"type": "service_account"
},
"severity": "INFO",
"timestamp": "2024-08-29 19:30:36.339983306"
}
Detection logic
Condition
protoPayload.authorizationInfo is_not_null
protoPayload.authorizationInfo array_any
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.authorizationInfo | is_not_null |
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 |
|---|---|
project | resource.labels.project_id |
principal | protoPayload.authenticationInfo.principalEmail |
caller_ip | protoPayload.requestMetadata.callerIP |
methodName | protoPayload.methodName |
resourceName | protoPayload.resourceName |
serviceName | protoPayload.serviceName |
actor_user |