Translated ['src/pentesting-ci-cd/argocd-security.md', 'src/pentesting-c

This commit is contained in:
Translator
2026-07-06 15:54:40 +00:00
parent 89b4cac818
commit ae78f13d24
2 changed files with 276 additions and 56 deletions
+219
View File
@@ -0,0 +1,219 @@
# Argo CD Security
{{#include ../banners/hacktricks-training.md}}
## 기본 정보
[Argo CD](https://argo-cd.readthedocs.io/)는 Kubernetes용 GitOps 지속적 배포 플랫폼이다. Git repositories를 감시하고, Helm, Kustomize, Jsonnet 또는 config management plugins 같은 도구로 Kubernetes manifests를 렌더링하며, Git에 저장된 원하는 상태와 live cluster state를 재조정한다.
공격자 관점에서 Argo CD는 **Kubernetes credentials를 가진 deployment engine**으로 취급하라. Argo CD를 성공적으로 침해하면 다음으로 이어질 수 있다:
- private Git repositories와 repository credentials 접근.
- Argo CD가 사용하는 Kubernetes cluster secrets 접근.
- `argocd-repo-server`에서 manifest generation code execution.
- trusted Git repositories, Argo CD applications, 또는 cache manipulation을 통한 무단 Kubernetes object deployment.
## 아키텍처 및 흥미로운 Components
일반적인 Kubernetes objects와 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 상태를 비교한 다음 Kubernetes에 resources를 적용합니다.
- **`argocd-repo-server`**: repositories를 clone하고, Git data를 cache하며, Helm/Kustomize/Jsonnet/plugins를 실행해 manifests를 생성합니다. 기본 gRPC port는 **8081**입니다.
- **`argocd-redis`**: application, manifest, Git reference data를 위한 cache입니다. 기본 Redis port는 **6379**입니다.
- **`argocd-applicationset-controller`**: Git, SCM, clusters, pull requests 같은 generators로부터 Argo CD `Application` objects를 생성합니다.
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나 노출된 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>
```
유용한 attack paths:
- **Application write access**: `source.repoURL`, `source.path`, Helm values, Kustomize options, plugin settings 또는 sync options를 수정하여 Argo CD가 attacker-controlled manifests를 배포하게 만듭니다.
- **Project misconfiguration**: `AppProject` objects는 광범위한 `sourceRepos`, 광범위한 `destinations`, unsafe `clusterResourceWhitelist` 또는 약한 namespace restrictions를 허용할 수 있습니다.
- **Repository credential abuse**: repository secrets, GitHub App credentials, SSH keys 및 tokens는 trusted repos에 push하거나 malicious dependencies를 추가하는 데 사용될 수 있습니다.
- **Cluster credential abuse**: cluster secrets에는 Argo CD가 target clusters에 배포할 때 사용하는 bearer tokens 또는 exec-provider configuration이 들어 있을 수 있습니다.
- **Local admin / project tokens**: long-lived Argo CD tokens는 revoked되거나 expired되지 않았다면 API를 통해 재사용될 수 있습니다.
클러스터 read access가 있을 때 Kubernetes에서 configuration을 열거하십시오:
```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 Abuse
Argo CD가 신뢰하는 repository에 push할 수 있다면, 일반적으로 무엇이 배포되는지 영향을 줄 수 있습니다. 영향은 `AppProject` 경계와 application controller가 사용하는 service account 권한에 따라 달라집니다.
Common payload locations:
- application path 아래의 Raw Kubernetes YAML.
- Helm chart templates와 `values.yaml`.
- Kustomize overlays, remote bases and generators.
- Jsonnet or config management plugin input.
- `Application` objects를 생성하거나 업데이트하는 ApplicationSet generator files.
앱이 automated sync, pruning, self-heal, sync windows 또는 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'
```
## Direct `argocd-repo-server` Abuse
공개 Argo CD API만이 공격 표면이라고 가정하지 마세요. 내부 Argo CD 컴포넌트는 gRPC를 통해 `argocd-repo-server`와 통신합니다. 임의의 pods가 repo-server에 도달할 수 있다면, 공격자가 제어하는 내부 요청은 보통 `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
```
흥미로운 징후:
- repo-server gRPC endpoint가 non-Argo CD pods에서 도달 가능하다.
- NetworkPolicies가 없거나, ingress를 차단하지 않고 egress만 allow-list 한다.
- repo-server가 custom config management plugins, decryption tools, 또는 여러 tenant의 repository content에 접근할 수 있다.
- Redis가 non-Argo CD pods에서 도달 가능하여, credentials가 있거나 필요하지 않을 경우 cache inspection 또는 tampering이 가능하다.
## Kustomize Options를 통한 Unauthenticated Repo-Server RCE
2026년 7월, Synacktiv는 공격자가 내부 gRPC service에 도달할 수 있을 때 Argo CD의 `repo-server`에서 unauthenticated code execution chain을 공개했다. 이 공격은 `/repository.RepoServerService/GenerateManifest`에 대한 직접 접근과 공격자 제어 `KustomizeOptions`를 악용한다.
위험한 primitive는 repo-server가 공격자 제어 repository content를 clone하고 Helm support와 함께 Kustomize를 실행하도록 강제하는 것이다:
```bash
kustomize build <attacker_repo_path> --enable-helm --helm-command ./payload.sh
```
Helm 처리을 트리거하려면 최소한의 malicious Kustomize input이 필요합니다:
```yaml
helmCharts:
- name: pwn
version: 0.0.1
```
이것이 작동하는 이유:
- `argocd-repo-server`는 렌더링 전에 repository를 clone합니다.
- `--helm-command ./payload.sh`는 cloned repository를 기준으로 상대 경로로 해석됩니다.
- 공격자가 rendered repository와 Kustomize build options를 제어할 수 있다면, Code execution에는 shell metacharacter injection이 필요하지 않습니다.
Synacktiv의 2026년 7월 1일 disclosure 시점에, 그들은 이 issue에 공식 fix나 CVE가 없다고 보고했습니다. 이를 먼저 network-exposure issue로 취급하세요: exploitation에는 내부 repo-server gRPC port에 도달 가능해야 합니다.
## Redis Cache Poisoning to Deploy Manifests
`argocd-repo-server`에서 code execution이 발생한 후, 또는 유효한 credentials로 Redis에 직접 access한 후, Redis-backed cache entries를 점검합니다. Argo CD는 일반적으로 gzip-compressed JSON values를 저장합니다.
흥미로운 key prefixes:
```text
mfst|... # cached rendered manifests
git-refs|... # Git branch/ref to commit mappings
app|... # application resource/cache data
cluster|... # cluster cache information
```
Synacktiv이 설명한 cache poisoning 공격은 두 가지 상태를 악용합니다:
1. 관련 `mfst|...` manifest cache entry를 수정해 공격자가 제어하는 Kubernetes manifest를 포함시킵니다.
2. 관련 `git-refs|...` mapping을 수정해 Argo CD가 branch가 이동했다고 믿게 만든 뒤, cached revision으로 다시 reconcile하게 만듭니다.
영향:
- Auto Sync가 활성화되어 있으면 Argo CD가 poisoned cached manifest를 자동으로 적용할 수 있습니다.
- Auto Sync가 없어도 사용자가 application을 수동으로 sync할 때 payload가 적용될 수 있습니다.
- 최종 영향은 target application's destination과 Argo CD에 허용된 Kubernetes permissions에 의해 제한됩니다.
## ApplicationSet Attacks
ApplicationSet은 generator output으로부터 `Application` objects를 생성하거나 업데이트하므로 특히 민감합니다.
Review:
```bash
kubectl get applicationsets.argoproj.io -A -o yaml
kubectl get appprojects.argoproj.io -A -o yaml
```
Interesting patterns:
- attacker-writable files를 읽는 Git generators가 app names, paths, projects 또는 destinations를 제어하는 경우.
- public repositories에서 untrusted contributors가 generated applications에 영향을 줄 수 있는 Pull request generators.
- broad destination clusters/namespaces를 허용하는 Template fields.
- `sourceRepos: ["*"]` 또는 broad `destinations`를 허용하는 AppProjects.
- automated sync와 pruning을 상속하는 Generated applications.
## Post-Exploitation
Argo CD pod shell에서, 우선순위를 두고:
```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을 탈취한다.
- mounted secrets 또는 Argo CD Kubernetes secrets에서 repository credentials를 추출한다.
- Argo CD가 사용하는 cluster credentials를 식별한다.
- 주입된 secrets를 포함할 수 있는 generated manifests와 plugin output을 읽는다.
- custom plugins, SOPS, Helm secrets, Vault plugins 또는 cloud CLIs가 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 values는 역사적으로 component network policy creation을 disabled로 두는 것이 기본이었다.
- `argocd-server`를 인증된 entry point로 유지한다. internal services는 임의의 workloads에서 접근 가능해서는 안 된다.
- 사용하지 않는 config management tools와 plugins는 비활성화한다.
- `AppProject``sourceRepos`, `destinations`, namespace permissions, cluster-scoped resources를 제한한다.
- 권한이 낮은 Argo CD user가 재사용을 유도할 수 있는 광범위한 repository credentials 저장을 피한다.
- repo-server requests, Kustomize build options, plugin executions, Redis writes, 그리고 `mfst|` / `git-refs|` keys에 대한 예상치 못한 access를 모니터링한다.
- compromise 이후 Argo CD local users, project tokens, repository credentials, cluster credentials를 rotate한다.
유용한 명령:
```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 Note: Typed API Requests in CodeQL
Go services에서 gRPC/REST handlers를 사용할 때, 기본 CodeQL remote sources는 raw input이 typed request objects로 unmarshaled된 뒤의 flows를 놓칠 수 있습니다. Argo CD-style services에 유용한 model은 다음과 같습니다:
- `Server` 또는 `Service` 같은 receiver type.
- 첫 번째 parameter는 `context.Context`.
- 두 번째 parameter는 typed request object.
그 두 번째 parameter를 remote source로 model하고, `exec.Command` / `exec.CommandContext` arguments에 custom sinks를 추가하세요. 이렇게 하면 internal API request fields에서 command execution helpers로 이어지는 flows를 찾는 데 도움이 됩니다.
## 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,51 +6,51 @@
## VCS
VCS는 **Version Control System**의 약자이며, 이 시스템은 개발자가 **source code를 관리**할 수 있게 해줍니다. 가장 흔한 것은 **git**이며, 보통 기업은 다음 **platforms** 중 하나를 사용합니다:
VCS는 **Version Control System**의 약자이며, 이 시스템은 개발자가 **소스 코드**를 **관리**할 수 있게 해줍니다. 가장 흔한 것은 **git**이며, 보통 다음 **platforms** 중 하나에서 회사들이 사용하는 것을 볼 수 있습니다:
- Github
- Gitlab
- Bitbucket
- Gitea
- Gitblit
- Cloud providers (자체 VCS platforms 제공)
- Cloud providers (자체 VCS platforms 제공합니다)
## CI/CD Pipelines
CI/CD pipelines는 개발자가 빌드, 테스트, 배포를 포함한 다양한 목적의 **code 실행을 자동화**할 수 있게 해줍니다. 이러한 자동화된 워크플로는 code push, pull request, 예약 작업 같은 **특정 액션에 의해 트리거**됩니다. 이는 development에서 production까지의 과정을 간소화하는 데 유용합니다.
CI/CD pipelines는 개발자가 빌드, 테스트, 배포를 포함한 다양한 목적을 위해 **코드 실행을 자동화**할 수 있게 해줍니다. 이 자동화된 workflow는 코드 push, pull request, 예약 작업 같은 특정 action에 의해 **triggered**됩니다. 이는 development에서 production까지의 과정을 간소화하는 데 유용합니다.
하지만 이러한 시스템은 **어딘가에서 실행**되어야 하며, 보통 code를 deploy하거나 민감한 정보에 접근하기 위한 **privileged credentials**가 필요합니다.
하지만 이러한 시스템은 **어딘가에서 실행되어야** 하며, 보통 code를 deploy하거나 민감한 정보에 접근하기 위한 **privileged credentials**가 필요합니다.
## VCS Pentesting Methodology
> [!NOTE]
> 일부 VCS platforms는 이 섹션을 위해 pipelines 생성도 허용하지만, 여기서는 source code 제에 대한 잠재적 공격만 분석합니다.
> 일부 VCS platforms는 이 섹션을 위해 pipeline 생성도 허용하지만, 여기서는 source code 제에 대한 잠재적 attack만 분석합니다.
프로젝트의 source code를 담고 있는 platforms에는 민감한 정보가 포함되며, 이 platform 내부에서 부여된 permissions에는 매우 주의해야 합니다. attacker가 악용할 수 있는 VCS platforms 전반의 흔한 문제는 다음과 같습니다:
프로젝트의 source code가 들어 있는 platforms에는 민감한 정보가 포함되어 있으며, 이 platform 내부에서 부여된 permissions에는 매우 주의해야 합니다. 공격자가 악용할 수 있는 VCS platforms 전반의 흔한 문제는 다음과 같습니다:
- **Leaks**: code에 commits 안 leaks가 포함되어 있고 attacker가 repo에 접근할 수 있다면(공개되어 있거나 접근 권한이 있기 때문), leaks를 발견할 수 있습니다.
- **Access**: attacker가 **VCS platform 내부의 account에 접근**할 수 있다면 **더 많은 가시성과 permissions** 얻을 수 있습니다.
- **Register**: 일부 platforms는 외부 사용자가 그냥 account를 만들 수 있게 허용합니다.
- **SSO**: 일부 platforms는 사용자의 직접 등록은 허용하지 않지만, 유효한 SSO가 있으면 누구나 접근할 수 있게 허용합니다(예: attacker가 자신의 github account로 들어갈 수 있음).
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... repo에 어떤 식으로든 접근하기 위해 사용자가 훔칠 수 있는 token 종류는 여러 가지가 있습니다.
- **Webhooks**: VCS platforms는 webhooks 생성을 허용합니다. 만약 이것들이 보이지 않는 secrets**보호되지 않으면 attacker가 악용할 수 있습니다**.
- secret이 없면, attacker는 third party platform의 webhook을 악용할 수 있습니다
- secret이 URL에 있면, 같은 일이 발생하고 attacker도 secret 갖게 됩니다
- **Code compromise:** 악의적 행위자가 repos에 대해 어떤 형태의 **write** access를 가지고 있다면, **malicious code를 주입**하려 시도할 수 있습니다. 성공하려면 **branch protections를 우회**해야 할 수도 있습니다. 이러한 행위는 mid에 다른 목표를 가지고 수행될 수 있습니다:
- main branch를 compromise하여 **production을 compromise**.
- main(또는 다른 branches)을 compromise하여 **developers machines를 compromise**(보통 개발자들이 자신의 머신에서 repo 내부의 test, terraform 또는 다른 것들을 실행하기 때문).
- **pipeline을 compromise**(다음 섹션 참조)
- **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이 빌드하는 repository에 호스팅된 **CI configuration file**을 사용하는 것입니다. 이 파일은 실행되는 jobs의 순서, 흐름에 영향을 주는 조건, build environment settings를 설명합니다.\
이러한 파일들은 보통 일정한 이름과 형식을 가집니다. 예를 들어 Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), 그리고 .github/workflows 아래에 있는 GitHub Actions YAML files가 있습니다. 트리거되면 pipeline job은 선택된 source(예: commit / branch)에서 **code를 가져와**, 해당 code에 대해 CI configuration file에 지정된 **commands를 실행**합니다.
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에 대해 **실행**합니다.
따라서 attacker의 궁극적인 목표는 어떻게든 이러한 **configuration files** 또는 그들이 실행하는 **commands**를 **compromise**하는 것입니다.
따라서 공격자의 궁극적인 목표는 어떤 식으로든 이러한 configuration files 또는 그들이 실행하는 **commands**를 **compromise**하는 것입니다.
> [!TIP]
> 일부 hosted builders는 contributors가 Docker build context와 Dockerfile path를 선택하게 해줍니다. context가 attacker-controlled라면, build 중 host files를 ingest하고 secrets를 exfiltrate하기 위해 repo 밖(예: "..")으로 설정할 수 있습니다. 다음을 참조하세요:
> 일부 hosted builders는 기여자가 Docker build context와 Dockerfile path를 선택하도록 허용합니다. context가 attacker-controlled라면, build 중 host files를 가져오고 secrets를 exfiltrate하기 위해 repo 밖(예: "..")으로 설정할 수 있습니다. See:
>
>{{#ref}}
>docker-build-context-abuse.md
@@ -58,72 +58,73 @@ pipeline을 정의하는 가장 일반적인 방법은 pipeline이 빌드하는
### PPE - Poisoned Pipeline Execution
Poisoned Pipeline Execution (PPE) 경로는 SCM repository의 permissions를 용해 CI pipeline을 조작하고 harmful commands를 실행합니다. 필요한 permissions가 있는 사용자는 CI configuration files 또는 pipeline job이 사용하는 다른 파일을 수정하여 malicious commands를 포함시킬 수 있습니다. 이렇게 CI pipeline이 "poison"되면 이러한 malicious commands가 실행됩니다.
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가 실행됩니다.
malicious actor가 PPE attack을 성공적으로 수행하려면 다음이 가능해야 합니다:
악의적 행위자가 PPE attack을 성공시키려면 다음이 가능해야 합니다:
- 보통 pipelines는 push pull request가 수행될 때 트리거되므로, **VCS platform에 write access**가 있어야 합니다. (접근 권한을 얻는 방법 요약은 VCS pentesting methodology를 확인하세요).
- 때로는 **external PR "write access"로 간주**된다는 점에 유의하세요.
- write permissions가 있더라도, **CI config file 또는 config가 의존하는 다른 파일을 수정할 수 있어야** 합니다.
- 이를 위해 **branch protections를 우회**야 할 수도 있습니다.
- 보통 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가지 flavor가 있습니다:
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가 없는 사용자(심지어 org의 일부도 아닐 수 있음)도 PR을 보낼 수 있으므로 pipelines가 **트리거**될 수 있습니다.
- **3PE Command Injection**: 보통 CI/CD pipelines는 PR에 대한 **정보로 environment variables를 설정**합니다. 그 값이 attacker가 제어 수 있고(PR title 같은), **위험한 위치**(예: **sh commands** 실행)에서 **사용**된다면 attacker가 그곳에 **commands를 주입**할 수 있습니다.
- **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가지 flavor를 알았으니, 성공적인 exploitation 후 attacker가 얻을 수 있는 것을 살펴봅시다:
pipeline을 poison하는 3가지 flavour를 알았으니, 성공적인 exploitation 후 공격자가 얻을 수 있는 것을 살펴봅시다:
- **Secrets**: 앞서 언급했듯이, pipelines는 jobs를 수행하기 위해 **privileges**가 필요하며(코드 가져오기, 빌드, 배포 등), 이러한 privileges는 보통 **secrets** 안에 있습니다. 이러한 secrets는 보통 **env variables 또는 시스템 내부 파일** 통해 접근할 수 있습니다. 따라서 attacker는 항상 가능한 한 많은 secrets를 exfiltrate하려 할 것입니다.
- pipeline platform에 따라 attacker**config에 secrets를 지정해야 할 수도 있습니다**. 이는 attacker가 CI configuration pipeline(**I-PPE** 같은)을 수정할 수 없다면, **그 pipeline이 가진 secrets만 exfiltrate**할 수 있음을 의미합니다.
- **Computation**: code는 어딘가에서 실행되며, 실행 위치에 따라 attacker가 더 깊 pivot할 수 있습니다.
- **On-Premises**: pipelines가 on premises에서 실행된다면, attacker는 더 많은 resources에 접근할 수 있는 **internal network**에 도달할 수 있습니다.
- **Cloud**: attacker는 **다른 cloud machine들**에 접근할 수 있을 뿐 아니라, IAM roles/service accounts **tokens**를 exfiltrate하여 cloud 내부에서 **추가 접근**을 얻을 수도 있습니다.
- **Platforms machine**: 때때로 jobs는 **pipelines platform machines** 내부에서 실행되며, 보통 이는 **더 이상의 access가 없는** cloud 안에 있습니다.
- **Select it:** 때때로 **pipelines platform이 여러 machines를 설정**해 두며, CI configuration file을 **수정할 수 있다면** malicious code를 어디서 실행할지 **지정**할 수 있습니다. 이 상황에서는 attacker가 각 machine에서 reverse shell을 실행해 추가 exploitation을 시도할 가능성이 니다.
- **Compromise production**: pipeline 내부에 있고 최종 버전이 기서 빌드 및 배포된다면, **production에서 실행될 code를 compromise**할 수 있습니다.
- **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를 훔치면, attacker는 dependencies나 release tooling을 backdoor하여 **pipeline execution**에서 **ecosystem-wide code execution**으로 이동할 수 있습니다:
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**: 대상`--ignore-scripts`설치하더라도, malicious package는 여전히 `bin` field에 **common CLI name**을 등록할 수 있으므로 attacker-controlled wrapper가 `PATH`에 symlink되고 나중에 command가 사용될 때 실행됩니다.
- **Runtime bootstrapping**: 작은 installer가 설치 중 두 번째 runtime 또는 toolchain을 다운로드할 수 있습니다(예: Bun 또는 packed interpreter). 그런 다음 그것으로 main payload를 launch하여 local dependency requirements를 피할 수 있습니다.
- **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` + `workflow`** permissions가 있는 token이면 branch를 만들고, `.github/workflows/` 안에 malicious file을 commit하고, 트리거한 뒤, 생성된 artifacts/logs를 수집하고, trace를 줄이기 위해 임시 branch/workflow run을 삭제할 수 있습니다.
- **Wormable registry propagation**: 훔친 npm tokens **publish** permissions가 있는지, 그리고 2FA 우회하는지 검증해야 합니다. 가능하다면 writable packages를 열거하고, tarballs를 다운로드한 뒤, `setup.mjs` 같은 loader를 주입하고, `preinstall`이 이를 실행하도록 설정한 다음, patch version을 올리고 republish하세요. 이렇게 하면 하나의 CI compromise가 다른 환경들에서 downstream auto-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는 `bin` field에 **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` + `workflow`** permissions가 있는 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, 예상치 못한 `bin` entries, 또는 release artifact만 수정하는 version bumps에 대해 release automation을 검토하세요.
- CI가 short-lived OIDC나 trusted publishing 대신 `~/.npmrc` 같은 plaintext files에 long-lived registry credentials를 저장하는지 확인하세요.
- CI에서 사용 가능한 GitHub tokens가 workflow files를 쓸 수 있는지 또는 branches/tags를 생성할 수 있는지 검증하세요.
- compromised package가 의심되면, Git repository뿐 아니라 published tarball 확인하세요. malicious loader/runtime published artifact에만 존재할 수 있니다.
- CI 내부에서 `npm install` 대신 `npm ci` 사용, 예상치 못한 Bun downloads/execution, 또는 transient branches에서 생성된 새로운 workflow artifacts 같은 비정상적인 package-manager execution을 찾아보세요.
- `package.json`에 추가된 package-manager hooks, 예상치 못한 `bin` entries, 또는 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](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)는 새로운 [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf)를 기반으로 software supply chain stack의 security compliance를 감사하는 오픈소스 tool입니다. 이 auditing은 전체 SDLC process에 초점을 맞추며, code time부터 deploy time까지의 risks를 드러낼 수 있습니다.
### 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/)
Cider에 따르면 상위 10 CI/CD risks에 대한 이 흥미로운 article을 확인하세요: [**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
- locally 실행할 수 있는 각 platform에서, 원하는 대로 test할 수 있도록 locally launch하는 방법을 찾을 수 있습니다
- 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** infrastructure-as-code를 위한 static code analysis tool입니다.
## References