Translated ['', 'src/pentesting-ci-cd/pentesting-ci-cd-methodology.md']

This commit is contained in:
Translator
2026-04-27 23:29:47 +00:00
parent 28e8af6704
commit 2ab31b2df5

View File

@@ -1,4 +1,4 @@
# Pentesting CI/CD Methodology
# Metodologia de Pentesting em CI/CD
{{#include ../banners/hacktricks-training.md}}
@@ -6,51 +6,51 @@
## VCS
VCS significa **Version Control System**, estes sistemas permitem aos desenvolvedores **gerir o seu source code**. O mais comum é o **git** e normalmente encontrarás empresas a usálo numa das seguintes **plataformas**:
VCS significa **Version Control System**, este systems permite que developers **gerenciem seu source code**. O mais comum é **git** e você normalmente encontrará empresas usando-o em uma das seguintes **platforms**:
- Github
- Gitlab
- Bitbucket
- Gitea
- Gitblit
- Cloud providers (they offer their own VCS platforms)
- Cloud providers (eles oferecem suas próprias plataformas VCS)
## CI/CD Pipelines
CI/CD pipelines permitem aos desenvolvedores **automatizar a execução de code** para vários propósitos, incluindo build, testes e deploy de aplicações. Estes workflows automatizados são **disparados por ações específicas**, como pushes de code, pull requests, ou tarefas agendadas. São úteis para simplificar o processo do desenvolvimento até a produção.
CI/CD pipelines permitem que developers **automatizem a execução de code** para vários propósitos, incluindo build, testing e deploying applications. Esses workflows automatizados são **disparados por ações específicas**, como code pushes, pull requests ou tarefas agendadas. Eles são úteis para simplificar o processo do development até production.
No entanto, estes sistemas precisam de ser **executados em algum lugar** e geralmente com **credenciais privilegiadas para deploy de code ou acesso a informação sensível**.
No entanto, esses systems precisam ser **executados em algum lugar** e normalmente com **privileged credentials para deploy code ou acessar information sensível**.
## VCS Pentesting Methodology
> [!NOTE]
> Even if some VCS platforms allow to create pipelines for this section we are going to analyze only potential attacks to the control of the source code.
> Mesmo que algumas plataformas VCS permitam criar pipelines, para esta seção vamos analisar apenas attacks potenciais ao controle do source code.
Plataformas que contêm o source code do teu projeto têm informação sensível e é preciso ter muito cuidado com as permissões concedidas dentro desta plataforma. Estes são alguns problemas comuns across VCS platforms que um atacante poderia abusar:
Platforms que contêm o source code do seu projeto contêm information sensível e as pessoas precisam ter muito cuidado com as permissions concedidas dentro dessa plataforma. Estes são alguns problemas comuns entre platforms VCS que um attacker poderia abusar:
- **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).
- **Leaks**: Se seu code contém leaks nos commits e o attacker consegue acessar o repo (porque ele é público ou porque ele tem acesso), ele pode descobrir os leaks.
- **Access**: Se um attacker consegue **access a uma conta dentro da platform VCS** ele pode ganhar **mais visibility e permissions**.
- **Register**: Algumas platforms simplesmente permitem que usuários externos criem uma conta.
- **SSO**: Algumas platforms não permitem que users se registrem, mas permitem que qualquer um acesse com um SSO válido (então um attacker poderia usar sua conta github para entrar, por exemplo).
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... há vários tipos de tokens que um user poderia roubar para access de alguma forma um repo.
- **Webhooks**: Platforms VCS permitem gerar webhooks. Se eles **não estiverem protegidos** com secrets invisíveis, um **attacker poderia abusar deles**.
- Se nenhum secret estiver em place, o attacker pode abusar do webhook da plataforma de third party
- Se o secret estiver na URL, o mesmo acontece e o attacker também tem o secret
- **Code compromise:** Se um malicious actor tiver algum tipo de access de **write** aos repos, ele poderia tentar **inject malicious code**. Para ser bem-sucedido, ele talvez precise **bypass branch protections**. Essas ações podem ser realizadas com diferentes goals in mid:
- Compromise a main branch para **compromise production**.
- Compromise a main (ou outras branches) para **compromise developer machines** (já que eles normalmente executam test, terraform ou outras coisas dentro do repo em suas machines).
- **Compromise the pipeline** (check next section)
## 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.
A forma mais comum de definir um pipeline é usando um **CI configuration file hospedado no repository** que o pipeline builda. Este file descreve a ordem dos jobs executados, conditions que afetam o flow e settings do build environment.\
Esses files normalmente têm um nome e formato consistentes, por exemplo — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI) e os arquivos YAML do GitHub Actions localizados em .github/workflows. Quando disparado, o pipeline job **pulls the code** da source selecionada (por exemplo, commit / branch) e **executa os commands especificados no CI configuration file** contra esse code.
Therefore the ultimate goal of the attacker is to somehow **compromise those configuration files** or the **commands they execute**.
Portanto, o objetivo final do attacker é de alguma forma **compromise esses configuration files** ou os **commands que eles executam**.
> [!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:
> Alguns hosted builders permitem que contributors escolham o Docker build context e o caminho do Dockerfile. Se o context for controlado pelo attacker, você pode defini-lo fora do repo (por exemplo, "..") para ingerir host files durante o build e exfiltrar secrets. Veja:
>
>{{#ref}}
>docker-build-context-abuse.md
@@ -58,34 +58,53 @@ 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.
O caminho Poisoned Pipeline Execution (PPE) explora permissions em um repository SCM para manipular um CI pipeline e executar commands prejudiciais. Users com as permissions necessárias podem modificar CI configuration files ou outros files usados pelo pipeline job para incluir commands malicious. Isso “poisons” o CI pipeline, levando à execução desses commands malicious.
For a malicious actor to be successful performing a PPE attack he needs to be able to:
Para que um malicious actor tenha sucesso ao realizar um attack PPE, ele precisa ser capaz de:
- 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**.
- Ter **write access à platform VCS**, já que normalmente pipelines são disparados quando um push ou pull request é realizado. (Veja a VCS pentesting methodology para um resumo de formas de obter access).
- Observe que às vezes um **external PR conta como "write access"**.
- Mesmo tendo permissions de write, ele precisa ter certeza de que pode **modificar o CI config file ou outros files dos quais o config depende**.
- Para isso, talvez precise ser capaz de **bypass branch protections**.
There are 3 PPE flavours:
Há 3 variações de PPE:
- **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**: Um attack **Direct PPE** ocorre quando o actor **modifica o CI config** file que será executado.
- **I-DDE**: Um attack **Indirect PPE** ocorre quando o actor **modifica** um **file** do qual o CI config file que será executado **depende** (como um make file ou uma terraform config).
- **Public PPE or 3PE**: Em alguns casos, os pipelines podem ser **disparados por users que não têm write access no repo** (e que talvez nem façam parte da org) porque eles podem enviar um PR.
- **3PE Command Injection**: Normalmente, CI/CD pipelines vão **set environment variables** com **information sobre o PR**. Se esse value puder ser controlado por um attacker (como o title do PR) e for **usado** em um **local perigoso** (como executar **sh commands**), um attacker pode **inject commands ali**.
### Exploitation Benefits
Knowing the 3 flavours to poison a pipeline, lets check what an attacker could obtain after a successful exploitation:
Sabendo as 3 variações para poison um pipeline, vamos ver o que um attacker poderia obter após uma exploitation bem-sucedida:
- **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**: Como mencionado anteriormente, pipelines requerem **privileges** para seus jobs (retrieval do code, build, deploy...) e esses privileges normalmente são **concedidos em secrets**. Esses secrets normalmente ficam acessíveis via **env variables ou files dentro do system**. Portanto, um attacker sempre tentará exfiltrar o máximo de secrets possível.
- Dependendo da platform do pipeline, o attacker **pode precisar especificar os secrets na config**. Isso significa que, se o attacker não puder modificar o CI configuration pipeline (**I-PPE**, por exemplo), ele poderá **apenas exfiltrar os secrets que esse pipeline já possui**.
- **Computation**: O code é executado em algum lugar; dependendo de onde é executado, um attacker pode conseguir pivot further.
- **On-Premises**: Se os pipelines forem executados on premises, um attacker pode acabar em uma **internal network com access a mais resources**.
- **Cloud**: O attacker pode acessar **other machines in the cloud** mas também pode **exfiltrate** tokens de IAM roles/service accounts **delas** para obter **further access dentro da cloud**.
- **Platforms machine**: Às vezes, os jobs serão executados dentro das **machines da platform de pipelines**, que normalmente estão dentro de uma cloud com **no more access**.
- **Select it:** Às vezes a **platform de pipelines terá várias machines configuradas** e, se você puder **modificar o CI configuration file**, poderá **indicar onde quer executar o malicious code**. Nessa situação, um attacker provavelmente executará uma reverse shell em cada machine possível para tentar explorá-la further.
- **Compromise production**: Se você estiver dentro do pipeline e a versão final for buildada e deployed a partir dele, você poderá **compromise o code que vai acabar rodando em production**.
### Dependency & Registry Supply-Chain Abuse
Compromising um CI/CD pipeline ou roubando credentials dele pode permitir que um attacker passe de **pipeline execution** para **ecosystem-wide code execution** ao backdooring dependencies ou release tooling:
- **Install-time code execution via package hooks**: publique uma versão de package que adicione hooks `preinstall`, `postinstall`, `prepare` ou similares para que o payload rode automaticamente em developer workstations e CI runners durante a installation de dependencies.
- **Secondary execution paths**: mesmo que targets instalem com `--ignore-scripts`, um malicious package ainda pode registrar um **common CLI name** no field `bin`, fazendo com que o wrapper controlado pelo attacker seja symlinked para `PATH` e execute depois, quando o command for usado.
- **Runtime bootstrapping**: um pequeno installer pode baixar uma segunda runtime ou toolchain durante a installation (por exemplo Bun ou um interpreter empacotado) e então iniciar o main payload com ela, evitando requirements locais de dependency.
- **Credential harvesting from build environments**: uma vez que o code rode dentro do CI, verifique environment variables, `~/.npmrc`, `~/.git-credentials`, SSH keys, cloud CLI configs e tooling local como `gh auth token`. No GitHub Actions, procure também secrets e artifacts específicos do runner.
- **Workflow injection with stolen GitHub tokens**: um token com permissions **`repo` + `workflow`** é suficiente para criar uma branch, fazer commit de um file malicious dentro de `.github/workflows/`, dispará-lo, coletar os artifacts/logs produzidos e depois deletar a branch temporária / workflow run para reduzir traces.
- **Wormable registry propagation**: npm tokens roubados devem ser validados para permissions de **publish** e para saber se contornam 2FA. Se sim, enumere packages graváveis, baixe seus tarballs, injete um loader como `setup.mjs`, defina `preinstall` para executá-lo, aumente a patch version e republique. Isso transforma um único compromise de CI em auto-execution downstream em outros environments.
#### Practical checks during an assessment
- Revise a automação de release para hooks de package-manager adicionados ao `package.json`, entradas `bin` inesperadas ou bumps de version que alteram apenas o release artifact.
- Verifique se o CI armazena credentials de registry de longa duração em files plaintext como `~/.npmrc` em vez de usar OIDC de curta duração ou trusted publishing.
- Verifique se tokens do GitHub disponíveis no CI podem escrever workflow files ou criar branches/tags.
- Se suspeitar de um package compromise, inspecione o tarball publicado e não apenas o Git repository, porque o malicious loader/runtime pode existir apenas no published artifact.
- Procure por execução inesperada de package-manager dentro do CI, como `npm install` em vez de `npm ci`, downloads/execução inesperados de Bun, ou novos workflow artifacts gerados a partir de branches transitórias.
## More relevant info
@@ -109,6 +128,8 @@ Check this interesting article about the top 10 CI/CD risks according to Cider:
## References
- [https://www.cidersecurity.io/blog/research/ppe-poisoned-pipeline-execution/?utm_source=github\&utm_medium=github_page\&utm_campaign=ci%2fcd%20goat_060422](https://www.cidersecurity.io/blog/research/ppe-poisoned-pipeline-execution/?utm_source=github&utm_medium=github_page&utm_campaign=ci%2fcd%20goat_060422)
- [The npm Threat Landscape: Attack Surface and Mitigations](https://unit42.paloaltonetworks.com/monitoring-npm-supply-chain-attacks/)
- [Checkmarx Security Update: April 22, 2026](https://checkmarx.com/blog/checkmarx-security-update-april-22/?p=108469)
{{#include ../banners/hacktricks-training.md}}