Metodologia de Pentesting de CI/CD

Tip

Aprenda e pratique AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoie o HackTricks

VCS

VCS significa Version Control System, este sistema permite aos desenvolvedores gerenciar seu código-fonte. O mais comum é git e você normalmente encontrará empresas usando-o em uma das seguintes plataformas:

  • Github
  • Gitlab
  • Bitbucket
  • Gitea
  • Gitblit
  • Cloud providers (eles oferecem suas próprias plataformas VCS)

CI/CD Pipelines

CI/CD pipelines permitem que desenvolvedores automatizem a execução de código para vários propósitos, incluindo build, test e deployment de aplicações. Esses workflows automatizados são acionados por ações específicas, como code pushes, pull requests ou tarefas agendadas. Eles são úteis para simplificar o processo de development até production.

No entanto, esses sistemas precisam ser executados em algum lugar e normalmente com credenciais privilegiadas para deploy de código ou acesso a informações sensíveis.

Metodologia de Pentesting em VCS

Note

Mesmo que algumas plataformas VCS permitam criar pipelines, para esta seção vamos analisar apenas ataques potenciais ao controle do código-fonte.

Plataformas que contêm o código-fonte do seu projeto contêm informações sensíveis e as pessoas precisam ser muito cuidadosas com as permissões concedidas dentro dessa plataforma. Estes são alguns problemas comuns em plataformas VCS que um attacker pode abusar:

  • Leaks: Se seu código 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 acessar uma conta dentro da plataforma VCS ele pode obter mais visibility e permissions.
  • Register: Algumas plataformas simplesmente permitem que usuários externos criem uma conta.
  • SSO: Algumas plataformas não permitem que usuários se cadastrem, mas permitem que qualquer pessoa acesse com um SSO válido (então um attacker poderia usar sua conta do github para entrar, por exemplo).
  • Credentials: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies… há vários tipos de tokens que um user pode roubar para acessar de alguma forma um repo.
  • Webhooks: Plataformas VCS permitem gerar webhooks. Se eles não estiverem protegidos com secrets não visíveis, um attacker pode abusar deles.
  • Se nenhum secret estiver configurado, o attacker pode abusar do webhook da plataforma third party
  • Se o secret estiver na URL, o mesmo acontece e o attacker também terá o secret
  • Code compromise: Se um malicious actor tiver algum tipo de acesso de write aos repos, ele pode tentar injetar malicious code. Para ter sucesso, ele pode precisar bypassar branch protections. Essas ações podem ser realizadas com diferentes objetivos em mente:
  • Comprometer a main branch para comprometer production.
  • Comprometer a main (ou outras branches) para comprometer as máquinas dos developers (pois eles normalmente executam test, terraform ou outras coisas dentro do repo em suas máquinas).
  • Comprometer o pipeline (veja a próxima seção)

Metodologia de Pentesting de Pipelines

A forma mais comum de definir um pipeline é usando um CI configuration file hospedado no repository que o pipeline builda. Esse arquivo descreve a ordem dos jobs executados, as conditions que afetam o flow e as configurações do ambiente de build.
Esses arquivos 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 acionado, o job do pipeline faz pull do code da source selecionada (por exemplo, commit / branch) e executa os commands especificados no CI configuration file contra esse code.

Portanto, o objetivo final do attacker é de alguma forma comprometer esses configuration files ou os commands que eles executam.

