Invite an External User to a GCP Project
idempotent
Platform: GCP
MITRE ATT&CK Tactics
- Persistence
Description
Persists in the GCP project by inviting an external (fictitious) user to the project. The attacker could then use the external user to access the project.
Warm-up: None
Detonation:
- Updates the project IAM policy to grant the attacker account the role
roles/editor
Note
Since the target e-mail must exist for this attack simulation to work, Stratus Red Team grants the role to stratusredteam@gmail.com by default.
This is a real Google account, owned by Stratus Red Team maintainers and that is not used for any other purpose than this attack simulation. However, you can override
this behavior by setting the environment variable STRATUS_RED_TEAM_ATTACKER_EMAIL
, for instance:
Instructions
Detection
The Google Cloud Admin logs event SetIamPolicy
is generated when a principal is granted non-owner permissions at the project level.
{
"protoPayload": {
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"serviceName": "cloudresourcemanager.googleapis.com",
"methodName": "SetIamPolicy",
"serviceData": {
"@type": "type.googleapis.com/google.iam.v1.logging.AuditData",
"policyDelta": {
"bindingDeltas": [
{
"action": "ADD",
"role": "roles/editor",
"member": "user:stratusredteam@gmail.com"
}
]
}
},
"request": {
"resource": "target-project",
"policy": {
// ...
},
"@type": "type.googleapis.com/google.iam.v1.SetIamPolicyRequest"
}
}
}
Although this attack technique does not simulate it, an attacker can also
use the GCP console to invite an external user as owner of a GCP project,
which cannot be done through the SetIamPolicy API call. In that case, an InsertProjectOwnershipInvite
event is generated:
{
"protoPayload": {
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"serviceName": "cloudresourcemanager.googleapis.com",
"methodName": "InsertProjectOwnershipInvite",
"resourceName": "projects/target-project",
"request": {
"member": "user:attacker@gmail.com",
"projectId": "target-project",
"@type": "type.googleapis.com/google.internal.cloud.resourcemanager.InsertProjectOwnershipInviteRequest"
},
"response": {
"@type": "type.googleapis.com/google.internal.cloud.resourcemanager.InsertProjectOwnershipInviteResponse"
}
}
}