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"
}
# ------ paired body: gcp_iam_service_accounts_get_access_token_privilege_escalation.py ------
from panther_gcp_helpers import gcp_alert_context
def rule(event):
authorization_info = event.deep_walk("protoPayload", "authorizationInfo")
if not authorization_info:
return False
for auth in authorization_info:
if (
auth.get("permission") == "iam.serviceAccounts.getAccessToken"
and auth.get("granted") is True
):
return True
return False
def title(event):
actor = event.udm("actor_user")
operation = event.deep_get("protoPayload", "methodName", default="<OPERATION_NOT_FOUND>")
project_id = event.deep_get("resource", "labels", "project_id", default="<PROJECT_NOT_FOUND>")
return f"[GCP]: [{actor}] performed [{operation}] on project [{project_id}]"
def alert_context(event):
return gcp_alert_context(event)