GitLab Developer Account Leads to Full OpenStack Cloud Control via CI/CD Runner Misconfigurations

A penetration testing team demonstrated how a standard developer account in GitLab can be escalated to full administrative control over an OpenStack cloud environment through typical CI/CD misconfigurations. Starting with only GitLab credentials, the testers created a pipeline that executed arbitrary commands on a production Kubernetes runner named PROD-K8S-RUNNER01. Membership in the docker group allowed privilege escalation to root by mounting the host filesystem and adding an SSH key. From the compromised host, the team discovered a kubeconfig file granting extensive Kubernetes permissions including secret access, pod execution, and role bindings. This access enabled mounting a node filesystem to extract OpenStack cloud-config credentials. The resulting cloud account possessed broad roles across nova, cinder, neutron, and other services, effectively providing administrator-level control over virtual machines, networks, storage, and managed Kubernetes clusters.

HabrTranslated from Russian

Read at source

A penetration testing team from Bastion has shown how a routine developer account in GitLab can serve as the starting point for a full infrastructure compromise, ultimately granting control over an OpenStack cloud environment.

Initial Access via GitLab Account

With only a standard developer account and no VPN, domain credentials, or RDP access, the testers created a test project and added a .gitlab-ci.yml file. The pipeline was configured to run reconnaissance commands and contact an external webhook. Execution occurred on the runner PROD-K8S-RUNNER01 under the gitlab_runner user, which belonged to the docker group.

Privilege Escalation to Root

Membership in the docker group provided direct access to the Docker socket, allowing containers to be launched with host namespaces mounted. The team deployed a C2 beacon and then used it to run a container that added their SSH key to the host’s root authorized_keys file, achieving root access on the runner.

Kubernetes Access and Node Compromise

Manual inspection of the host revealed a kubeconfig file belonging to a CICD service account for the prod-cluster-k8s cluster. The account possessed permissions to read secrets, create pod exec sessions, perform port forwards, and create role bindings. These rights enabled the creation of a privileged pod that mounted the filesystem of node PROD-K8S01-MS1-MAIN-1.

Cloud Credential Extraction and Impact

Analysis of /etc/kubernetes on the node yielded an OpenStack cloud-config file. Using the extracted credentials, the testers enumerated servers, networks, users, and roles. Although the account lacked the explicit admin role, its combined permissions across nova, cinder, neutron, glance, octavia, heat, magnum, and managed Kubernetes services provided effective administrative control over the entire cloud infrastructure.

The full attack chain required no complex exploits, only common misconfigurations: running CI/CD runners with docker group membership, storing kubeconfigs on build hosts, and granting overly broad RBAC permissions to service accounts.

Meridian digestThe week's most consequential security stories, distilled into one briefing.See the digest

More in Vulnerabilities & Exploits

Telegram for Android Patches Voice Call Vulnerability Enabling Code Execution
Yandex Patches Millions of Stations After eMudhra Certificate Keys Compromised
Cisco ASA and FTD Face DoS Vulnerability in SSL VPN Already Exploited in the Wild