GCP
Security
Tutorials
How to Identify Your GCP SSH vulnerabilities with CloudQuery
In July 2024, Google announced an OpenSSH vulnerability regarding Google Compute Engine (GCE) and Google Kubernetes Engine (GKE). (You can learn more about this announcement here). Fortunately, you can use CloudQuery to export your data from GCP to Postgres, or any other data destination, which can allow you to quickly identify if your GCP resources are affected.
What is the OpenSSH vulnerability? #
Let’s take a look at the CVE-2024-6387 vulnerability and its description provided by Google’s security bulletin:
- GCE bulletin - A vulnerability (CVE-2024-6387) has been discovered in OpenSSH. Successful exploitation of this vulnerability allows a remote, unauthenticated attacker to execute arbitrary code as root on the target machine. All GCE VMs that use a glibc-based Linux distribution and have OpenSSH exposed are vulnerable to this issue.
- GKE bulletin - A remote code execution vulnerability, CVE-2024-6387, was recently discovered in OpenSSH. The vulnerability exploits a race condition that could be used to obtain access to a remote shell, enabling attackers to gain root access to GKE nodes. At the time of publication, exploitation is believed to be difficult and take several hours per machine being attacked. We are not aware of any exploitation attempts. All supported versions of Container Optimized OS and Ubuntu images on GKE run versions of OpenSSH that are vulnerable to this issue. GKE clusters with public node IP addresses and SSH exposed to the Internet should be treated with the highest priority for mitigation. The GKE control plane is not vulnerable to this issue.
In plain English, this means that a serious vulnerability has been found in OpenSSH, which could let hackers remotely take control of affected machines. As a result, everyone using GCP needs to secure their systems by updating OpenSSH and tightening SSH exposure to the Internet.
How to identify GCP Assets potentially vulnerable to the OpenSSH Vulnerability? #
Now that you have GCP data in your PostgreSQL database, let’s dive into some queries that will help you identify vulnerable resources. For these queries we will be leveraging the
gcp_compute_firewalls
and gcp_container_clusters
tables.Identifying potentially vulnerable compute firewalls by name and status:
select
id as gcp_resource_id,
project_id as gcp_project_id,
name,
description,
kind,
network,
disabled
from gcp_compute_firewalls
where name = 'default-allow-ssh'
and disabled is false;
This is the first step to see if any of your GCP compute firewalls allow the default SSH access over TCP via port 22. This query retrieves details of the ‘default-allow-ssh’ firewall rules from Google Cloud Platform (GCP) compute firewalls that are not disabled.
Identifying potentially vulnerable compute firewalls by port and protocol:
For this vulnerability, you want to make sure traffic using TCP from port 22 is blocked or restricted to only your trusted networks. You can use the below query to identify all your active firewalls in your GCP cloud that use TCP and allow access via port 22 for further investigation:
with allowed_ports_flattened as (
select
_cq_id,
JSONB_ARRAY_ELEMENTS(allowed) as allowed
from gcp_prod.gcp_compute_firewalls
), --get all allowed ports and protocols from jsonb array in allowed field
ports_protocols_separated as (
select
_cq_id,
JSONB_ARRAY_ELEMENTS_TEXT(allowed -> 'ports') as ports,
allowed ->> 'I_p_protocol' as protocol
from allowed_ports_flattened
), --get all allowed ports as text and separate out protocol
port_ranges as (
select
_cq_id,
protocol,
nullif(split_part(ports, '-', 1), '')::integer AS range_start,
nullif(split_part(ports, '-', 2), '')::integer AS range_end
from ports_protocols_separated
) --calculate ip range start and end if a range exists
id as gcp_resource_id,
project_id as gcp_project_id,
name,
description,
kind,
network,
protocol,
allowed as ports_allowed,
range_start as allowed_ports_range_start,
range_end as allowed_ports_range_end,
disabled
from gcp_compute_firewalls gcp_cf
join port_ranges pr on gcp_cf._cq_id = pr._cq_id
where
--check if port 22 is in the allowed port range or is the single port
((22 between range_start and range_end) or range_start = 22)
and protocol = 'tcp' --the vuln only relates to TCP traffic
and disabled is false; --select for only active firewalls
This query is slightly more complex. To find the allowable port ranges and IP protocol you will need to leverage PostgreSQL’s built-in JSON functions and Common Table Expressions (CTE). Let’s walk through the different steps in this query and what they do:
- The
allowed_ports_flattened
CTE takes theallowed
JSONB field and flattens out all the elements of the array of ports and protocols using theJSONB_ARRAY_ELEMENTS
this allows you to separate and transform these values for calculation. We also include the_cq_id
field as a unique identifier that we will use to join back to your basegcp_compute_firewalls
table - Next, the
ports_protocols_separated
CTE takes your results fromallowed_ports_flattened
and separates theI_p_protocol
andports
fields in the JSONB into their own columns. - The final
port_ranges
CTE is where the now-separatedports
field can be further split into a start and end range and converted back to integers. The left side of the range is split out as the start of your allowed port range and the right side is the end of your allowed port range. If only a single port exists then it will appear in the range start field and the range end field will benull
.
Now that you understand what the CTEs in the above query are querying, you can build the full query. You can select descriptive fields about your GCP firewalls from the
gcp_compute_firewalls
table while also including the port ranges we just calculated, then use the where
clause to find all firewalls that are active, use TCP, and have port 22 allowed.Identifying potentially vulnerable public GKE clusters:
Per Google, as noted above, GKE clusters with public node IP addresses and SSH exposed to the internet are the highest priority targets for this vulnerability. Let’s see how you can identify clusters that have public nodes using the query below:
select
id as gcp_resource_id,
project_id as gcp_project_id,
name,
description,
network,
status,
private_cluster_config
from gcp_container_clusters
where
private_cluster_config ->> 'enable_private_nodes' = 'false'
Once again you can use PostgreSQL’s JSON functions to parse the
private_cluster_config
field. If this field is set to false
then this container cluster may be publicly accessible and allow SSH access.Summary #
Recently, Google announced a critical OpenSSH vulnerability affecting Google Compute Engine (GCE) and Google Kubernetes Engine (GKE). This vulnerability allows remote, unauthenticated attackers to execute arbitrary code as root on affected machines. To quickly identify if your GCP resources are affected, you can use CloudQuery to export your GCP data to a PostgreSQL database and run specific queries against the gcp_compute_firewalls and gcp_container_clusters tables. These queries help identify potentially vulnerable compute firewalls and public GKE clusters by examining firewall rules and cluster configurations, ensuring prompt mitigation of this critical security issue.
If you're ready to find out if you are vulnerable to the OpenSSH vulnerability on your GCP clusters, you can use CloudQuery to help maintain confidence in your CSPM by identifying potentially vulnerable cloud resources. Try CloudQuery for free and gain immediate insights into vulnerabilities and misconfigurations in your GCP environment. If you have any questions or want to connect with our engineering team, contact us or join our Community.
Written by Kevin Rheinheimer
Kevin is a senior data engineer at CloudQuery, specializing in cloud data infrastructure and application development.