Tip

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 {{#endref}}

PPE - Poisoned Pipeline Execution

O caminho Poisoned Pipeline Execution (PPE) explora permissions em um repository SCM para manipular um pipeline CI e executar commands maliciosos. Users com as permissions necessárias podem modificar CI configuration files ou outros files usados pelo job do pipeline para incluir commands maliciosos. Isso “envenena” o CI pipeline, levando à execução desses commands maliciosos.

Para um malicious actor ter sucesso ao realizar um ataque PPE, ele precisa ser capaz de:

  • Ter write access à plataforma VCS, já que normalmente os pipelines são acionados quando ocorre um push ou um pull request. (Veja a metodologia de pentesting em VCS para um resumo das formas de obter acesso).
  • Note que às vezes um external PR conta como “write access”.
  • Mesmo tendo write permissions, ele precisa ter certeza de que consegue modificar o CI config file ou outros files dos quais o config depende.
  • Para isso, ele pode precisar ser capaz de bypassar branch protections.

Há 3 variações de PPE:

  • D-PPE: Um ataque Direct PPE ocorre quando o actor modifica o CI config file que será executado.
  • I-DDE: Um ataque 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 acionados 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 definir environment variables com informações sobre o PR. Se esse valor puder ser controlado por um attacker (como o título do PR) e for usado em um lugar perigoso (como executar sh commands), um attacker pode injetar commands ali.

Benefícios da Exploitation

Conhecendo as 3 variações para envenenar um pipeline, vamos ver o que um attacker pode obter após uma exploitation bem-sucedida:

  • Secrets: Como mencionado anteriormente, pipelines exigem privileges para seus jobs (obter o code, buildá-lo, fazer deploy…) e esses privileges normalmente são concedidos em secrets. Esses secrets normalmente são acessíveis via env variables ou files dentro do sistema. Portanto, um attacker sempre tentará exfiltrar o máximo de secrets possível.
  • Dependendo da plataforma de pipeline, o attacker pode precisar especificar os secrets no config. Isso significa que, se o attacker não puder modificar o CI configuration pipeline (I-PPE, por exemplo), ele só poderá exfiltrar os secrets que esse pipeline possui.
  • Computation: O code é executado em algum lugar, dependendo de onde for executado um attacker pode conseguir fazer pivot further.
  • On-Premises: Se os pipelines forem executados on premises, um attacker pode acabar em uma internal network com acesso a mais resources.
  • Cloud: O attacker poderia acessar outras machines na cloud mas também poderia exfiltrar IAM roles/service accounts tokens de lá para obter further access dentro da cloud.
  • Platforms machine: Às vezes os jobs serão executados dentro das pipelines platform machines, que normalmente estão em uma cloud com no more access.
  • Select it: Às vezes a pipelines platform 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á um reverse shell em cada máquina 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á comprometer o code que vai acabar sendo executado em production.

Dependency & Registry Supply-Chain Abuse

Comprometer um CI/CD pipeline ou roubar credenciais dele pode permitir que um attacker vá de pipeline execution para ecosystem-wide code execution ao inserir backdoor em dependencies ou ferramentas de release:

  • Install-time code execution via package hooks: publicar uma versão do package que adiciona hooks preinstall, postinstall, prepare ou similares para que o payload rode automaticamente em workstations de developers e CI runners durante a instalação de dependencies.
  • Secondary execution paths: mesmo que os targets instalem com --ignore-scripts, um package malicioso ainda pode registrar um common CLI name no campo bin, fazendo com que o wrapper controlado pelo attacker seja linked por symlink em PATH e executado depois quando o command for usado.
  • Runtime bootstrapping: um pequeno installer pode baixar um segundo runtime ou toolchain durante a instalação (por exemplo Bun ou um interpreter empacotado) e então lançar o main payload com ele, evitando dependências locais.
  • 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 ferramentas locais 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 permissões repo + workflow é suficiente para criar uma branch, fazer commit de um file malicioso dentro de .github/workflows/, acioná-lo, coletar os artifacts/logs produzidos e depois apagar a branch/workflow run temporária para reduzir rastros.
  • Wormable registry propagation: tokens do npm roubados devem ser validados quanto a permissões de publish e se contornam 2FA. Se contornarem, enumere packages graváveis, baixe seus tarballs, injete um loader como setup.mjs, defina preinstall para executá-lo, incremente a patch version e publique novamente. Isso transforma um comprometimento de CI em auto-execution downstream em outros ambientes.

Verificações práticas durante uma avaliação

  • Revise a automação de release em busca de hooks de package-manager adicionados ao package.json, entradas bin inesperadas ou bumps de versão que modificam apenas o release artifact.
  • Verifique se o CI armazena credenciais de registry de longa duração em files em texto puro 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 houver suspeita de um package comprometido, inspecione o tarball publicado e não apenas o Git repository, porque o loader/runtime malicioso pode existir apenas no artifact publicado.
  • Procure 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.

Mais informações relevantes

Tools & CIS Benchmark

  • Chain-bench é uma ferramenta open-source para auditar sua software supply chain stack quanto à conformidade de segurança com base em um novo CIS Software Supply Chain benchmark. A auditoria se concentra em todo o processo de SDLC, onde pode revelar riscos desde o code time até o deploy time.

Top 10 CI/CD Security Risk

Confira este artigo interessante sobre os top 10 riscos de CI/CD segundo a Cider: https://www.cidersecurity.io/top-10-cicd-security-risks/

Labs

Automatic Tools

  • Checkov: Checkov é uma ferramenta de static code analysis para infrastructure-as-code.

References

Tip

Aprenda e pratique AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoie o HackTricks