GCP – How to prevent lateral movement techniques on Google Cloud
Cybercriminals often use lateral movement techniques when exploring a compromised network to slide sideways, from devices to applications, as they hunt for vulnerabilities, escalate access privileges, and seek to reach their ultimate target.
Research published today by Palo Alto Networks highlights several techniques that exploit misconfigurations which could allow a malicious actor to move laterally in cloud environments. While these misconfiguration problems aren’t new, Palo Alto Networks’ research showcases real-world scenarios in which cybercriminals have abused cloud administration permissions to access unauthorized content across cloud providers, including AWS, Azure, and Google Cloud.
In this post, we explain the misconfigurations that could potentially enable these attack vectors, and recommend protection methods that can help secure your Google Cloud environment.
Technique 1: Snapshot Creation
The first lateral movement technique is abuse of virtual machine disk snapshot permissions to gain access to the disk of an instance you aren’t authorized for. These permissions allow a user to create a copy of an existing disk or restore a snapshot to a new disk.
These are critical capabilities for managing backups and recovery points, but if a principal has both of these permissions, they are able to create a full working copy of a disk under your control. When you attach that disk to an instance, you can now access the contents of the disk that you previously had no Read permissions for.
Use of this technique can be accelerated if a snapshot of the disk already exists. Instead of having to create a snapshot, an attacker with the Viewer role and appropriate permissions can restore an existing backup to a project they control. In short – limited Read access to a target project, and Restore permissions to a separate project, allows an attacker to recreate all the instances and access the data.
This means snapshot permissions on a disk should be viewed as a permission to access the disk’s core content, even if the user doesn’t have standard access to the instance. Failure to apply principle of least privilege to this permission allows a threat actor with an initial footprint in an organization to gain access to data far beyond the initial blast radius.
How to execute
The first step is to create a snapshot of the disk that is part of an instance you can’t access. This step can be skipped if there is already a snapshot of the instance that you have read access for.
<ListValue: [StructValue([(‘code’, ‘gcloud compute snapshots create SNAPSHOT_NAME \rn –source-disk-zone=SOURCE_ZONE \rn –source-disk=SOURCE_DISK_NAME \rn –snapshot-type=SNAPSHOT_TYPE’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3efb89d810a0>)])]>
<ListValue: [StructValue([(‘code’, ‘gcloud beta compute instant-snapshots create INSTANT_SNAPSHOT_NAME \rn –source-disk=SOURCE_DISK_NAME \rn –zone=SOURCE_DISK_ZONE’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3efb89d81f70>)])]>
Once you have a snapshot created, you need to use it to create a disk under your control. This works for both Standard and Instance Snapshots as well.
<ListValue: [StructValue([(‘code’, ‘gcloud compute disks create DISK_NAME \rn –size=DISK_SIZE \rn –source-snapshot=SNAPSHOT_NAME \rn –type=DISK_TYPE’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3efb89d81ca0>)])]>
<ListValue: [StructValue([(‘code’, ‘gcloud beta compute disks create DISK_NAME –zone=ZONE \rn –source-instant-snapshot=SOURCE_INSTANT_SNAPSHOT_NAME’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3efb89d81c10>)])]>
The final step is to attach the disk to a new instance you own to gain access to the core content of the original target disk.
<ListValue: [StructValue([(‘code’, ‘gcloud compute instances attach-disk INSTANCE_NAME \rn –disk DISK_NAME’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3efb89d81490>)])]>
Permissions required
Standard Snapshots
Create
Compute.snapshots.create on the project
compute.disks.createSnapshot on the disk
compute.instances.useReadOnly on the source VM (for regional disk)
Restore
Compute.disks.create on the attacker’s project
compute.snapshots.useReadOnly on the new snapshot
Instant Snapshots
Create
compute.instantSnapshosts.create on the project
Restore
Compute.disks.create on the attacker’s project
compute.instantSnapshots.useReadOnly on the snapshot
How to prevent
The ability to create a VM disk snapshot ultimately means you have read permissions because it is trivial to create a copy of the disk under your control. This means security administrators need to limit the snapshot Create and Read permissions solely to roles who should have access to the disk content.
The full scope of this permission should be evaluated as organizations build their business continuity and failover plans. Once appropriate risk tolerance is identified, organizations can control the snapshot permission via IAM roles.
Technique 2: Metadata-based SSH keys
The second technique uses metadata permissions to add an SSH public key to an instance or project, enabling SSH to an instance you weren’t initially able to access.
The concept of using existing permissions to create new and unauthorized accesses is a well known adversarial technique. Google Cloud offers a number of ways to lock down this permission, but an organization that chooses to use metadata-based SSH keys should consider metadata permissions as the equivalent of providing access to the core content on an instance.
How to execute
<ListValue: [StructValue([(‘code’, ‘gcloud compute project-info add-metadata –metadata-from-file=ssh-keys=KEY_FILE’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3efb89d81f10>)])]>
<ListValue: [StructValue([(‘code’, ‘gcloud compute instances add-metadata VM_NAME –metadata-from-file \ ssh-keys=KEY_FILE’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3efb89d81d60>)])]>
Permissions required
Add SSH Keys to Project Metadatacompute.projects.setCommonInstanceMetadata on the projectiam.serviceAccounts.actAs on the projectAdd SSH Keys to Instance Metadatacompute.instances.setMetadata on the VM
How to prevent
The best way to lock down this technique is to use OS Login so that SSH keys are not stored in instance metadata. Cloud Administrators can set the project or instance metadata field ‘enable-oslogin’ to True to turn this on.
Google also offers an Org Policy to enforce OS Login (constraints/compute.requireOsLogin) for all instances at the Project, Folder, or Org level. Google’s Security Command Center can also alert organizations on any workloads that are vulnerable to this misconfiguration.
Another way to block this is to prevent VMs from accepting SSH keys that are stored in project metadata by blocking project SSH keys from VMs. This is done by setting the ‘block-project-ssh-keys’ to True on the VM. This permission is also detectable in Google’s Security Command Center as a potential vulnerability to help strengthen your Organization’s posture.
<ListValue: [StructValue([(‘code’, ‘gcloud compute instances create VM_NAME \rn –metadata block-project-ssh-keys=TRUE’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3efb89d81520>)])]>
Technique 3: Serial console
While serial access is turned off by default across Google Cloud, having metadata access to an instance can enable you to turn it on in order to access the previously unauthorized instance. Similar to the metadata SSH Key technique above, without an Org Policy security guardrail in place, metadata permissions need to be managed by the cloud administrator as providing access to the core content on an instance.
How to execute
The first step is to enable access to the serial console at Project or Instance level.
For a Project
<ListValue: [StructValue([(‘code’, ‘gcloud compute project-info add-metadata \rn –metadata serial-port-enable=TRUE’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3efb89d812e0>)])]>
<ListValue: [StructValue([(‘code’, ‘gcloud compute instances add-metadata instance-name \rn –metadata serial-port-enable=TRUE’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3efb89d81340>)])]>
Once access is enabled, you just need to connect to the serial console for access.
<ListValue: [StructValue([(‘code’, ‘gcloud compute connect-to-serial-port VM_NAME \rn –location=REGION \rn –port=PORT_NUMBER’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3efb89d81cd0>)])]>
Permissions required
compute.instances.setMetadata on the VM if enabling interactive access on a specific VMcompute.projects.setCommonInstanceMetadata on the project, if enabling interactive access for all VMs in the projectiam.serviceAccountUser role on the Instance’s service account
How to protect and detect
Similar to the metadata SSH Key technique, the best method for locking this down is to set an Org Policy to prevent Serial Port access from being turned on with constraints by using compute.disableSerialPortAccess. This can be implemented at the Project, Folder, or Org level depending on your Org’s security posture. Security Command Center will also detect when the permission is enabled.
Key takeaways
Each of the permissions listed in Palo Alto Networks’ blog have genuine utility for cloud administrators and users. Snapshots are a critical backup tool, while metadata SSH Key and Serial Console are extremely useful access mechanisms for certain organizations and users.
From a security perspective, it is critical to balance the operational utility of these permissions with the potential access they provide by ensuring that your IAM roles and permissions are locked down to the least privilege principle to accomplish their task.
Google Cloud is dedicated to offering the tools and features to support our customers in accomplishing this task. We recently released Custom Org Policies to provide greater flexibility in establishing security guardrails, and we regularly update the vulnerability detection in Security Command Center based on our real-world threat data from Mandiant Threat Intelligence and our Threat Horizons reports.
Read More for the details.