mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 14:47:17 -07:00
Translated ['src/pentesting-ci-cd/pentesting-ci-cd-methodology.md', 'src
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
# Argo CD Security
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
|
||||
[Argo CD](https://argo-cd.readthedocs.io/) is a GitOps continuous delivery platform for Kubernetes. It watches Git repositories, renders Kubernetes manifests with tools such as Helm, Kustomize, Jsonnet or config management plugins, and reconciles the live cluster state with the desired state stored in Git.
|
||||
|
||||
Зі сторони attacker, treat Argo CD as a **deployment engine with Kubernetes credentials**. A useful Argo CD compromise can lead to:
|
||||
|
||||
- Access to private Git repositories and repository credentials.
|
||||
- Access to Kubernetes cluster secrets used by Argo CD.
|
||||
- Manifest generation code execution in `argocd-repo-server`.
|
||||
- Unauthorized Kubernetes object deployment through trusted Git repositories, Argo CD applications, or cache manipulation.
|
||||
|
||||
## Architecture & Interesting Components
|
||||
|
||||
Common Kubernetes objects and services:
|
||||
```bash
|
||||
kubectl get pods,svc,endpoints,ingress -A | grep -iE 'argocd|argo-cd'
|
||||
kubectl get applications,appprojects,applicationsets -A 2>/dev/null
|
||||
kubectl get secrets,configmaps -n argocd 2>/dev/null
|
||||
kubectl get networkpolicy -n argocd 2>/dev/null
|
||||
```
|
||||
Цікаві сервіси:
|
||||
|
||||
- **`argocd-server`**: public API, web UI, CLI API, authentication and authorization.
|
||||
- **`argocd-application-controller`**: порівнює desired і live state, потім застосовує resources до Kubernetes.
|
||||
- **`argocd-repo-server`**: клонують repositories, кешує Git data, і запускає Helm/Kustomize/Jsonnet/plugins для генерації manifests. Стандартний gRPC port — **8081**.
|
||||
- **`argocd-redis`**: cache для application, manifest і Git reference data. Стандартний Redis port — **6379**.
|
||||
- **`argocd-applicationset-controller`**: генерує Argo CD `Application` objects з generators, таких як Git, SCM, clusters і pull requests.
|
||||
|
||||
З compromised pod або internal network segment, перевірте internal reachability:
|
||||
```bash
|
||||
nc -vz <argocd-server> 443
|
||||
nc -vz <argocd-repo-server> 8081
|
||||
nc -vz <argocd-redis> 6379
|
||||
```
|
||||
## Public API / UI Attacks
|
||||
|
||||
Якщо у вас є Argo CD credentials або exposed instance, почніть із звичайної API surface:
|
||||
```bash
|
||||
argocd login <argocd-server>
|
||||
argocd account get-user-info
|
||||
argocd account list
|
||||
argocd proj list
|
||||
argocd app list
|
||||
argocd repo list
|
||||
argocd cluster list
|
||||
argocd admin settings rbac can <subject> <action> <resource> <object>
|
||||
```
|
||||
Корисні paths для attack:
|
||||
|
||||
- **Application write access**: змініть `source.repoURL`, `source.path`, Helm values, Kustomize options, plugin settings або sync options, щоб Argo CD розгортав manifests, контрольовані attacker.
|
||||
- **Project misconfiguration**: об’єкти `AppProject` можуть дозволяти широкі `sourceRepos`, широкі `destinations`, небезпечний `clusterResourceWhitelist` або слабкі namespace restrictions.
|
||||
- **Repository credential abuse**: repository secrets, GitHub App credentials, SSH keys і tokens можуть дозволити push у trusted repos або додавання malicious dependencies.
|
||||
- **Cluster credential abuse**: cluster secrets можуть містити bearer tokens або exec-provider configuration, які Argo CD використовує для deploy у target clusters.
|
||||
- **Local admin / project tokens**: long-lived Argo CD tokens можна повторно використовувати через API, якщо їх не revoked або не expired.
|
||||
|
||||
Перелічіть configuration з Kubernetes, коли маєте cluster read access:
|
||||
```bash
|
||||
kubectl get applications.argoproj.io -A -o yaml
|
||||
kubectl get appprojects.argoproj.io -A -o yaml
|
||||
kubectl get applicationsets.argoproj.io -A -o yaml
|
||||
kubectl get secrets -n argocd -o yaml | grep -nE 'repoURL|sshPrivateKey|password|bearerToken|githubApp|tlsClientCertData|tlsClientCertKey'
|
||||
kubectl get cm -n argocd argocd-cm argocd-rbac-cm argocd-cmd-params-cm -o yaml
|
||||
```
|
||||
## Зловживання Trusted Git Repository
|
||||
|
||||
If you can push to a repository trusted by Argo CD, you can usually influence what is deployed. Impact depends on the `AppProject` boundaries and the service account permissions used by the application controller.
|
||||
|
||||
Common payload locations:
|
||||
|
||||
- Raw Kubernetes YAML under an application path.
|
||||
- Helm chart templates and `values.yaml`.
|
||||
- Kustomize overlays, remote bases and generators.
|
||||
- Jsonnet or config management plugin input.
|
||||
- ApplicationSet generator files that create or update `Application` objects.
|
||||
|
||||
Check whether the app uses automated sync, pruning, self-heal, sync windows or manual approvals:
|
||||
```bash
|
||||
kubectl get applications.argoproj.io -A \
|
||||
-o custom-columns='NS:.metadata.namespace,APP:.metadata.name,PROJECT:.spec.project,AUTOSYNC:.spec.syncPolicy.automated,REPO:.spec.source.repoURL,PATH:.spec.source.path,DEST:.spec.destination.server'
|
||||
```
|
||||
## Пряме зловживання `argocd-repo-server`
|
||||
|
||||
Не припускайте, що публічний Argo CD API — це єдина attack surface. Внутрішні компоненти Argo CD взаємодіють з `argocd-repo-server` через gRPC. Якщо arbitrary pods можуть дістатися до repo-server, attacker-controlled internal requests можуть обійти перевірки, які зазвичай enforced by `argocd-server`.
|
||||
|
||||
Практичні перевірки:
|
||||
```bash
|
||||
kubectl get svc -n argocd argocd-repo-server -o yaml
|
||||
kubectl get endpoints -n argocd argocd-repo-server -o wide
|
||||
nc -vz <argocd-repo-server> 8081
|
||||
```
|
||||
Цікаві ознаки:
|
||||
|
||||
- gRPC endpoint repo-server доступний із non-Argo CD pods.
|
||||
- NetworkPolicies відсутні або лише allow-list egress без deny ingress.
|
||||
- repo-server має доступ до custom config management plugins, decryption tools або repository content від multiple tenants.
|
||||
- Redis доступний із non-Argo CD pods, що дає змогу переглядати або змінювати cache, якщо credentials доступні або не потрібні.
|
||||
|
||||
## Unauthenticated Repo-Server RCE via Kustomize Options
|
||||
|
||||
У липні 2026 року Synacktiv опублікувала chain виконання коду без автентифікації в `repo-server` Argo CD, коли attacker може дістатися внутрішнього gRPC service. Атака зловживає прямим доступом до `/repository.RepoServerService/GenerateManifest` і керованим attacker-ом `KustomizeOptions`.
|
||||
|
||||
Небезпечний primitive — змусити repo-server клонувати repository content під контролем attacker-а і запускати Kustomize з Helm support:
|
||||
```bash
|
||||
kustomize build <attacker_repo_path> --enable-helm --helm-command ./payload.sh
|
||||
```
|
||||
Мінімальний malicious Kustomize input, потрібний для trigger Helm processing:
|
||||
```yaml
|
||||
helmCharts:
|
||||
- name: pwn
|
||||
version: 0.0.1
|
||||
```
|
||||
Чому це працює:
|
||||
|
||||
- `argocd-repo-server` клонує repository перед rendering.
|
||||
- `--helm-command ./payload.sh` розв’язується відносно клонованого repository.
|
||||
- Code execution не потребує shell metacharacter injection, якщо attacker може контролювати rendered repository і Kustomize build options.
|
||||
|
||||
На момент disclosure від Synacktiv 1 липня 2026 року вони повідомили, що issue не мала офіційного fix або CVE. Розглядайте це насамперед як network-exposure issue: exploitation вимагає reachability до internal repo-server gRPC port.
|
||||
|
||||
## Redis Cache Poisoning to Deploy Manifests
|
||||
|
||||
Після code execution у `argocd-repo-server`, або після direct access до Redis із valid credentials, перевірте Redis-backed cache entries. Argo CD зазвичай зберігає gzip-compressed JSON values.
|
||||
|
||||
Interesting key prefixes:
|
||||
```text
|
||||
mfst|... # cached rendered manifests
|
||||
git-refs|... # Git branch/ref to commit mappings
|
||||
app|... # application resource/cache data
|
||||
cluster|... # cluster cache information
|
||||
```
|
||||
Атака cache poisoning, описана Synacktiv, зловживає двома станами:
|
||||
|
||||
1. Змініть відповідний запис `mfst|...` у cache manifest, щоб включити Kubernetes manifest, контрольований attacker’ом.
|
||||
2. Змініть пов’язане зіставлення `git-refs|...`, щоб Argo CD повірив, що branch перемістився, а потім reconciles повернувся до cached revision.
|
||||
|
||||
Impact:
|
||||
|
||||
- Якщо увімкнено Auto Sync, Argo CD може автоматично застосувати poisoned cached manifest.
|
||||
- Без Auto Sync payload все ще може бути застосований, коли user вручну syncs application.
|
||||
- Остаточний impact обмежується destination цільової application та Kubernetes permissions, доступними Argo CD.
|
||||
|
||||
## ApplicationSet Attacks
|
||||
|
||||
ApplicationSet особливо чутливий, оскільки він створює або оновлює об’єкти `Application` на основі generator output.
|
||||
|
||||
Review:
|
||||
```bash
|
||||
kubectl get applicationsets.argoproj.io -A -o yaml
|
||||
kubectl get appprojects.argoproj.io -A -o yaml
|
||||
```
|
||||
Цікаві patterns:
|
||||
|
||||
- Git generators, що читають attacker-writable files, які керують app names, paths, projects або destinations.
|
||||
- Pull request generators для public repositories, де untrusted contributors можуть впливати на generated applications.
|
||||
- Template fields, які дозволяють broad destination clusters/namespaces.
|
||||
- AppProjects, що permit `sourceRepos: ["*"]` або broad `destinations`.
|
||||
- Generated applications, які успадковують automated sync і pruning.
|
||||
|
||||
## Post-Exploitation
|
||||
|
||||
З Argo CD pod shell, prioritise:
|
||||
```bash
|
||||
env
|
||||
cat /proc/1/environ 2>/dev/null | tr '\0' '\n'
|
||||
find /var/run/secrets /app/config -type f -maxdepth 4 2>/dev/null
|
||||
mount | grep -E 'secret|token|config'
|
||||
```
|
||||
Корисні цілі:
|
||||
|
||||
- Викрасти `REDIS_PASSWORD` або Redis TLS/client material.
|
||||
- Витягнути repository credentials із mounted secrets або Argo CD Kubernetes secrets.
|
||||
- Виявити cluster credentials, які використовує Argo CD.
|
||||
- Прочитати generated manifests і plugin output, які можуть містити injected secrets.
|
||||
- Перевірити, чи custom plugins, SOPS, Helm secrets, Vault plugins або cloud CLIs expose decryption keys і cloud credentials.
|
||||
|
||||
## Detection & Hardening
|
||||
|
||||
Важливі перевірки:
|
||||
|
||||
- Обмежити `argocd-repo-server` port **8081** і Redis port **6379** за допомогою NetworkPolicies так, щоб лише очікувані компоненти Argo CD могли до них звертатися.
|
||||
- У Helm deployments перевірити, що network policies справді створюються. Значення Argo CD Helm chart historically за замовчуванням вимикали створення network policy для компонентів.
|
||||
- Залишити `argocd-server` як authenticated entry point. Internal services не мають бути доступні для довільних workloads.
|
||||
- Вимкнути невикористовувані config management tools і plugins.
|
||||
- Обмежити `AppProject` `sourceRepos`, `destinations`, namespace permissions і cluster-scoped resources.
|
||||
- Уникати зберігання широких repository credentials там, де користувач Argo CD з низькими привілеями може спричинити їх повторне використання.
|
||||
- Моніторити repo-server requests, Kustomize build options, plugin executions, Redis writes і неочікуваний доступ до ключів `mfst|` / `git-refs|`.
|
||||
- Оновити Argo CD local users, project tokens, repository credentials і cluster credentials після compromise.
|
||||
|
||||
Корисні команди:
|
||||
```bash
|
||||
kubectl get networkpolicy -n argocd
|
||||
kubectl get networkpolicy -A | grep -i argocd
|
||||
kubectl describe networkpolicy -n argocd argocd-repo-server-network-policy 2>/dev/null
|
||||
kubectl describe networkpolicy -n argocd argocd-redis-network-policy 2>/dev/null
|
||||
```
|
||||
## Примітка щодо Static Analysis: Typed API Requests in CodeQL
|
||||
|
||||
For Go services using gRPC/REST handlers, default CodeQL remote sources may miss flows once raw input has been unmarshaled into typed request objects. A useful model for Argo CD-style services is:
|
||||
|
||||
- Receiver type such as `Server` or `Service`.
|
||||
- First parameter is `context.Context`.
|
||||
- Second parameter is a typed request object.
|
||||
|
||||
Model that second parameter as a remote source and add custom sinks for `exec.Command` / `exec.CommandContext` arguments. This helps find flows from internal API request fields into command execution helpers.
|
||||
|
||||
## References
|
||||
|
||||
- [Synacktiv - Caught in the Octopus Trap: Unauthenticated RCE in Argo CD with CodeQL](https://www.synacktiv.com/en/publications/caught-in-the-octopus-trap-unauthenticated-rce-in-argo-cd-with-codeql)
|
||||
- [Argo CD docs - Security considerations](https://argo-cd.readthedocs.io/en/stable/operator-manual/security/)
|
||||
- [Argo CD docs - High Availability](https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/)
|
||||
- [Argo CD docs - repo-server command reference](https://argo-cd.readthedocs.io/en/stable/operator-manual/server-commands/argocd-repo-server/)
|
||||
- [Argo CD - repo-server NetworkPolicy manifest](https://github.com/argoproj/argo-cd/blob/master/manifests/base/repo-server/argocd-repo-server-network-policy.yaml)
|
||||
- [Argo CD docs - metrics](https://argo-cd.readthedocs.io/en/latest/operator-manual/metrics/)
|
||||
- [Argo Helm - chart values reference](https://github.com/argoproj/argo-helm/blob/main/charts/argo-cd/README.md)
|
||||
- [Kustomize - Helm chart generator example](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/chart.md)
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## VCS
|
||||
|
||||
VCS означає **Version Control System**, ці системи дозволяють розробникам **керувати своїм source code**. Найпоширеніша з них — **git**, і ви зазвичай зустрінете компанії, які використовують її в одній із таких **platforms**:
|
||||
VCS означає **Version Control System**, ці системи дозволяють розробникам **керувати своїм source code**. Найпоширеніший з них — **git**, і зазвичай компанії використовують його на одній із таких **platforms**:
|
||||
|
||||
- Github
|
||||
- Gitlab
|
||||
@@ -18,39 +18,39 @@ VCS означає **Version Control System**, ці системи дозвол
|
||||
|
||||
## CI/CD Pipelines
|
||||
|
||||
CI/CD pipelines дозволяють розробникам **автоматизувати виконання code** для різних цілей, зокрема build, testing і deploying applications. Ці автоматизовані workflows **запускаються певними діями**, такими як code pushes, pull requests або scheduled tasks. Вони корисні для спрощення процесу від development до production.
|
||||
CI/CD pipelines дають змогу розробникам **автоматизувати виконання code** для різних цілей, зокрема build, testing і deploy applications. Ці автоматизовані workflows **запускаються конкретними діями**, такими як code pushes, pull requests або scheduled tasks. Вони корисні для спрощення процесу від development до production.
|
||||
|
||||
Однак ці системи потрібно **виконувати десь**, і зазвичай з **privileged credentials для deploy code або доступу до sensitive information**.
|
||||
Однак ці системи потрібно **виконувати десь**, і зазвичай із **privileged credentials для deploy code або доступу до sensitive information**.
|
||||
|
||||
## VCS Pentesting Methodology
|
||||
|
||||
> [!NOTE]
|
||||
> Навіть якщо деякі VCS platforms дозволяють створювати pipelines, у цьому розділі ми будемо аналізувати лише potential attacks to the control of the source code.
|
||||
> Навіть якщо деякі VCS platforms дозволяють створювати pipelines, для цього розділу ми аналізуватимемо лише potential attacks на control of the source code.
|
||||
|
||||
Platforms that contains the source code of your project contains sensitive information and people need to be very careful with the permissions granted inside this platform. These are some common problems across VCS platforms that attacker could abuse:
|
||||
Platforms, що містять source code вашого проєкту, містять sensitive information, і люди мають бути дуже обережними з permissions, наданими в цій platform. Ось деякі поширені проблеми на VCS platforms, які attacker може використати:
|
||||
|
||||
- **Leaks**: If your code contains leaks in the commits and the attacker can access the repo (because it's public or because he has access), he could discover the leaks.
|
||||
- **Access**: If an attacker can **access to an account inside the VCS platform** he could gain **more visibility and permissions**.
|
||||
- **Register**: Some platforms will just allow external users to create an account.
|
||||
- **SSO**: Some platforms won't allow users to register, but will allow anyone to access with a valid SSO (so an attacker could use his github account to enter for example).
|
||||
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... there are several kind of tokens a user could steal to access in some way a repo.
|
||||
- **Webhooks**: VCS platforms allow to generate webhooks. If they are **not protected** with non visible secrets an **attacker could abuse them**.
|
||||
- If no secret is in place, the attacker could abuse the webhook of the third party platform
|
||||
- If the secret is in the URL, the same happens and the attacker also have the secret
|
||||
- **Code compromise:** If a malicious actor has some kind of **write** access over the repos, he could try to **inject malicious code**. In order to be successful he might need to **bypass branch protections**. These actions can be performed with different goals in mid:
|
||||
- Compromise the main branch to **compromise production**.
|
||||
- Compromise the main (or other branches) to **compromise developers machines** (as they usually execute test, terraform or other things inside the repo in their machines).
|
||||
- **Compromise the pipeline** (check next section)
|
||||
- **Leaks**: Якщо ваш code містить leaks у commits, і attacker може отримати доступ до repo (бо воно public або бо він має access), він може виявити leaks.
|
||||
- **Access**: Якщо attacker може **access to an account inside the VCS platform**, він може отримати **більше visibility and permissions**.
|
||||
- **Register**: Деякі platforms просто дозволяють external users створювати account.
|
||||
- **SSO**: Деякі platforms не дозволять users реєструватися, але дозволять будь-кому отримати access із valid SSO (тому attacker може використати, наприклад, свій github account, щоб увійти).
|
||||
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... є кілька видів tokens, які user може вкрасти, щоб у якийсь спосіб отримати access до repo.
|
||||
- **Webhooks**: VCS platforms дозволяють генерувати webhooks. Якщо вони **не захищені** невидимими secrets, **attacker could abuse them**.
|
||||
- Якщо secret відсутній, attacker може використати webhook third party platform
|
||||
- Якщо secret знаходиться в URL, відбувається те саме, і attacker також має secret
|
||||
- **Code compromise:** Якщо malicious actor має якийсь **write** access до repos, він може спробувати **inject malicious code**. Щоб досягти успіху, йому може знадобитися **bypass branch protections**. Ці дії можна виконати з різними цілями:
|
||||
- Compromise main branch, щоб **compromise production**.
|
||||
- Compromise main (або інші branches), щоб **compromise developers machines** (оскільки вони зазвичай запускають test, terraform або інші речі всередині repo на своїх машинах).
|
||||
- **Compromise the pipeline** (див. наступний розділ)
|
||||
|
||||
## Pipelines Pentesting Methodology
|
||||
|
||||
The most common way to define a pipeline, is by using a **CI configuration file hosted in the repository** the pipeline builds. This file describes the order of executed jobs, conditions that affect the flow, and build environment settings.\
|
||||
These files typically have a consistent name and format, for example — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), and the GitHub Actions YAML files located under .github/workflows. When triggered, the pipeline job **pulls the code** from the selected source (e.g. commit / branch), and **runs the commands specified in the CI configuration file** against that code.
|
||||
Найпоширеніший спосіб визначити pipeline — це використання **CI configuration file hosted in the repository**, який pipeline будує. Цей file описує порядок виконуваних jobs, conditions, що впливають на flow, і build environment settings.\
|
||||
Такі files зазвичай мають сталу назву й формат, наприклад — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), а також GitHub Actions YAML files, розміщені в .github/workflows. Коли pipeline запускається, job pipeline **pulls the code** із вибраного source (наприклад, commit / branch) і **runs the commands specified in the CI configuration file** проти цього code.
|
||||
|
||||
Therefore the ultimate goal of the attacker is to somehow **compromise those configuration files** or the **commands they execute**.
|
||||
Отже, кінцева мета attacker — у якийсь спосіб **compromise those configuration files** або **the commands they execute**.
|
||||
|
||||
> [!TIP]
|
||||
> Some hosted builders let contributors choose the Docker build context and Dockerfile path. If the context is attacker-controlled, you may set it outside the repo (e.g., "..") to ingest host files during build and exfiltrate secrets. See:
|
||||
> Деякі hosted builders дозволяють contributors вибирати Docker build context і Dockerfile path. Якщо context під контролем attacker, він може вказати його поза repo (наприклад, ".."), щоб під час build зчитати host files і exfiltrate secrets. Див.:
|
||||
>
|
||||
>{{#ref}}
|
||||
>docker-build-context-abuse.md
|
||||
@@ -58,72 +58,73 @@ Therefore the ultimate goal of the attacker is to somehow **compromise those con
|
||||
|
||||
### PPE - Poisoned Pipeline Execution
|
||||
|
||||
The Poisoned Pipeline Execution (PPE) path exploits permissions in an SCM repository to manipulate a CI pipeline and execute harmful commands. Users with the necessary permissions can modify CI configuration files or other files used by the pipeline job to include malicious commands. This "poisons" the CI pipeline, leading to the execution of these malicious commands.
|
||||
Шлях Poisoned Pipeline Execution (PPE) використовує permissions у SCM repository, щоб маніпулювати CI pipeline і виконувати шкідливі commands. Users із необхідними permissions можуть змінювати CI configuration files або інші files, які використовуються pipeline job, щоб додати malicious commands. Це "poisons" CI pipeline, що призводить до виконання цих malicious commands.
|
||||
|
||||
For a malicious actor to be successful performing a PPE attack he needs to be able to:
|
||||
Щоб malicious actor успішно виконав PPE attack, йому потрібно:
|
||||
|
||||
- Have **write access to the VCS platform**, as usually pipelines are triggered when a push or a pull request is performed. (Check the VCS pentesting methodology for a summary of ways to get access).
|
||||
- Note that sometimes an **external PR count as "write access"**.
|
||||
- Even if he has write permissions, he needs to be sure he can **modify the CI config file or other files the config is relying on**.
|
||||
- For this, he might need to be able to **bypass branch protections**.
|
||||
- Мати **write access до VCS platform**, оскільки зазвичай pipelines запускаються, коли виконується push або pull request. (Перевірте VCS pentesting methodology для стислого огляду способів отримати access).
|
||||
- Зверніть увагу, що іноді **external PR count as "write access"**.
|
||||
- Навіть маючи write permissions, він має переконатися, що може **modify CI config file або інші files, на які config спирається**.
|
||||
- Для цього йому може знадобитися **bypass branch protections**.
|
||||
|
||||
There are 3 PPE flavours:
|
||||
Є 3 PPE flavour:
|
||||
|
||||
- **D-PPE**: A **Direct PPE** attack occurs when the actor **modifies the CI config** file that is going to be executed.
|
||||
- **I-DDE**: An **Indirect PPE** attack occurs when the actor **modifies** a **file** the CI config file that is going to be executed **relays on** (like a make file or a terraform config).
|
||||
- **Public PPE or 3PE**: In some cases the pipelines can be **triggered by users that doesn't have write access in the repo** (and that might not even be part of the org) because they can send a PR.
|
||||
- **3PE Command Injection**: Usually, CI/CD pipelines will **set environment variables** with **information about the PR**. If that value can be controlled by an attacker (like the title of the PR) and is **used** in a **dangerous place** (like executing **sh commands**), an attacker might **inject commands in there**.
|
||||
- **D-PPE**: Атака **Direct PPE** відбувається, коли actor **modifies the CI config** file, який буде виконано.
|
||||
- **I-DDE**: Атака **Indirect PPE** відбувається, коли actor **modifies** **file**, на який **relies on** CI config file, який буде виконано (наприклад, make file або terraform config).
|
||||
- **Public PPE or 3PE**: У деяких випадках pipelines можуть бути **triggered by users that doesn't have write access in the repo** (і які можуть навіть не бути частиною org), тому що вони можуть надіслати PR.
|
||||
- **3PE Command Injection**: Зазвичай CI/CD pipelines **set environment variables** з **information about the PR**. Якщо attacker може керувати таким значенням (наприклад, title PR) і воно **used** у **dangerous place** (наприклад, виконання **sh commands**), attacker може **inject commands in there**.
|
||||
|
||||
### Exploitation Benefits
|
||||
|
||||
Knowing the 3 flavours to poison a pipeline, lets check what an attacker could obtain after a successful exploitation:
|
||||
Знаючи 3 flavour для poisoning pipeline, подивимось, що attacker може отримати після успішної exploitation:
|
||||
|
||||
- **Secrets**: As it was mentioned previously, pipelines require **privileges** for their jobs (retrieve the code, build it, deploy it...) and this privileges are usually **granted in secrets**. These secrets are usually accessible via **env variables or files inside the system**. Therefore an attacker will always try to exfiltrate as much secrets as possible.
|
||||
- Depending on the pipeline platform the attacker **might need to specify the secrets in the config**. This means that is the attacker cannot modify the CI configuration pipeline (**I-PPE** for example), he could **only exfiltrate the secrets that pipeline has**.
|
||||
- **Computation**: The code is executed somewhere, depending on where is executed an attacker might be able to pivot further.
|
||||
- **On-Premises**: If the pipelines are executed on premises, an attacker might end in an **internal network with access to more resources**.
|
||||
- **Cloud**: The attacker could access **other machines in the cloud** but also could **exfiltrate** IAM roles/service accounts **tokens** from it to obtain **further access inside the cloud**.
|
||||
- **Platforms machine**: Sometimes the jobs will be execute inside the **pipelines platform machines**, which usually are inside a cloud with **no more access**.
|
||||
- **Select it:** Sometimes the **pipelines platform will have configured several machines** and if you can **modify the CI configuration file** you can **indicate where you want to run the malicious code**. In this situation, an attacker will probably run a reverse shell on each possible machine to try to exploit it further.
|
||||
- **Compromise production**: If you ware inside the pipeline and the final version is built and deployed from it, you could **compromise the code that is going to end running in production**.
|
||||
- **Secrets**: Як уже згадувалося, pipelines потребують **privileges** для своїх jobs (retrieve the code, build it, deploy it...) і ці privileges зазвичай **granted in secrets**. Такі secrets зазвичай доступні через **env variables або files inside the system**. Тому attacker завжди намагатиметься exfiltrate якомога більше secrets.
|
||||
- Залежно від pipeline platform attacker **might need to specify the secrets in the config**. Це означає, що якщо attacker не може змінити CI configuration pipeline (**I-PPE**, наприклад), він може **лише exfiltrate ті secrets, які має цей pipeline**.
|
||||
- **Computation**: Code виконується десь; залежно від того, де саме, attacker може просунутися далі.
|
||||
- **On-Premises**: Якщо pipelines виконуються on premises, attacker може опинитися в **internal network з access до більшої кількості ресурсів**.
|
||||
- **Cloud**: Attacker може отримати access до **other machines in the cloud**, але також може **exfiltrate** IAM roles/service accounts **tokens** звідти, щоб отримати **further access inside the cloud**.
|
||||
- **Platforms machine**: Іноді jobs виконуватимуться всередині **pipelines platform machines**, які зазвичай знаходяться в cloud із **no more access**.
|
||||
- **Select it:** Іноді **pipelines platform will have configured several machines** і якщо ви можете **modify the CI configuration file**, ви можете **indicate where you want to run the malicious code**. У такій ситуації attacker, ймовірно, запустить reverse shell на кожній можливої машині, щоб спробувати просунути атаку далі.
|
||||
- **Compromise production**: Якщо ви ware inside the pipeline і фінальна версія збирається та deploy з нього, ви можете **compromise the code that is going to end running in production**.
|
||||
|
||||
### Dependency & Registry Supply-Chain Abuse
|
||||
|
||||
Compromising a CI/CD pipeline or stealing credentials from it can let an attacker move from **pipeline execution** to **ecosystem-wide code execution** by backdooring dependencies or release tooling:
|
||||
Compromising CI/CD pipeline або stealing credentials із нього може дозволити attacker перейти від **pipeline execution** до **ecosystem-wide code execution** шляхом backdooring dependencies або release tooling:
|
||||
|
||||
- **Install-time code execution via package hooks**: publish a package version that adds `preinstall`, `postinstall`, `prepare`, or similar hooks so the payload runs automatically on developer workstations and CI runners during dependency installation.
|
||||
- **Secondary execution paths**: even if targets install with `--ignore-scripts`, a malicious package can still register a **common CLI name** in the `bin` field so the attacker-controlled wrapper is symlinked into `PATH` and executes later when the command is used.
|
||||
- **Runtime bootstrapping**: a small installer can download a second runtime or toolchain during installation (for example Bun or a packed interpreter) and then launch the main payload with it, avoiding local dependency requirements.
|
||||
- **Credential harvesting from build environments**: once code runs inside CI, check environment variables, `~/.npmrc`, `~/.git-credentials`, SSH keys, cloud CLI configs, and local tooling such as `gh auth token`. On GitHub Actions, also look for runner-specific secrets and artifacts.
|
||||
- **Workflow injection with stolen GitHub tokens**: a token with **`repo` + `workflow`** permissions is enough to create a branch, commit a malicious file inside `.github/workflows/`, trigger it, collect the produced artifacts/logs, and then delete the temporary branch/workflow run to reduce traces.
|
||||
- **Wormable registry propagation**: stolen npm tokens should be validated for **publish** permissions and whether they bypass 2FA. If they do, enumerate writable packages, download their tarballs, inject a loader such as `setup.mjs`, set `preinstall` to execute it, bump the patch version, and republish. This turns one CI compromise into downstream auto-execution in other environments.
|
||||
- **Install-time code execution via package hooks**: publish package version, яка додає `preinstall`, `postinstall`, `prepare` або схожі hooks, щоб payload автоматично запускався на developer workstations і CI runners під час dependency installation.
|
||||
- **Secondary execution paths**: навіть якщо targets встановлюють із `--ignore-scripts`, malicious package все одно може зареєструвати **common CLI name** у полі `bin`, щоб wrapper під контролем attacker було symlinked у `PATH` і він виконався пізніше, коли команду буде використано.
|
||||
- **Runtime bootstrapping**: невеликий installer може завантажити second runtime або toolchain під час installation (наприклад Bun або packed interpreter), а потім запустити з ним main payload, уникаючи локальних dependency requirements.
|
||||
- **Credential harvesting from build environments**: коли code виконується всередині CI, перевіряйте environment variables, `~/.npmrc`, `~/.git-credentials`, SSH keys, cloud CLI configs і local tooling, наприклад `gh auth token`. На GitHub Actions також шукайте runner-specific secrets і artifacts.
|
||||
- **Workflow injection with stolen GitHub tokens**: token із permissions **`repo` + `workflow`** достатньо, щоб створити branch, commit malicious file всередині `.github/workflows/`, trigger it, зібрати produced artifacts/logs, а потім видалити temporary branch/workflow run, щоб зменшити сліди.
|
||||
- **Wormable registry propagation**: stolen npm tokens слід перевіряти на **publish** permissions і на те, чи обходять вони 2FA. Якщо так, перелічіть writable packages, завантажте їх tarballs, inject loader, наприклад `setup.mjs`, set `preinstall` щоб виконати його, підвищте patch version і republish. Це перетворює одне CI compromise на downstream auto-execution в інших environments.
|
||||
|
||||
#### Practical checks during an assessment
|
||||
|
||||
- Review release automation for package-manager hooks added to `package.json`, unexpected `bin` entries, or version bumps that only modify the release artifact.
|
||||
- Check whether CI stores long-lived registry credentials in plaintext files such as `~/.npmrc` instead of using short-lived OIDC or trusted publishing.
|
||||
- Verify whether GitHub tokens available in CI can write workflow files or create branches/tags.
|
||||
- If a compromised package is suspected, inspect the published tarball and not only the Git repository, because the malicious loader/runtime may exist only in the published artifact.
|
||||
- Hunt for unexpected package-manager execution inside CI such as `npm install` instead of `npm ci`, unexpected Bun downloads/execution, or new workflow artifacts generated from transient branches.
|
||||
- Перегляньте release automation на наявність package-manager hooks, доданих до `package.json`, unexpected `bin` entries або version bumps, які змінюють лише release artifact.
|
||||
- Перевірте, чи CI зберігає long-lived registry credentials у plaintext files, таких як `~/.npmrc`, замість використання short-lived OIDC або trusted publishing.
|
||||
- Переконайтеся, чи GitHub tokens, доступні в CI, можуть записувати workflow files або створювати branches/tags.
|
||||
- Якщо підозрюється compromised package, перевірте published tarball, а не лише Git repository, тому що malicious loader/runtime може існувати лише в published artifact.
|
||||
- Шукайте unexpected package-manager execution усередині CI, наприклад `npm install` замість `npm ci`, unexpected Bun downloads/execution або нові workflow artifacts, згенеровані з transient branches.
|
||||
- Також розглядайте GitOps deployment engines як CI/CD targets. Специфічні для Argo CD enumeration, repo-server abuse і Redis cache poisoning attacks описані в [Argo CD Security](argocd-security.md).
|
||||
|
||||
## More relevant info
|
||||
|
||||
### Tools & CIS Benchmark
|
||||
|
||||
- [**Chain-bench**](https://github.com/aquasecurity/chain-bench) is an open-source tool for auditing your software supply chain stack for security compliance based on a new [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf). The auditing focuses on the entire SDLC process, where it can reveal risks from code time into deploy time.
|
||||
- [**Chain-bench**](https://github.com/aquasecurity/chain-bench) — це open-source tool для аудиту вашого software supply chain stack на відповідність security compliance на основі нового [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf). Аудит зосереджений на всьому процесі SDLC, де він може виявити risks від code time до deploy time.
|
||||
|
||||
### Top 10 CI/CD Security Risk
|
||||
|
||||
Check this interesting article about the top 10 CI/CD risks according to Cider: [**https://www.cidersecurity.io/top-10-cicd-security-risks/**](https://www.cidersecurity.io/top-10-cicd-security-risks/)
|
||||
Перегляньте цю цікаву статтю про top 10 CI/CD risks за версією Cider: [**https://www.cidersecurity.io/top-10-cicd-security-risks/**](https://www.cidersecurity.io/top-10-cicd-security-risks/)
|
||||
|
||||
### Labs
|
||||
|
||||
- On each platform that you can run locally you will find how to launch it locally so you can configure it as you want to test it
|
||||
- На кожній platform, яку можна запускати локально, ви знайдете, як запустити її локально, щоб налаштувати її так, як потрібно для тесту
|
||||
- Gitea + Jenkins lab: [https://github.com/cider-security-research/cicd-goat](https://github.com/cider-security-research/cicd-goat)
|
||||
|
||||
### Automatic Tools
|
||||
|
||||
- [**Checkov**](https://github.com/bridgecrewio/checkov): **Checkov** is a static code analysis tool for infrastructure-as-code.
|
||||
- [**Checkov**](https://github.com/bridgecrewio/checkov): **Checkov** — це static code analysis tool для infrastructure-as-code.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
Reference in New Issue
Block a user