14 KiB
Pentesting CI/CD Methodology
{{#include ../banners/hacktricks-training.md}}
VCS
VCS는 Version Control System의 약자이며, 이 시스템은 개발자가 소스 코드를 관리할 수 있게 해줍니다. 가장 흔한 것은 git이며, 보통 다음 platforms 중 하나에서 회사들이 사용하는 것을 볼 수 있습니다:
- Github
- Gitlab
- Bitbucket
- Gitea
- Gitblit
- Cloud providers (자체 VCS platforms를 제공합니다)
CI/CD Pipelines
CI/CD pipelines는 개발자가 빌드, 테스트, 배포를 포함한 다양한 목적을 위해 코드 실행을 자동화할 수 있게 해줍니다. 이 자동화된 workflow는 코드 push, pull request, 예약된 작업 같은 특정 action에 의해 triggered됩니다. 이는 development에서 production까지의 과정을 간소화하는 데 유용합니다.
하지만 이러한 시스템은 어딘가에서 실행되어야 하며, 보통 code를 deploy하거나 민감한 정보에 접근하기 위한 privileged credentials가 필요합니다.
VCS Pentesting Methodology
Note
일부 VCS platforms는 이 섹션을 위해 pipeline 생성도 허용하지만, 여기서는 source code 제어에 대한 잠재적 attack만 분석합니다.
프로젝트의 source code가 들어 있는 platforms에는 민감한 정보가 포함되어 있으며, 이 platform 내부에서 부여된 permissions에는 매우 주의해야 합니다. 공격자가 악용할 수 있는 VCS platforms 전반의 흔한 문제는 다음과 같습니다:
- Leaks: code에 commits 안에 leaks가 포함되어 있고 공격자가 repo에 접근할 수 있다면(공개되어 있거나 접근 권한이 있어서), leaks를 발견할 수 있습니다.
- Access: 공격자가 VCS platform 내부의 계정에 접근할 수 있다면, 더 많은 가시성과 permissions를 얻을 수 있습니다.
- Register: 일부 platforms는 외부 사용자가 그냥 계정을 만들 수 있게 합니다.
- SSO: 일부 platforms는 사용자의 register를 허용하지 않지만, 유효한 SSO가 있으면 누구나 접근할 수 있게 합니다(예: 공격자가 github 계정으로 들어갈 수 있음).
- Credentials: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... repo에 접근하기 위해 사용자가 탈취될 수 있는 token 종류는 여러 가지가 있습니다.
- Webhooks: VCS platforms는 webhooks 생성을 허용합니다. 보이지 않는 secret으로 보호되지 않으면 공격자가 악용할 수 있습니다.
- secret이 없으면, 공격자가 third party platform의 webhook을 악용할 수 있습니다
- secret이 URL 안에 있으면, 같은 일이 발생하고 공격자는 secret도 함께 갖게 됩니다
- Code compromise: 악의적 행위자가 repos에 대해 어떤 형태의 write access를 가지고 있다면, 악성 code를 주입하려고 시도할 수 있습니다. 이를 성공시키려면 branch protections를 우회해야 할 수도 있습니다. 이러한 action은 다양한 목적을 위해 수행될 수 있습니다:
- main branch를 compromise해서 production을 compromise.
- main (또는 다른 branches)을 compromise해서 developers machines를 compromise (보통 그들은 자신의 machine에서 repo 내부의 test, terraform 또는 다른 것들을 실행하기 때문).
- pipeline을 compromise (다음 섹션 확인)
Pipelines Pentesting Methodology
pipeline을 정의하는 가장 일반적인 방법은 pipeline이 build하는 repository에 호스팅된 CI configuration file을 사용하는 것입니다. 이 file은 실행되는 jobs의 순서, flow에 영향을 주는 조건, build environment 설정을 설명합니다.
이러한 file들은 보통 일관된 이름과 format을 가지며, 예를 들어 Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), 그리고 .github/workflows 아래에 위치한 GitHub Actions YAML files가 있습니다. trigger되면 pipeline job은 선택된 source(예: commit / branch)에서 code를 pull하고, CI configuration file에 지정된 commands를 그 code에 대해 실행합니다.
따라서 공격자의 궁극적인 목표는 어떤 식으로든 이러한 configuration files 또는 그것들이 실행하는 commands를 compromise하는 것입니다.
Tip
일부 hosted builders는 기여자가 Docker build context와 Dockerfile path를 선택하도록 허용합니다. context가 attacker-controlled라면, build 중 host files를 가져오고 secrets를 exfiltrate하기 위해 repo 밖(예: "..")으로 설정할 수 있습니다. See:
{{#ref}} docker-build-context-abuse.md {{#endref}}
PPE - Poisoned Pipeline Execution
Poisoned Pipeline Execution (PPE) 경로는 SCM repository의 permissions를 이용해 CI pipeline을 조작하고 harmful commands를 실행합니다. 필요한 permissions를 가진 사용자는 CI configuration files나 pipeline job이 사용하는 다른 files를 수정해 malicious commands를 포함시킬 수 있습니다. 이렇게 CI pipeline이 "poisoned"되며, 이 malicious commands가 실행됩니다.
악의적 행위자가 PPE attack을 성공시키려면 다음이 가능해야 합니다:
- 보통 pipeline은 push 또는 pull request가 수행될 때 trigger되므로, VCS platform에 write access가 있어야 합니다. (access를 얻는 방법 요약은 VCS pentesting methodology를 확인).
- 경우에 따라 external PR도 "write access"로 간주됩니다.
- write permissions가 있더라도, CI config file 또는 config가 의존하는 다른 files를 수정할 수 있어야 합니다.
- 이를 위해 branch protections를 우회할 수 있어야 할 수도 있습니다.
PPE에는 3가지 flavour가 있습니다:
- D-PPE: actor가 실행될 CI config file을 수정할 때 발생하는 Direct PPE attack입니다.
- I-DDE: actor가 실행될 CI config file이 의존하는 file(예: make file 또는 terraform config)을 수정할 때 발생하는 Indirect PPE attack입니다.
- Public PPE or 3PE: 어떤 경우에는 repo에 write access가 없는 사용자(조직 구성원이 아닐 수도 있음)도 PR을 보낼 수 있기 때문에 pipeline이 trigger될 수 있습니다.
- 3PE Command Injection: 보통 CI/CD pipelines는 PR에 대한 정보로 environment variables를 설정합니다. 그 값이 공격자에 의해 제어될 수 있고(PR title처럼), dangerous place(예: sh commands 실행)에서 사용된다면, 공격자는 거기에 commands를 주입할 수 있습니다.
Exploitation Benefits
pipeline을 poison하는 3가지 flavour를 알았으니, 성공적인 exploitation 후 공격자가 얻을 수 있는 것을 살펴봅시다:
- Secrets: 앞서 언급했듯이, pipelines는 jobs를 위해 privileges가 필요하며(코드 가져오기, 빌드, 배포 등), 이 privileges는 보통 secrets에 저장됩니다. 이러한 secrets는 일반적으로 env variables 또는 시스템 내부 files를 통해 접근할 수 있습니다. 따라서 공격자는 항상 가능한 한 많은 secrets를 exfiltrate하려고 합니다.
- pipeline platform에 따라 공격자가 config에 secrets를 지정해야 할 수도 있습니다. 즉, 공격자가 CI configuration pipeline (I-PPE 같은)을 수정할 수 없다면, 그 pipeline이 가진 secrets만 exfiltrate할 수 있다는 뜻입니다.
- Computation: code는 어딘가에서 실행되며, 실행 위치에 따라 공격자가 더 깊이 pivot할 수 있습니다.
- On-Premises: pipelines가 on premises에서 실행되면, 공격자는 더 많은 resources에 접근 가능한 internal network에 도달할 수 있습니다.
- Cloud: 공격자는 cloud 안의 다른 machine들에 접근할 수도 있지만, 그로부터 IAM roles/service accounts tokens를 exfiltrate하여 cloud 내부에서 더 많은 access를 얻을 수도 있습니다.
- Platforms machine: 때때로 jobs는 pipelines platform machines 내부에서 실행되며, 이들은 보통 더 이상의 access가 없는 cloud 안에 있습니다.
- Select it: 때때로 pipelines platform이 여러 machine을 구성해 두며, CI configuration file을 수정할 수 있다면 악성 code를 어디서 실행할지 지정할 수 있습니다. 이 경우 공격자는 더 추가로 exploit하기 위해 가능한 각 machine에서 reverse shell을 실행할 가능성이 높습니다.
- Compromise production: pipeline 내부에 있고 최종 버전이 거기서 build되고 deploy된다면, production에서 실행될 code를 compromise할 수 있습니다.
Dependency & Registry Supply-Chain Abuse
CI/CD pipeline을 compromise하거나 그 credentials를 훔치면, dependencies나 release tooling을 backdooring해서 공격자가 pipeline execution에서 ecosystem-wide code execution으로 이동할 수 있습니다:
- Install-time code execution via package hooks:
preinstall,postinstall,prepare또는 유사한 hooks를 추가한 package version을 publish해서 dependency installation 중 developer workstations와 CI runners에서 payload가 자동 실행되게 합니다. - Secondary execution paths: target이
--ignore-scripts로 install하더라도, malicious package는binfield에 common CLI name을 등록할 수 있으며, 그러면 attacker-controlled wrapper가PATH에 symlink되고 나중에 해당 command가 사용될 때 실행됩니다. - Runtime bootstrapping: 작은 installer가 installation 중 두 번째 runtime 또는 toolchain(예: Bun 또는 packed interpreter)을 다운로드한 뒤, local dependency requirements를 피하면서 그걸로 main payload를 실행할 수 있습니다.
- Credential harvesting from build environments: code가 CI 안에서 실행되면 environment variables,
~/.npmrc,~/.git-credentials, SSH keys, cloud CLI configs, 그리고gh auth token같은 local tooling을 확인하세요. GitHub Actions에서는 runner-specific secrets와 artifacts도 찾아보세요. - Workflow injection with stolen GitHub tokens:
repo+workflowpermissions가 있는 token이면 branch를 만들고,.github/workflows/안에 malicious file을 commit하고, 이를 trigger한 다음, 생성된 artifacts/logs를 수집하고, 흔적을 줄이기 위해 temporary branch/workflow run을 삭제할 수 있습니다. - Wormable registry propagation: 훔친 npm tokens는 publish permissions와 2FA 우회 여부를 검증해야 합니다. 가능하다면 writable packages를 열거하고, tarball을 다운로드한 뒤,
setup.mjs같은 loader를 주입하고, 실행되도록preinstall을 설정한 다음, patch version을 올리고 republish하세요. 이렇게 하면 하나의 CI compromise가 다른 environments에서 downstream auto-execution으로 이어집니다.
Practical checks during an assessment
package.json에 추가된 package-manager hooks, 예상치 못한binentries, 또는 release artifact만 수정하는 version bumps를 검토하세요.- CI가 짧은 수명의 OIDC나 trusted publishing 대신
~/.npmrc같은 plaintext files에 장기 registry credentials를 저장하는지 확인하세요. - CI에서 사용 가능한 GitHub tokens가 workflow files를 쓰거나 branches/tags를 생성할 수 있는지 검증하세요.
- compromised package가 의심되면, published tarball을 확인하세요. malicious loader/runtime가 published artifact에만 있을 수 있기 때문입니다.
- CI 안에서
npm install처럼 예상치 못한 package-manager execution이 있는지,npm ci대신 사용되는지, 예상치 못한 Bun 다운로드/execution이 있는지, 또는 transient branches에서 새 workflow artifacts가 생성되는지 찾아보세요. - GitOps deployment engines도 CI/CD targets로 검토하세요. Argo CD-specific enumeration, repo-server abuse, 그리고 Redis cache poisoning attacks는 Argo CD Security에서 다룹니다.
More relevant info
Tools & CIS Benchmark
- Chain-bench는 새로운 CIS Software Supply Chain benchmark를 기반으로 software supply chain stack의 security compliance를 감사하는 오픈소스 tool입니다. 이 auditing은 전체 SDLC process에 초점을 맞추며, code time부터 deploy time까지의 risks를 드러낼 수 있습니다.
Top 10 CI/CD Security Risk
Cider에 따르면 상위 10개 CI/CD risks에 대한 이 흥미로운 article을 확인하세요: https://www.cidersecurity.io/top-10-cicd-security-risks/
Labs
- locally 실행할 수 있는 각 platform에서, 원하는 대로 test할 수 있도록 locally launch하는 방법을 찾을 수 있습니다
- Gitea + Jenkins lab: https://github.com/cider-security-research/cicd-goat
Automatic Tools
- Checkov: Checkov는 infrastructure-as-code를 위한 static code analysis tool입니다.
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}}