mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 22:51:09 -07:00
Translated ['src/pentesting-ci-cd/argocd-security.md', 'src/pentesting-c
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
# Argo CD Security
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Podstawowe informacje
|
||||
|
||||
[Argo CD](https://argo-cd.readthedocs.io/) to platforma ciągłego dostarczania GitOps dla Kubernetes. Monitoruje repozytoria Git, renderuje manifesty Kubernetes za pomocą narzędzi takich jak Helm, Kustomize, Jsonnet lub wtyczki do zarządzania konfiguracją, a następnie uzgadnia rzeczywisty stan klastra z pożądanym stanem zapisanym w Git.
|
||||
|
||||
Z perspektywy atakującego traktuj Argo CD jako **silnik wdrożeniowy z poświadczeniami Kubernetes**. Udana kompromitacja Argo CD może prowadzić do:
|
||||
|
||||
- Dostępu do prywatnych repozytoriów Git i poświadczeń repozytoriów.
|
||||
- Dostępu do secretów klastra Kubernetes używanych przez Argo CD.
|
||||
- Wykonania code execution przy generowaniu manifestów w `argocd-repo-server`.
|
||||
- Nieautoryzowanego wdrażania obiektów Kubernetes przez zaufane repozytoria Git, aplikacje Argo CD lub manipulację cache.
|
||||
|
||||
## Architektura i interesujące komponenty
|
||||
|
||||
Typowe obiekty i usługi Kubernetes:
|
||||
```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
|
||||
```
|
||||
Interesujące usługi:
|
||||
|
||||
- **`argocd-server`**: publiczne API, web UI, CLI API, uwierzytelnianie i autoryzacja.
|
||||
- **`argocd-application-controller`**: porównuje desired i live state, a następnie stosuje resources do Kubernetes.
|
||||
- **`argocd-repo-server`**: klonuje repositories, buforuje dane Git i uruchamia Helm/Kustomize/Jsonnet/plugins, aby generować manifests. Domyślny port gRPC to **8081**.
|
||||
- **`argocd-redis`**: cache dla application, manifest i Git reference data. Domyślny port Redis to **6379**.
|
||||
- **`argocd-applicationset-controller`**: generuje obiekty Argo CD `Application` z generatorów takich jak Git, SCM, clusters i pull requests.
|
||||
|
||||
Z kompromitowanego pod lub wewnętrznego segmentu sieci sprawdź wewnętrzną dostępność:
|
||||
```bash
|
||||
nc -vz <argocd-server> 443
|
||||
nc -vz <argocd-repo-server> 8081
|
||||
nc -vz <argocd-redis> 6379
|
||||
```
|
||||
## Public API / UI Attacks
|
||||
|
||||
Jeśli masz poświadczenia Argo CD albo wystawioną instancję, zacznij od normalnej powierzchni API:
|
||||
```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>
|
||||
```
|
||||
Przydatne ścieżki ataku:
|
||||
|
||||
- **Application write access**: zmodyfikuj `source.repoURL`, `source.path`, wartości Helm, opcje Kustomize, ustawienia pluginów lub opcje sync, aby Argo CD wdrożyło manifesty kontrolowane przez atakującego.
|
||||
- **Project misconfiguration**: obiekty `AppProject` mogą zezwalać na szerokie `sourceRepos`, szerokie `destinations`, niebezpieczne `clusterResourceWhitelist` lub słabe ograniczenia namespace.
|
||||
- **Repository credential abuse**: sekrety repository, poświadczenia GitHub App, klucze SSH i tokeny mogą umożliwiać push do zaufanych repo lub dodawanie złośliwych dependencies.
|
||||
- **Cluster credential abuse**: sekrety cluster mogą zawierać bearer tokens lub konfigurację exec-provider używaną przez Argo CD do wdrażania do docelowych cluster.
|
||||
- **Local admin / project tokens**: długowieczne tokeny Argo CD mogą być ponownie używane przez API, dopóki nie zostaną revoked albo nie wygasną.
|
||||
|
||||
Wylicz konfigurację z Kubernetes, gdy masz cluster read access:
|
||||
```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
|
||||
|
||||
Jeśli możesz pushować do repozytorium zaufanego przez Argo CD, zwykle możesz wpływać na to, co zostanie wdrożone. Impact zależy od granic `AppProject` i uprawnień service account używanych przez application controller.
|
||||
|
||||
Common payload locations:
|
||||
|
||||
- Raw Kubernetes YAML pod ścieżką aplikacji.
|
||||
- Helm chart templates i `values.yaml`.
|
||||
- Kustomize overlays, remote bases i generatory.
|
||||
- Jsonnet albo wejście pluginu config management.
|
||||
- Pliki generatora ApplicationSet, które tworzą albo aktualizują obiekty `Application`.
|
||||
|
||||
Sprawdź, czy app używa automated sync, pruning, self-heal, sync windows albo 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'
|
||||
```
|
||||
## Bezpośrednie nadużycie `argocd-repo-server`
|
||||
|
||||
Nie zakładaj, że publiczne API Argo CD to jedyna powierzchnia ataku. Wewnętrzne komponenty Argo CD komunikują się z `argocd-repo-server` przez gRPC. Jeśli dowolne pods mogą osiągnąć repo-server, kontrolowane przez atakującego wewnętrzne żądania mogą ominąć kontrole normalnie egzekwowane przez `argocd-server`.
|
||||
|
||||
Praktyczne sprawdzenia:
|
||||
```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
|
||||
```
|
||||
Interesujące sygnały:
|
||||
|
||||
- Endpoint gRPC repo-server jest osiągalny z podów spoza Argo CD.
|
||||
- Brakuje NetworkPolicies albo zezwalają tylko na allow-list egress bez blokowania ingress.
|
||||
- repo-server ma dostęp do niestandardowych pluginów config management, narzędzi do decryptowania albo zawartości repository z wielu tenantów.
|
||||
- Redis jest osiągalny z podów spoza Argo CD, co pozwala na inspekcję cache albo jego modyfikację, jeśli credentials są dostępne albo nie są wymagane.
|
||||
|
||||
## Unauthenticated Repo-Server RCE via Kustomize Options
|
||||
|
||||
W lipcu 2026 Synacktiv ujawnił chain wykonania code bez uwierzytelnienia w `repo-server` Argo CD, gdy atakujący może dosięgnąć wewnętrznej usługi gRPC. Atak wykorzystuje bezpośredni dostęp do `/repository.RepoServerService/GenerateManifest` oraz kontrolowane przez atakującego `KustomizeOptions`.
|
||||
|
||||
Niebezpieczny primitive polega na wymuszeniu, aby repo-server sklonował zawartość repository kontrolowaną przez atakującego i uruchomił Kustomize z obsługą Helm:
|
||||
```bash
|
||||
kustomize build <attacker_repo_path> --enable-helm --helm-command ./payload.sh
|
||||
```
|
||||
Minimalny złośliwy input Kustomize potrzebny do uruchomienia przetwarzania Helm:
|
||||
```yaml
|
||||
helmCharts:
|
||||
- name: pwn
|
||||
version: 0.0.1
|
||||
```
|
||||
Dlaczego to działa:
|
||||
|
||||
- `argocd-repo-server` klonuje repository przed renderowaniem.
|
||||
- `--helm-command ./payload.sh` rozwiązuje się względnie do sklonowanego repository.
|
||||
- code execution nie wymaga wstrzyknięcia shell metacharacterów, jeśli attacker może kontrolować renderowane repository i opcje build Kustomize.
|
||||
|
||||
W momencie ujawnienia przez Synacktiv 1 lipca 2026, zgłosili oni, że issue nie miała oficjalnego fix ani CVE. Traktuj to najpierw jako problem network-exposure: exploitation wymaga osiągalności wewnętrznego portu gRPC repo-server.
|
||||
|
||||
## Redis Cache Poisoning to Deploy Manifests
|
||||
|
||||
Po code execution w `argocd-repo-server`, albo po bezpośrednim dostępie do Redis z poprawnymi credentials, sprawdź cache entries oparte na Redis. Argo CD często przechowuje gzip-compressed wartości JSON.
|
||||
|
||||
Interesujące prefixy key:
|
||||
```text
|
||||
mfst|... # cached rendered manifests
|
||||
git-refs|... # Git branch/ref to commit mappings
|
||||
app|... # application resource/cache data
|
||||
cluster|... # cluster cache information
|
||||
```
|
||||
Atak cache poisoning opisany przez Synacktiv nadużywa dwóch elementów stanu:
|
||||
|
||||
1. Zmodyfikuj odpowiedni wpis cache manifestu `mfst|...`, aby zawierał manifest Kubernetes kontrolowany przez atakującego.
|
||||
2. Zmodyfikuj powiązane mapowanie `git-refs|...`, aby Argo CD uwierzyło, że gałąź została przesunięta, a następnie ponownie zsynchronizowało się do zbuforowanej wersji.
|
||||
|
||||
Wpływ:
|
||||
|
||||
- Przy włączonym Auto Sync Argo CD może automatycznie zastosować zatruty zbuforowany manifest.
|
||||
- Bez Auto Sync payload może nadal zostać zastosowany, gdy użytkownik ręcznie zsynchronizuje aplikację.
|
||||
- Końcowy wpływ jest ograniczony przez destination aplikacji docelowej oraz uprawnienia Kubernetes dostępne dla Argo CD.
|
||||
|
||||
## ApplicationSet Attacks
|
||||
|
||||
ApplicationSet jest szczególnie wrażliwy, ponieważ tworzy lub aktualizuje obiekty `Application` na podstawie wyjścia generatora.
|
||||
|
||||
Review:
|
||||
```bash
|
||||
kubectl get applicationsets.argoproj.io -A -o yaml
|
||||
kubectl get appprojects.argoproj.io -A -o yaml
|
||||
```
|
||||
Interesujące wzorce:
|
||||
|
||||
- Generatory git odczytujące pliki zapisywalne przez atakującego, które kontrolują nazwy app, ścieżki, projekty lub destinations.
|
||||
- Generatory pull request dla publicznych repozytoriów, gdzie nieufni contributorzy mogą wpływać na generowane applications.
|
||||
- Pola template, które pozwalają na szerokie destination clusters/namespaces.
|
||||
- AppProjects, które zezwalają na `sourceRepos: ["*"]` lub szerokie `destinations`.
|
||||
- Generowane applications, które dziedziczą automated sync i pruning.
|
||||
|
||||
## Post-Exploitation
|
||||
|
||||
Z poziomu shell w podzie Argo CD, priorytetyzuj:
|
||||
```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'
|
||||
```
|
||||
Przydatne cele:
|
||||
|
||||
- Ukradnij `REDIS_PASSWORD` lub material TLS/client Redis.
|
||||
- Wyciągnij credentials repozytorium z zamontowanych secrets lub Argo CD Kubernetes secrets.
|
||||
- Zidentyfikuj cluster credentials używane przez Argo CD.
|
||||
- Odczytaj wygenerowane manifests i output pluginów, które mogą zawierać wstrzyknięte sekrety.
|
||||
- Sprawdź, czy custom plugins, SOPS, Helm secrets, Vault plugins lub cloud CLIs ujawniają decryption keys i cloud credentials.
|
||||
|
||||
## Detection & Hardening
|
||||
|
||||
Ważne kontrole:
|
||||
|
||||
- Ogranicz port **8081** `argocd-repo-server` i port Redis **6379** za pomocą NetworkPolicies, aby tylko oczekiwane komponenty Argo CD mogły się z nimi łączyć.
|
||||
- W wdrożeniach Helm sprawdź, czy network policies są faktycznie tworzone. Wartości Argo CD Helm chart historycznie miały domyślnie wyłączone tworzenie network policy dla komponentów.
|
||||
- Traktuj `argocd-server` jako uwierzytelniony punkt wejścia. Usługi wewnętrzne nie powinny być osiągalne z dowolnych workloadów.
|
||||
- Wyłącz nieużywane narzędzia i pluginy do config management.
|
||||
- Ogranicz `AppProject` `sourceRepos`, `destinations`, uprawnienia namespace oraz cluster-scoped resources.
|
||||
- Unikaj przechowywania szerokich repository credentials, które może zostać ponownie użyte przez użytkownika Argo CD o niskich uprawnieniach.
|
||||
- Monitoruj requests do repo-server, Kustomize build options, wykonania pluginów, zapisy do Redis oraz nieoczekiwany dostęp do kluczy `mfst|` / `git-refs|`.
|
||||
- Rotuj lokalnych użytkowników Argo CD, project tokens, repository credentials i cluster credentials po kompromitacji.
|
||||
|
||||
Przydatne komendy:
|
||||
```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
|
||||
```
|
||||
## Uwaga dotycząca statycznej analizy: Typed API Requests w CodeQL
|
||||
|
||||
Dla usług Go używających handlerów gRPC/REST, domyślne remote sources w CodeQL mogą nie wychwycić przepływów po tym, jak raw input został zdeserializowany do typed request objects. Przydatny model dla usług w stylu Argo CD to:
|
||||
|
||||
- Typ odbiorcy, taki jak `Server` lub `Service`.
|
||||
- Pierwszy parametr to `context.Context`.
|
||||
- Drugi parametr to typed request object.
|
||||
|
||||
Zamodeluj ten drugi parametr jako remote source i dodaj niestandardowe sinks dla argumentów `exec.Command` / `exec.CommandContext`. To pomaga znaleźć przepływy z pól wewnętrznych API request do helperów wykonujących komendy.
|
||||
|
||||
## Referencje
|
||||
|
||||
- [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)
|
||||
@@ -1,4 +1,4 @@
|
||||
# Metodologia Pentesting CI/CD
|
||||
# Pentesting CI/CD Methodology
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## VCS
|
||||
|
||||
VCS oznacza **Version Control System**, ten system pozwala developerom **zarządzać kodem źródłowym**. Najczęściej spotykany to **git** i zwykle można go znaleźć w firmach używających jednej z poniższych **platform**:
|
||||
VCS to skrót od **Version Control System**, ten system pozwala developerom **zarządzać swoim source code**. Najpopularniejszy z nich to **git** i zwykle można go znaleźć w firmach używających jednej z poniższych **platform**:
|
||||
|
||||
- Github
|
||||
- Gitlab
|
||||
@@ -18,39 +18,39 @@ VCS oznacza **Version Control System**, ten system pozwala developerom **zarząd
|
||||
|
||||
## CI/CD Pipelines
|
||||
|
||||
CI/CD pipelines umożliwiają developerom **automatyzację wykonywania code** do różnych celów, w tym budowania, testowania i wdrażania aplikacji. Te zautomatyzowane workflow są **wyzwalane przez konkretne akcje**, takie jak push code, pull requesty lub zadania zaplanowane. Są użyteczne do usprawnienia procesu od development do production.
|
||||
CI/CD pipelines umożliwiają developerom **automatyzację wykonywania code** do różnych celów, w tym buildowania, testowania i deployowania aplikacji. Te zautomatyzowane workflow są **wyzwalane przez określone akcje**, takie jak push code, pull requests lub zaplanowane zadania. Są przydatne do usprawnienia procesu od developmentu do production.
|
||||
|
||||
Jednak te systemy muszą być **uruchamiane gdzieś** i zwykle z **uprzywilejowanymi credentials do wdrażania code lub dostępu do poufnych informacji**.
|
||||
Jednak te systemy muszą być **wykonywane gdzieś** i zwykle z **privileged credentials do deploy code lub access do wrażliwych informacji**.
|
||||
|
||||
## VCS Pentesting Methodology
|
||||
|
||||
> [!NOTE]
|
||||
> Nawet jeśli niektóre platformy VCS pozwalają tworzyć pipelines, w tej sekcji przeanalizujemy tylko potencjalne ataki na kontrolę nad kodem źródłowym.
|
||||
> Nawet jeśli niektóre platformy VCS pozwalają tworzyć pipelines, w tej sekcji przeanalizujemy tylko potencjalne ataki na kontrolę source code.
|
||||
|
||||
Platformy zawierające kod źródłowy Twojego projektu zawierają poufne informacje i ludzie muszą bardzo uważać na uprawnienia nadawane w obrębie tej platformy. Oto kilka typowych problemów występujących na platformach VCS, które atakujący mógłby wykorzystać:
|
||||
Platformy, które zawierają source code twojego projektu, zawierają wrażliwe informacje i ludzie muszą bardzo uważać na uprawnienia przyznawane w tej platformie. Oto kilka typowych problemów występujących na platformach VCS, które attacker mógłby wykorzystać:
|
||||
|
||||
- **Leaks**: Jeśli Twój code zawiera leaks w commitach, a atakujący może uzyskać dostęp do repo (bo jest publiczne albo ma dostęp), może odkryć te leaks.
|
||||
- **Access**: Jeśli atakujący może **uzyskać dostęp do konta w platformie VCS**, może zdobyć **większą widoczność i więcej uprawnień**.
|
||||
- **Register**: Niektóre platformy po prostu pozwalają zewnętrznym użytkownikom utworzyć konto.
|
||||
- **SSO**: Niektóre platformy nie pozwalają użytkownikom się rejestrować, ale pozwalają każdemu uzyskać dostęp przy użyciu poprawnego SSO (więc atakujący mógłby na przykład użyć swojego konta github, aby wejść).
|
||||
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... istnieje kilka rodzajów tokenów, które użytkownik mógłby ukraść, aby w jakiś sposób uzyskać dostęp do repo.
|
||||
- **Webhooks**: Platformy VCS pozwalają generować webhooks. Jeśli nie są **zabezpieczone** niewidocznymi secrets, **atakujący mógłby je nadużyć**.
|
||||
- Jeśli nie ma ustawionego secret, atakujący może nadużyć webhooka platformy third party
|
||||
- Jeśli secret jest w URL, dzieje się to samo, a atakujący również ma secret
|
||||
- **Code compromise:** Jeśli złośliwy aktor ma jakiś rodzaj dostępu **write** do repo, może spróbować **wstrzyknąć złośliwy code**. Aby to się udało, może potrzebować **obejść branch protections**. Działania te mogą być wykonywane z różnymi celami:
|
||||
- Skompromitować główną gałąź, aby **skomproitować production**.
|
||||
- Skompromitować główną (lub inne gałęzie), aby **skomproitować maszyny developerów** (ponieważ zwykle uruchamiają oni test, terraform lub inne rzeczy w repo na swoich maszynach).
|
||||
- **Skompromitować pipeline** (sprawdź następną sekcję)
|
||||
- **Leaks**: Jeśli twój code zawiera leaks w commitach i attacker może access repo (bo jest publiczne albo bo ma access), może odkryć te leaks.
|
||||
- **Access**: Jeśli attacker może **access do account w platformie VCS**, może zyskać **większą widoczność i uprawnienia**.
|
||||
- **Register**: Niektóre platformy po prostu pozwalają zewnętrznym użytkownikom tworzyć account.
|
||||
- **SSO**: Niektóre platformy nie pozwalają użytkownikom się rejestrować, ale pozwalają każdemu access z ważnym SSO (więc attacker mógłby na przykład użyć swojego github account, aby wejść).
|
||||
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... istnieje kilka rodzajów tokens, które user może ukraść, aby w jakiś sposób access repo.
|
||||
- **Webhooks**: Platformy VCS pozwalają generować webhooks. Jeśli nie są **chronione** niewidocznymi secrets, **attacker could abuse them**.
|
||||
- Jeśli nie ma żadnego secret, attacker może wykorzystać webhook platformy zewnętrznej
|
||||
- Jeśli secret jest w URL, dzieje się to samo, a attacker także ma secret
|
||||
- **Code compromise:** Jeśli złośliwy actor ma jakiegoś rodzaju access **write** do repo, może spróbować **wstrzyknąć malicious code**. Aby odnieść sukces, może potrzebować **bypass branch protections**. Te działania mogą być wykonane z różnymi celami:
|
||||
- Compromise główną branch, aby **compromise production**.
|
||||
- Compromise główną (lub inne branches), aby **compromise developers machines** (ponieważ zwykle uruchamiają testy, terraform lub inne rzeczy w repo na swoich maszynach).
|
||||
- **Compromise the pipeline** (check next section)
|
||||
|
||||
## Pipelines Pentesting Methodology
|
||||
|
||||
Najczęstszym sposobem definiowania pipeline jest użycie **pliku CI configuration hostowanego w repository**, które pipeline buduje. Ten plik opisuje kolejność wykonywanych jobów, warunki wpływające na przepływ oraz ustawienia środowiska builda.\
|
||||
Te pliki zwykle mają spójną nazwę i format, na przykład — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI) oraz pliki YAML GitHub Actions znajdujące się w .github/workflows. Po uruchomieniu job pipeline **pobiera code** z wybranego źródła (np. commit / branch) i **uruchamia commands określone w pliku CI configuration** na tym code.
|
||||
Najczęstszym sposobem definiowania pipeline jest użycie **CI configuration file hostowanego w repository** budowanego przez pipeline. Ten plik opisuje kolejność wykonywanych jobs, warunki wpływające na flow oraz ustawienia środowiska build.\
|
||||
Te pliki zwykle mają spójną nazwę i format, na przykład — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI) oraz pliki YAML GitHub Actions znajdujące się w .github/workflows. Gdy pipeline zostanie wyzwolony, job pipeline **pobiera code** z wybranego source (np. commit / branch) i **uruchamia commands określone w CI configuration file** przeciwko temu code.
|
||||
|
||||
Dlatego ostatecznym celem atakującego jest w jakiś sposób **skomproitować te pliki konfiguracyjne** albo **commands, które wykonują**.
|
||||
Dlatego ostatecznym celem attacker jest w jakiś sposób **compromise tych configuration files** albo **commands, które wykonują**.
|
||||
|
||||
> [!TIP]
|
||||
> Niektóre hosted builders pozwalają contributorom wybrać Docker build context i ścieżkę do Dockerfile. Jeśli context jest kontrolowany przez atakującego, możesz ustawić go poza repo (np. ".."), aby w trakcie builda wczytać pliki hosta i wyekstrahować secrets. Zobacz:
|
||||
> Niektóre hosted builders pozwalają contributorom wybierać Docker build context i ścieżkę Dockerfile. Jeśli context jest kontrolowany przez attacker, możesz ustawić go poza repo (np. ".."), aby podczas build odczytać host files i exfiltrate secrets. Zobacz:
|
||||
>
|
||||
>{{#ref}}
|
||||
>docker-build-context-abuse.md
|
||||
@@ -58,72 +58,73 @@ Dlatego ostatecznym celem atakującego jest w jakiś sposób **skomproitować te
|
||||
|
||||
### PPE - Poisoned Pipeline Execution
|
||||
|
||||
Ścieżka Poisoned Pipeline Execution (PPE) wykorzystuje uprawnienia w repo SCM do manipulowania CI pipeline i wykonywania szkodliwych commands. Użytkownicy z odpowiednimi uprawnieniami mogą modyfikować pliki CI configuration lub inne pliki używane przez job pipeline, aby wstawić złośliwe commands. To „zatruwa” CI pipeline, prowadząc do wykonania tych złośliwych commands.
|
||||
Ścieżka Poisoned Pipeline Execution (PPE) wykorzystuje uprawnienia w repository SCM do manipulowania pipeline CI i uruchamiania harmful commands. Użytkownicy z odpowiednimi uprawnieniami mogą modyfikować CI configuration files lub inne pliki używane przez job pipeline, aby dodać malicious commands. To „zatruwa” pipeline CI, prowadząc do wykonania tych malicious commands.
|
||||
|
||||
Aby złośliwy aktor odniósł sukces w ataku PPE, musi być w stanie:
|
||||
Aby malicious actor mógł skutecznie przeprowadzić attack PPE, musi być w stanie:
|
||||
|
||||
- Mieć **write access do platformy VCS**, ponieważ zwykle pipelines są wyzwalane, gdy wykonywany jest push lub pull request. (Sprawdź VCS pentesting methodology, aby zobaczyć podsumowanie sposobów uzyskania dostępu).
|
||||
- Zwróć uwagę, że czasem **external PR liczy się jako "write access"**.
|
||||
- Nawet mając write permissions, musi mieć pewność, że może **modyfikować plik CI config lub inne pliki, na których opiera się config**.
|
||||
- W tym celu może potrzebować możliwości **obejścia branch protections**.
|
||||
- Mieć **write access do platformy VCS**, ponieważ zwykle pipelines są wyzwalane przy push lub pull request. (Sprawdź VCS pentesting methodology po podsumowanie sposobów uzyskania access).
|
||||
- Zwróć uwagę, że czasami **external PR count as "write access"**.
|
||||
- Nawet jeśli ma write permissions, musi mieć pewność, że może **modify CI config file lub other files, na których config polega**.
|
||||
- W tym celu może potrzebować możliwości **bypass branch protections**.
|
||||
|
||||
Istnieją 3 odmiany PPE:
|
||||
|
||||
- **D-PPE**: Atak **Direct PPE** występuje, gdy aktor **modyfikuje plik CI config**, który ma zostać wykonany.
|
||||
- **I-DDE**: Atak **Indirect PPE** występuje, gdy aktor **modyfikuje** **plik**, na którym opiera się plik CI config, który ma zostać wykonany (na przykład make file lub terraform config).
|
||||
- **Public PPE or 3PE**: W niektórych przypadkach pipeline mogą być **wyzwalane przez użytkowników, którzy nie mają write access do repo** (i którzy mogą nawet nie należeć do org), ponieważ mogą wysłać PR.
|
||||
- **3PE Command Injection**: Zwykle CI/CD pipelines **ustawiają environment variables** z **informacjami o PR**. Jeśli ta wartość może być kontrolowana przez atakującego (na przykład tytuł PR) i jest **używana** w **niebezpiecznym miejscu** (na przykład do wykonywania **sh commands**), atakujący może **wstrzyknąć tam commands**.
|
||||
- **D-PPE**: Atak **Direct PPE** występuje, gdy actor **modyfikuje CI config** file, który ma zostać wykonany.
|
||||
- **I-DDE**: Atak **Indirect PPE** występuje, gdy actor **modyfikuje** **file**, na którym CI config file, który ma zostać wykonany, **polega** (np. make file lub terraform config).
|
||||
- **Public PPE or 3PE**: W niektórych przypadkach pipelines mogą być **wyzwalane przez users, którzy nie mają write access w repo** (a nawet mogą nie być częścią org), ponieważ mogą wysłać PR.
|
||||
- **3PE Command Injection**: Zwykle CI/CD pipelines **ustawiają environment variables** z **informacjami o PR**. Jeśli taką wartością może sterować attacker (np. tytułem PR) i jest ona **używana** w **niebezpiecznym miejscu** (np. do wykonywania **sh commands**), attacker może **inject commands** tam.
|
||||
|
||||
### Exploitation Benefits
|
||||
|
||||
Znając 3 odmiany zatruwania pipeline, sprawdźmy, co atakujący może uzyskać po skutecznej eksploatacji:
|
||||
Znając 3 odmiany zatruwania pipeline, sprawdźmy, co attacker mógłby uzyskać po udanym exploitation:
|
||||
|
||||
- **Secrets**: Jak wspomniano wcześniej, pipelines wymagają **uprawnień** do swoich jobów (pobranie code, build, deploy itp.), a te uprawnienia są zwykle **zawarte w secrets**. Te secrets są zwykle dostępne przez **env variables lub pliki w systemie**. Dlatego atakujący zawsze będzie próbował wyekstrahować jak najwięcej secrets.
|
||||
- Zależnie od platformy pipeline atakujący **może potrzebować wskazać secrets w config**. Oznacza to, że jeśli atakujący nie może modyfikować CI configuration pipeline (**I-PPE** na przykład), może **ekstrahować tylko te secrets, które ma dany pipeline**.
|
||||
- **Computation**: Code jest wykonywany gdzieś; w zależności od tego gdzie, atakujący może być w stanie dalej pivotować.
|
||||
- **On-Premises**: Jeśli pipelines są uruchamiane on premises, atakujący może trafić do **internal network z dostępem do większej liczby zasobów**.
|
||||
- **Cloud**: Atakujący mógłby uzyskać dostęp do **innych maszyn w cloud**, ale także **ekstrahować** IAM roles/service accounts **tokens** z nich, aby uzyskać **dalszy dostęp wewnątrz cloud**.
|
||||
- **Platforms machine**: Czasem joby będą wykonywane na **maszynach platformy pipelines**, które zwykle są w cloud z **brakiem dalszego dostępu**.
|
||||
- **Select it:** Czasem **platforma pipelines będzie miała skonfigurowanych kilka maszyn** i jeśli możesz **modyfikować plik CI configuration**, możesz **określić, gdzie chcesz uruchomić złośliwy code**. W takiej sytuacji atakujący prawdopodobnie uruchomi reverse shell na każdej możliwej maszynie, aby spróbować wykorzystać ją dalej.
|
||||
- **Compromise production**: Jeśli jesteś inside pipeline, a finalna wersja jest z niego budowana i wdrażana, możesz **skomproitować code, który finalnie będzie uruchomiony w production**.
|
||||
- **Secrets**: Jak wspomniano wcześniej, pipelines wymagają **privileges** do swoich jobs (pobranie code, build, deploy it...) i te privileges są zwykle **przyznawane w secrets**. Te secrets są zwykle dostępne przez **env variables lub files wewnątrz systemu**. Dlatego attacker zawsze będzie próbował exfiltrate jak najwięcej secrets.
|
||||
- W zależności od platformy pipeline attacker **może potrzebować określić secrets w config**. Oznacza to, że jeśli attacker nie może modify CI configuration pipeline (**I-PPE** na przykład), może **tylko exfiltrate secrets, które ten pipeline ma**.
|
||||
- **Computation**: code jest wykonywany gdzieś, a w zależności od miejsca wykonania attacker może mieć możliwość dalszego pivot.
|
||||
- **On-Premises**: Jeśli pipelines są wykonywane on premises, attacker może skończyć w **internal network z access do większej liczby resources**.
|
||||
- **Cloud**: Attacker może access **other machines in the cloud**, ale także może **exfiltrate** IAM roles/service accounts **tokens** stamtąd, aby uzyskać **dalszy access inside the cloud**.
|
||||
- **Platforms machine**: Czasami jobs będą execute wewnątrz **maszyn platformy pipelines**, które zwykle znajdują się w cloud z **brakiem dalszego access**.
|
||||
- **Select it:** Czasami **platforma pipelines będzie miała skonfigurowane kilka maszyn** i jeśli możesz **modify CI configuration file**, możesz **wskazać, gdzie chcesz uruchomić malicious code**. W takiej sytuacji attacker prawdopodobnie uruchomi reverse shell na każdej możliwej maszynie, aby spróbować wykorzystać ją dalej.
|
||||
- **Compromise production**: Jeśli jesteś inside pipeline i finalna wersja jest z niego buildowana i deployowana, możesz **compromise code, który będzie ostatecznie działał w production**.
|
||||
|
||||
### Dependency & Registry Supply-Chain Abuse
|
||||
|
||||
Skompromitowanie CI/CD pipeline lub kradzież credentials z niego może pozwolić atakującemu przejść od **pipeline execution** do **ecosystem-wide code execution** poprzez backdooring dependencies lub release tooling:
|
||||
Compromising CI/CD pipeline albo stealing credentials z niego może pozwolić attackerowi przejść od **pipeline execution** do **ecosystem-wide code execution** przez backdooring dependencies lub release tooling:
|
||||
|
||||
- **Install-time code execution via package hooks**: opublikuj wersję package, która dodaje `preinstall`, `postinstall`, `prepare` lub podobne hooks, aby payload uruchamiał się automatycznie na stacjach developerów i runnerach CI podczas instalacji dependency.
|
||||
- **Secondary execution paths**: nawet jeśli cele instalują z `--ignore-scripts`, złośliwy package może nadal zarejestrować **common CLI name** w polu `bin`, dzięki czemu wrapper kontrolowany przez atakującego zostanie zlinkowany do `PATH` i uruchomi się później, gdy polecenie zostanie użyte.
|
||||
- **Runtime bootstrapping**: mały installer może pobrać drugi runtime lub toolchain podczas instalacji (na przykład Bun lub spakowany interpreter), a następnie uruchomić z nim główny payload, omijając lokalne wymagania dependency.
|
||||
- **Credential harvesting from build environments**: gdy code działa wewnątrz CI, sprawdź environment variables, `~/.npmrc`, `~/.git-credentials`, SSH keys, cloud CLI configs oraz lokalne narzędzia, takie jak `gh auth token`. W GitHub Actions sprawdź także secrets i artifacts specyficzne dla runnera.
|
||||
- **Workflow injection with stolen GitHub tokens**: token z uprawnieniami **`repo` + `workflow`** wystarcza, aby utworzyć branch, commit złośliwego pliku w `.github/workflows/`, uruchomić go, zebrać wygenerowane artifacts/logs, a następnie usunąć tymczasowy branch/uruchomienie workflow, aby ograniczyć ślady.
|
||||
- **Wormable registry propagation**: skradzione npm tokens należy zweryfikować pod kątem uprawnień **publish** i tego, czy omijają 2FA. Jeśli tak, wylicz zapisywalne packages, pobierz ich tarballe, wstrzyknij loader taki jak `setup.mjs`, ustaw `preinstall`, aby go wykonał, zwiększ wersję patch i opublikuj ponownie. To zamienia jedno skompromitowanie CI w auto-execution downstream w innych środowiskach.
|
||||
- **Install-time code execution via package hooks**: opublikuj wersję package, która dodaje `preinstall`, `postinstall`, `prepare` lub podobne hooks, aby payload uruchamiał się automatycznie na developer workstations i CI runners podczas dependency installation.
|
||||
- **Secondary execution paths**: nawet jeśli targets instalują z `--ignore-scripts`, malicious package nadal może zarejestrować **common CLI name** w polu `bin`, dzięki czemu wrapper kontrolowany przez attacker zostanie zlinkowany do `PATH` i uruchomi się później, gdy command zostanie użyty.
|
||||
- **Runtime bootstrapping**: mały installer może pobrać drugi runtime lub toolchain podczas installation (na przykład Bun lub spakowany interpreter), a następnie uruchomić z nim główny payload, omijając lokalne dependency requirements.
|
||||
- **Credential harvesting from build environments**: gdy code uruchamia się w CI, sprawdź environment variables, `~/.npmrc`, `~/.git-credentials`, SSH keys, cloud CLI configs i lokalne tooling, takie jak `gh auth token`. W GitHub Actions sprawdź też secrets i artifacts specyficzne dla runnera.
|
||||
- **Workflow injection with stolen GitHub tokens**: token z uprawnieniami **`repo` + `workflow`** wystarczy, aby utworzyć branch, commit z malicious file wewnątrz `.github/workflows/`, wyzwolić go, zebrać wygenerowane artifacts/logs, a następnie usunąć tymczasowy branch/workflow run, aby zmniejszyć ślady.
|
||||
- **Wormable registry propagation**: skradzione npm tokens należy zweryfikować pod kątem uprawnień **publish** i tego, czy omijają 2FA. Jeśli tak, zidentyfikuj writable packages, pobierz ich tarballs, wstrzyknij loader taki jak `setup.mjs`, ustaw `preinstall`, aby go uruchamiał, zwiększ patch version i opublikuj ponownie. To zamienia jedno kompromitowane CI w downstream auto-execution w innych środowiskach.
|
||||
|
||||
#### Practical checks during an assessment
|
||||
|
||||
- Przejrzyj release automation pod kątem hooks package-manager dodanych do `package.json`, nieoczekiwanych wpisów `bin` lub bumpów wersji, które zmieniają tylko release artifact.
|
||||
- Sprawdź, czy CI przechowuje długowieczne credentials registry w plikach tekstowych, takich jak `~/.npmrc`, zamiast używać krótkotrwałych OIDC lub trusted publishing.
|
||||
- Zweryfikuj, czy GitHub tokens dostępne w CI mogą zapisywać pliki workflow lub tworzyć branche/tagi.
|
||||
- Jeśli podejrzewany jest skompromitowany package, sprawdź opublikowany tarball, a nie tylko Git repository, ponieważ złośliwy loader/runtime może istnieć tylko w opublikowanym artefakcie.
|
||||
- Szukaj nieoczekiwanego wykonywania package-manager w CI, takiego jak `npm install` zamiast `npm ci`, nieoczekiwanych pobrań/uruchomień Bun lub nowych artifacts workflow generowanych z przejściowych branchy.
|
||||
- Przejrzyj release automation pod kątem package-manager hooks dodanych do `package.json`, nieoczekiwanych wpisów `bin` lub bumpów wersji, które zmieniają tylko release artifact.
|
||||
- Sprawdź, czy CI przechowuje długowieczne registry credentials w plikach tekstowych, takich jak `~/.npmrc`, zamiast używać krótkotrwałego OIDC lub trusted publishing.
|
||||
- Zweryfikuj, czy GitHub tokens dostępne w CI mogą zapisywać workflow files lub tworzyć branches/tags.
|
||||
- Jeśli podejrzewasz compromise package, sprawdź opublikowany tarball, a nie tylko Git repository, ponieważ malicious loader/runtime może istnieć tylko w opublikowanym artifact.
|
||||
- Szukaj nieoczekiwanego package-manager execution w CI, takiego jak `npm install` zamiast `npm ci`, nieoczekiwane pobrania/uruchomienia Bun lub nowe workflow artifacts generowane z transient branches.
|
||||
- Przejrzyj GitOps deployment engines także jako targets CI/CD. Specyficzna dla Argo CD enumeracja, abuse repo-server oraz ataki Redis cache poisoning są omówione w [Argo CD Security](argocd-security.md).
|
||||
|
||||
## More relevant info
|
||||
|
||||
### Tools & CIS Benchmark
|
||||
|
||||
- [**Chain-bench**](https://github.com/aquasecurity/chain-bench) to open-source tool do audytu software supply chain stack pod kątem zgodności bezpieczeństwa na podstawie nowego [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf). Audyt koncentruje się na całym procesie SDLC, gdzie może ujawnić ryzyka od code time do deploy time.
|
||||
- [**Chain-bench**](https://github.com/aquasecurity/chain-bench) to open-source tool do audytu software supply chain stack pod kątem security compliance na podstawie nowego [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf). Audyt skupia się na całym procesie SDLC, gdzie może ujawnić risks od code time do deploy time.
|
||||
|
||||
### Top 10 CI/CD Security Risk
|
||||
|
||||
Sprawdź ten interesujący artykuł o top 10 ryzykach CI/CD według Cider: [**https://www.cidersecurity.io/top-10-cicd-security-risks/**](https://www.cidersecurity.io/top-10-cicd-security-risks/)
|
||||
Sprawdź ten interesujący artykuł o top 10 CI/CD risks według Cider: [**https://www.cidersecurity.io/top-10-cicd-security-risks/**](https://www.cidersecurity.io/top-10-cicd-security-risks/)
|
||||
|
||||
### Labs
|
||||
|
||||
- Na każdej platformie, którą możesz uruchomić lokalnie, znajdziesz instrukcję, jak uruchomić ją lokalnie, aby móc skonfigurować ją tak, jak chcesz do testów
|
||||
- Na każdej platformie, którą możesz uruchomić lokalnie, znajdziesz instrukcje, jak uruchomić ją lokalnie, aby móc skonfigurować ją tak, jak chcesz do testów
|
||||
- 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** to narzędzie static code analysis dla infrastructure-as-code.
|
||||
- [**Checkov**](https://github.com/bridgecrewio/checkov): **Checkov** to narzędzie do static code analysis dla infrastructure-as-code.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
Reference in New Issue
Block a user