13 KiB
Metodologia Pentesting CI/CD
{{#include ../banners/hacktricks-training.md}}
VCS
VCS sta per Version Control System, questi sistemi permettono agli sviluppatori di gestire il proprio codice sorgente. Il più comune è git e di solito troverai aziende che lo usano in una delle seguenti platforms:
- Github
- Gitlab
- Bitbucket
- Gitea
- Gitblit
- Cloud providers (offrono le proprie piattaforme VCS)
CI/CD Pipelines
I CI/CD pipelines permettono agli sviluppatori di automatizzare l'esecuzione del codice per vari scopi, inclusi build, test e deploy delle applicazioni. Questi workflow automatizzati sono attivati da azioni specifiche, come push di codice, pull request o task pianificati. Sono utili per snellire il processo dallo sviluppo alla produzione.
Tuttavia, questi sistemi devono essere eseguiti da qualche parte e di solito con credenziali privilegiate per deployare il codice o accedere a informazioni sensibili.
VCS Pentesting Methodology
Note
Anche se alcune platforms VCS consentono di creare pipeline, per questa sezione analizzeremo solo i possibili attacchi al controllo del codice sorgente.
Le platforms che contengono il codice sorgente del tuo progetto contengono informazioni sensibili e le persone devono essere molto attente con i permessi concessi dentro questa platform. Questi sono alcuni problemi comuni tra le platforms VCS che un attacker potrebbe abusare:
- Leaks: Se il tuo codice contiene leaks nei commit e l'attacker può accedere al repo (perché è pubblico o perché ha accesso), potrebbe scoprire i leaks.
- Access: Se un attacker può accedere a un account dentro la platform VCS potrebbe ottenere maggiore visibilità e permessi.
- Register: Alcune platforms permetteranno semplicemente agli utenti esterni di creare un account.
- SSO: Alcune platforms non permetteranno agli utenti di registrarsi, ma consentiranno a chiunque di accedere con un SSO valido (quindi un attacker potrebbe usare il suo account github per entrare, ad esempio).
- Credentials: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... ci sono diversi tipi di token che un user potrebbe rubare per accedere in qualche modo a un repo.
- Webhooks: Le platforms VCS permettono di generare webhooks. Se non sono protetti con secret non visibili, un attacker potrebbe abusarne.
- Se non è presente alcun secret, l'attacker potrebbe abusare del webhook della third party platform
- Se il secret è nell'URL, accade lo stesso e l'attacker ha anche il secret
- Code compromise: Se un malicious actor ha qualche tipo di accesso in write sui repo, potrebbe provare a iniettare codice malevolo. Per avere successo potrebbe dover bypassare le branch protections. Queste azioni possono essere eseguite con obiettivi diversi in mente:
- Compromettere la main branch per compromettere la produzione.
- Compromettere la main (o altre branches) per compromettere le macchine degli sviluppatori (poiché di solito eseguono test, terraform o altro dentro il repo sulle loro macchine).
- Compromettere la pipeline (check next section)
Pipelines Pentesting Methodology
Il modo più comune per definire una pipeline è usare un file di configurazione CI ospitato nel repository che la pipeline builda. Questo file descrive l'ordine dei job eseguiti, le condizioni che influenzano il flusso e le impostazioni dell'ambiente di build.
Questi file hanno tipicamente un nome e un formato coerenti, per esempio — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), e i file YAML di GitHub Actions situati sotto .github/workflows. Quando viene attivato, il job della pipeline scarica il codice dalla sorgente selezionata (ad es. commit / branch) e esegue i comandi specificati nel file di configurazione CI su quel codice.
Pertanto l'obiettivo finale dell'attacker è in qualche modo compromettere quei file di configurazione o i comandi che eseguono.
Tip
Alcuni builder hosted consentono ai contributor di scegliere il Docker build context e il path del Dockerfile. Se il context è controllato dall'attacker, può impostarlo fuori dal repo (ad esempio, "..") per ingestire file dell'host durante la build ed exfiltrare secrets. Vedi:
{{#ref}} docker-build-context-abuse.md {{#endref}}
PPE - Poisoned Pipeline Execution
Il percorso Poisoned Pipeline Execution (PPE) sfrutta i permessi in un repository SCM per manipolare una CI pipeline ed eseguire comandi dannosi. Gli utenti con i permessi necessari possono modificare i file di configurazione CI o altri file usati dal job della pipeline per includere comandi malevoli. Questo "avvelena" la CI pipeline, portando all'esecuzione di questi comandi malevoli.
Perché un malicious actor abbia successo nell'eseguire un attacco PPE, deve essere in grado di:
- Avere write access alla piattaforma VCS, poiché di solito le pipeline vengono attivate quando viene eseguito un push o una pull request. (Controlla la VCS pentesting methodology per un riepilogo dei modi per ottenere accesso).
- Nota che a volte una external PR conta come "write access".
- Anche se ha permessi di write, deve essere sicuro di poter modificare il file di config CI o altri file da cui dipende la config.
- Per questo, potrebbe dover essere in grado di bypassare le branch protections.
Ci sono 3 varianti di PPE:
- D-PPE: Un attacco Direct PPE si verifica quando l'attacker modifica il file CI config che verrà eseguito.
- I-DDE: Un attacco Indirect PPE si verifica quando l'attacker modifica un file su cui il file CI config che verrà eseguito fa affidamento (come un make file o una terraform config).
- Public PPE or 3PE: In alcuni casi le pipeline possono essere attivate da utenti che non hanno write access nel repo (e che potrebbero non far nemmeno parte dell'org) perché possono inviare una PR.
- 3PE Command Injection: Di solito, le pipeline CI/CD imposteranno variabili d'ambiente con informazioni sulla PR. Se quel valore può essere controllato da un attacker (come il titolo della PR) ed è usato in un punto pericoloso (come l'esecuzione di sh commands), un attacker potrebbe iniettare comandi lì dentro.
Exploitation Benefits
Sapendo le 3 varianti per avvelenare una pipeline, vediamo cosa potrebbe ottenere un attacker dopo un'exploitazione riuscita:
- Secrets: Come detto prima, le pipeline richiedono privilegi per i loro job (recuperare il codice, buildarlo, deployarlo...) e questi privilegi sono solitamente concessi in secrets. Questi secrets sono di solito accessibili tramite variabili d'ambiente o file dentro il sistema. Pertanto un attacker cercherà sempre di exfiltrare quanti più secrets possibile.
- A seconda della piattaforma della pipeline, l'attacker potrebbe dover specificare i secrets nella config. Questo significa che se l'attacker non può modificare la pipeline di configurazione CI (I-PPE ad esempio), potrebbe solo exfiltrare i secrets che quella pipeline ha.
- Computation: Il codice viene eseguito da qualche parte, a seconda di dove viene eseguito un attacker potrebbe essere in grado di pivotare ulteriormente.
- On-Premises: Se le pipeline vengono eseguite on premises, un attacker potrebbe finire in una rete interna con accesso a più risorse.
- Cloud: L'attacker potrebbe accedere ad altre macchine nel cloud ma potrebbe anche exfiltrare token IAM roles/service accounts da esse per ottenere ulteriore accesso dentro il cloud.
- Platforms machine: A volte i job verranno eseguiti dentro le macchine della platform delle pipeline, che di solito sono dentro un cloud con nessun altro accesso.
- Select it: A volte la platform delle pipeline avrà configurato diverse macchine e se puoi modificare il file di configurazione CI puoi indicare dove vuoi eseguire il codice malevolo. In questa situazione, un attacker probabilmente eseguirà una reverse shell su ogni macchina possibile per provare a sfruttarla ulteriormente.
- Compromise production: Se sei dentro la pipeline e la versione finale viene buildata e deployata da lì, potresti compromettere il codice che andrà in esecuzione in produzione.
Dependency & Registry Supply-Chain Abuse
Compromettere una CI/CD pipeline o rubarne le credenziali può permettere a un attacker di passare dall'esecuzione nella pipeline all'esecuzione di codice su tutta l'ecosystem inserendo backdoor nelle dependencies o negli strumenti di release:
- Install-time code execution via package hooks: pubblica una versione del package che aggiunge hook come
preinstall,postinstall,prepareo simili, così il payload viene eseguito automaticamente sulle workstation degli sviluppatori e sui CI runners durante l'installazione delle dependencies. - Secondary execution paths: anche se i target installano con
--ignore-scripts, un package malevolo può comunque registrare un nome CLI comune nel campobincosì che il wrapper controllato dall'attacker venga symlinkato inPATHed eseguito più tardi quando il comando viene usato. - Runtime bootstrapping: un piccolo installer può scaricare un secondo runtime o toolchain durante l'installazione (per esempio Bun o un interpreter impacchettato) e poi lanciare con esso il main payload, evitando i requisiti delle dependencies locali.
- Credential harvesting from build environments: una volta che il codice gira dentro CI, controlla variabili d'ambiente,
~/.npmrc,~/.git-credentials, chiavi SSH, config dei cloud CLI e strumenti locali comegh auth token. Su GitHub Actions, cerca anche secrets e artifacts specifici del runner. - Workflow injection with stolen GitHub tokens: un token con permessi
repo+workflowè sufficiente per creare un branch, fare commit di un file malevolo dentro.github/workflows/, attivarlo, raccogliere gli artifacts/log prodotti e poi eliminare il branch/workflow run temporaneo per ridurre le tracce. - Wormable registry propagation: i token npm rubati dovrebbero essere verificati per i permessi di publish e per capire se bypassano 2FA. Se sì, enumera i package scrivibili, scarica i loro tarball, inietta un loader come
setup.mjs, impostapreinstallper eseguirlo, incrementa la patch version e ripubblica. Questo trasforma un compromesso CI in auto-esecuzione a valle in altri ambienti.
Practical checks during an assessment
- Esamina l'automazione di release per hook del package manager aggiunti a
package.json, entrybininattese o bump di versione che modificano solo l'artefatto di release. - Verifica se la CI conserva credenziali di registry a lunga durata in file in chiaro come
~/.npmrcinvece di usare OIDC a breve durata o trusted publishing. - Verifica se i token GitHub disponibili in CI possono scrivere file di workflow o creare branch/tag.
- Se si sospetta un package compromesso, ispeziona il tarball pubblicato e non solo il repository Git, perché il loader/runtime malevolo potrebbe esistere solo nell'artefatto pubblicato.
- Cerca esecuzioni inattese del package manager dentro CI come
npm installinvece dinpm ci, download/esecuzione inattesi di Bun, o nuovi artifacts di workflow generati da branch temporanei. - Esamina anche i motori di deploy GitOps come target CI/CD. L'enumerazione specifica di Argo CD, l'abuso del repo-server e gli attacchi di Redis cache poisoning sono trattati in Argo CD Security.
More relevant info
Tools & CIS Benchmark
- Chain-bench è uno strumento open-source per l'audit della tua software supply chain stack per la conformità alla sicurezza basata su un nuovo CIS Software Supply Chain benchmark. L'audit si concentra sull'intero processo SDLC, dove può rivelare rischi dal code time al deploy time.
Top 10 CI/CD Security Risk
Controlla questo articolo interessante sui top 10 rischi CI/CD secondo Cider: https://www.cidersecurity.io/top-10-cicd-security-risks/
Labs
- Su ogni platform che puoi eseguire localmente troverai come avviarla localmente così puoi configurarla come vuoi per testarla
- Gitea + Jenkins lab: https://github.com/cider-security-research/cicd-goat
Automatic Tools
- Checkov: Checkov è uno strumento di analisi statica del codice per infrastructure-as-code.
References
- 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
- Checkmarx Security Update: April 22, 2026
{{#include ../banners/hacktricks-training.md}}