How to prevent lateral movement techniques on Google Cloud

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.

code_block
<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 0x3e8cacfab730>)])]>
code_block
<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 0x3e8cacfab4f0>)])]>

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.

code_block
<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 0x3e8cacfab340>)])]>
code_block
<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 0x3e8cacfabb80>)])]>

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.

code_block
<ListValue: [StructValue([('code', 'gcloud compute instances attach-disk INSTANCE_NAME rn –disk DISK_NAME'), ('language', ''), ('caption', <wagtail.rich_text.RichText object at 0x3e8cacfab970>)])]>

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

code_block
<ListValue: [StructValue([('code', 'gcloud compute project-info add-metadata –metadata-from-file=ssh-keys=KEY_FILE'), ('language', ''), ('caption', <wagtail.rich_text.RichText object at 0x3e8cacfab4c0>)])]>
code_block
<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 0x3e8cacfabbe0>)])]>

Permissions required

  • Add SSH Keys to Project Metadata
    • compute.projects.setCommonInstanceMetadata on the project
    • iam.serviceAccounts.actAs on the project
  • Add SSH Keys to Instance Metadata
    • compute.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.

code_block
<ListValue: [StructValue([('code', 'gcloud compute instances create VM_NAME rn –metadata block-project-ssh-keys=TRUE'), ('language', ''), ('caption', <wagtail.rich_text.RichText object at 0x3e8cacfaba30>)])]>

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
code_block
<ListValue: [StructValue([('code', 'gcloud compute project-info add-metadata rn –metadata serial-port-enable=TRUE'), ('language', ''), ('caption', <wagtail.rich_text.RichText object at 0x3e8cacfab7f0>)])]>
  • For a VM Instance
code_block
<ListValue: [StructValue([('code', 'gcloud compute instances add-metadata instance-name rn –metadata serial-port-enable=TRUE'), ('language', ''), ('caption', <wagtail.rich_text.RichText object at 0x3e8cacfab880>)])]>

Once access is enabled, you just need to connect to the serial console for access.

code_block
<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 0x3e8cacfaba60>)])]>

Permissions required

  • compute.instances.setMetadata on the VM if enabling interactive access on a specific VM
  • compute.projects.setCommonInstanceMetadata on the project, if enabling interactive access for all VMs in the project
  • iam.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.