mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 14:47:17 -07:00
Translated ['src/pentesting-cloud/azure-security/az-post-exploitation/RE
This commit is contained in:
Binary file not shown.
@@ -4,33 +4,33 @@
|
||||
|
||||
## Basic Information
|
||||
|
||||
[Argo CD](https://argo-cd.readthedocs.io/) 是一个面向 Kubernetes 的 GitOps continuous delivery platform。它会监视 Git repositories,使用 Helm、Kustomize、Jsonnet 或 config management plugins 等工具渲染 Kubernetes manifests,并将 live cluster state 与存储在 Git 中的 desired state 进行 reconcile。
|
||||
[Argo CD](https://argo-cd.readthedocs.io/) 是一个用于 Kubernetes 的 GitOps continuous delivery platform。它监视 Git repositories,使用 Helm、Kustomize、Jsonnet 或 config management plugins 等工具渲染 Kubernetes manifests,并将 live cluster state 与 Git 中存储的 desired state 进行协调。
|
||||
|
||||
从攻击者视角来看,应将 Argo CD 视为一个带有 Kubernetes credentials 的 **deployment engine**。一次有效的 Argo CD compromise 可能导致:
|
||||
从攻击者的角度来看,应将 Argo CD 视为一个**拥有 Kubernetes credentials 的 deployment engine**。一次有效的 Argo CD compromise 可能导致:
|
||||
|
||||
- 访问 private Git repositories 和 repository credentials。
|
||||
- 访问 Argo CD 使用的 Kubernetes cluster secrets。
|
||||
- 在 `argocd-repo-server` 中执行 manifest generation code。
|
||||
- 通过 trusted Git repositories、Argo CD applications 或 cache manipulation 非授权部署 Kubernetes objects。
|
||||
- 通过受信任的 Git repositories、Argo CD applications 或 cache manipulation,未经授权地部署 Kubernetes objects。
|
||||
|
||||
## Architecture & Interesting Components
|
||||
|
||||
Common Kubernetes objects and services:
|
||||
常见的 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 和 authorization。
|
||||
- **`argocd-application-controller`**: 比较 desired 和 live state,然后将 resources 应用到 Kubernetes。
|
||||
- **`argocd-repo-server`**: clones repositories,缓存 Git data,并运行 Helm/Kustomize/Jsonnet/plugins 以生成 manifests。默认 gRPC 端口是 **8081**。
|
||||
- **`argocd-redis`**: application、manifest 和 Git reference data 的 cache。默认 Redis 端口是 **6379**。
|
||||
- **`argocd-applicationset-controller`**: 从 Git、SCM、clusters 和 pull requests 等 generators 生成 Argo CD `Application` objects。
|
||||
- **`argocd-server`**:公共 API、web UI、CLI API、身份验证和授权。
|
||||
- **`argocd-application-controller`**:比较期望状态和实际状态,然后将资源应用到 Kubernetes。
|
||||
- **`argocd-repo-server`**:克隆仓库、缓存 Git 数据,并运行 Helm/Kustomize/Jsonnet/plugins 以生成 manifests。默认 gRPC 端口为 **8081**。
|
||||
- **`argocd-redis`**:用于缓存 application、manifest 和 Git reference 数据。默认 Redis 端口为 **6379**。
|
||||
- **`argocd-applicationset-controller`**:根据 Git、SCM、clusters 和 pull requests 等 generators 生成 Argo CD `Application` 对象。
|
||||
|
||||
从被 compromise 的 pod 或 internal network segment 中,检查 internal reachability:
|
||||
从已被攻陷的 pod 或内部网络 segment 中,检查内部可达性:
|
||||
```bash
|
||||
nc -vz <argocd-server> 443
|
||||
nc -vz <argocd-repo-server> 8081
|
||||
@@ -38,7 +38,7 @@ nc -vz <argocd-redis> 6379
|
||||
```
|
||||
## Public API / UI 攻击
|
||||
|
||||
如果你有 Argo CD credentials 或一个暴露的 instance,先从 normal API surface 开始:
|
||||
如果你拥有 Argo CD credentials 或发现了暴露的实例,请从常规 API surface 开始:
|
||||
```bash
|
||||
argocd login <argocd-server>
|
||||
argocd account get-user-info
|
||||
@@ -49,15 +49,15 @@ 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 选项、plugin settings 或 sync options,让 Argo CD 部署 attacker-controlled manifests。
|
||||
- **Project misconfiguration**: `AppProject` objects 可能允许过宽的 `sourceRepos`、过宽的 `destinations`、不安全的 `clusterResourceWhitelist`,或薄弱的 namespace restrictions。
|
||||
- **Repository credential abuse**: repository secrets、GitHub App credentials、SSH keys 和 tokens 可能允许向受信任的 repos 推送,或添加 malicious dependencies。
|
||||
- **Cluster credential abuse**: cluster secrets 可能包含 bearer tokens 或 exec-provider configuration,供 Argo CD 用于部署到 target clusters。
|
||||
- **Local admin / project tokens**: 长期有效的 Argo CD tokens 除非被 revoke 或 expired,否则可以通过 API 重用。
|
||||
- **Application 写入权限**:修改 `source.repoURL`、`source.path`、Helm values、Kustomize options、plugin settings 或 sync options,使 Argo CD 部署攻击者控制的 manifests。
|
||||
- **Project 配置错误**:`AppProject` objects 可能允许宽泛的 `sourceRepos`、宽泛的 `destinations`、不安全的 `clusterResourceWhitelist` 或薄弱的 namespace restrictions。
|
||||
- **Repository credential abuse**:repository secrets、GitHub App credentials、SSH keys 和 tokens 可能允许向受信任的 repos 推送内容或添加恶意 dependencies。
|
||||
- **Cluster credential abuse**:cluster secrets 可能包含 bearer tokens 或 exec-provider configuration,供 Argo CD 部署到目标 clusters。
|
||||
- **Local admin / project tokens**:长期有效的 Argo CD tokens 可通过 API 重用,除非已被 revoke 或过期。
|
||||
|
||||
当你拥有 cluster read access 时,枚举 Kubernetes 中的配置:
|
||||
当你拥有 cluster read access 时,从 Kubernetes 枚举 configuration:
|
||||
```bash
|
||||
kubectl get applications.argoproj.io -A -o yaml
|
||||
kubectl get appprojects.argoproj.io -A -o yaml
|
||||
@@ -67,102 +67,102 @@ kubectl get cm -n argocd argocd-cm argocd-rbac-cm argocd-cmd-params-cm -o yaml
|
||||
```
|
||||
## Trusted Git Repository Abuse
|
||||
|
||||
如果你可以 push 到一个被 Argo CD trusted 的 repository,你通常可以影响部署内容。影响取决于 `AppProject` 边界以及 application controller 使用的 service account 权限。
|
||||
如果你可以向 Argo CD 信任的 repository push,通常就能影响部署的内容。影响取决于 `AppProject` 的边界,以及 application controller 使用的 service account 权限。
|
||||
|
||||
常见 payload 位置:
|
||||
常见的 payload 位置:
|
||||
|
||||
- application path 下的原始 Kubernetes YAML。
|
||||
- Helm chart templates 和 `values.yaml`。
|
||||
- Kustomize overlays、remote bases 和 generators。
|
||||
- Jsonnet 或 config management plugin 输入。
|
||||
- 创建或更新 `Application` objects 的 ApplicationSet generator files。
|
||||
- Jsonnet 或 config management plugin 的输入。
|
||||
- 用于创建或更新 `Application` 对象的 ApplicationSet generator 文件。
|
||||
|
||||
检查 app 是否使用 automated sync、pruning、self-heal、sync windows 或 manual approvals:
|
||||
检查应用是否使用 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'
|
||||
```
|
||||
## 直接滥用 `argocd-repo-server`
|
||||
|
||||
不要假设公开的 Argo CD API 是唯一的攻击面。内部 Argo CD 组件通过 gRPC 与 `argocd-repo-server` 通信。若任意 pods 能够访问 repo-server,攻击者控制的内部请求可能绕过通常由 `argocd-server` 强制执行的检查。
|
||||
不要假设 public Argo CD API 是唯一的攻击面。Argo CD 内部组件通过 gRPC 与 `argocd-repo-server` 通信。如果任意 pod 都能访问 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
|
||||
```
|
||||
Interesting signs:
|
||||
值得关注的迹象:
|
||||
|
||||
- repo-server gRPC endpoint 可从非 Argo CD pods 访问。
|
||||
- NetworkPolicies 缺失,或只允许 allow-list egress 但未拒绝 ingress。
|
||||
- repo-server 可访问自定义 config management plugins、decryption tools,或来自多个 tenant 的 repository content。
|
||||
- Redis 可从非 Argo CD pods 访问;如果 credentials 可用或不需要,就可能进行 cache inspection 或 tampering。
|
||||
- 缺少 NetworkPolicies,或仅允许 egress 白名单而未拒绝 ingress。
|
||||
- repo-server 可访问 custom config management plugins、decryption tools,或来自多个 tenants 的 repository 内容。
|
||||
- Redis 可从非 Argo CD pods 访问;如果凭据可用或不需要凭据,可能允许进行 cache inspection 或 tampering。
|
||||
|
||||
## 通过 Kustomize Options 实现未认证的 Repo-Server RCE
|
||||
## 未认证的 Repo-Server RCE via Kustomize Options
|
||||
|
||||
在 2026 年 7 月,Synacktiv 披露了 Argo CD 的 `repo-server` 中一条未认证 code execution 链,当 attacker 能访问内部 gRPC service 时即可触发。该攻击滥用对 `/repository.RepoServerService/GenerateManifest` 的直接访问,以及 attacker-controlled 的 `KustomizeOptions`。
|
||||
2026 年 7 月,Synacktiv 披露了 Argo CD 中的一条未认证 code execution chain:当攻击者能够访问内部 gRPC service 时,可对 `repo-server` 发起攻击。该攻击滥用对 `/repository.RepoServerService/GenerateManifest` 的直接访问,以及由攻击者控制的 `KustomizeOptions`。
|
||||
|
||||
危险的 primitive 是强制 repo-server clone attacker-controlled repository content,并在启用 Helm support 的情况下运行 Kustomize:
|
||||
其中的危险 primitive 是强制 repo-server clone 由攻击者控制的 repository 内容,并运行带 Helm support 的 Kustomize:
|
||||
```bash
|
||||
kustomize build <attacker_repo_path> --enable-helm --helm-command ./payload.sh
|
||||
```
|
||||
触发 Helm 处理所需的最小恶意 Kustomize 输入:
|
||||
最小恶意 Kustomize 输入需要触发 Helm 处理:
|
||||
```yaml
|
||||
helmCharts:
|
||||
- name: pwn
|
||||
version: 0.0.1
|
||||
```
|
||||
为什么这可行:
|
||||
为什么这能生效:
|
||||
|
||||
- `argocd-repo-server` 会在渲染之前先 clone 该 repository。
|
||||
- `--helm-command ./payload.sh` 会相对于已 clone 的 repository 来解析。
|
||||
- 如果 attacker 能控制被渲染的 repository 和 Kustomize build options,就不需要 shell metacharacter injection 也能实现 Code execution。
|
||||
- `argocd-repo-server` 会在渲染前 clone repository。
|
||||
- `--helm-command ./payload.sh` 会解析为相对于 cloned repository 的路径。
|
||||
- 如果 attacker 能够控制 rendered repository 和 Kustomize build options,则无需注入 shell metacharacter 也能实现 code execution。
|
||||
|
||||
在 Synacktiv 于 2026 年 7 月 1 日披露时,他们报告该问题没有官方修复或 CVE。应首先将其视为一个网络暴露问题:exploitation 需要能够访问内部的 repo-server gRPC 端口。
|
||||
在 Synacktiv 于 2026 年 7 月 1 日披露时,他们报告称该问题尚无官方修复或 CVE。应首先将其视为 network-exposure issue:利用需要能够访问内部 repo-server gRPC port。
|
||||
|
||||
## Redis Cache Poisoning to Deploy Manifests
|
||||
|
||||
在 `argocd-repo-server` 中实现 Code execution 后,或者在使用有效凭据直接访问 Redis 后,检查 Redis-backed cache entries。Argo CD 通常会存储 gzip-compressed JSON values。
|
||||
在 `argocd-repo-server` 中实现 code execution 后,或使用有效 credentials 直接访问 Redis 后,检查 Redis-backed cache entries。Argo CD 通常会存储 gzip-compressed JSON values。
|
||||
|
||||
有趣的 key prefixes:
|
||||
Interesting 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 attack 利用了两种状态:
|
||||
Synacktiv 描述的 cache poisoning attack 滥用了两部分状态:
|
||||
|
||||
1. 修改相关的 `mfst|...` manifest cache entry,以包含攻击者控制的 Kubernetes manifest。
|
||||
2. 修改相关的 `git-refs|...` mapping,让 Argo CD 认为 branch 已移动,然后再回滚到缓存的 revision。
|
||||
1. 修改相关的 `mfst|...` manifest cache 条目,使其包含攻击者控制的 Kubernetes manifest。
|
||||
2. 修改相关的 `git-refs|...` 映射,使 Argo CD 认为分支已发生移动,然后重新 reconcile 到缓存的 revision。
|
||||
|
||||
影响:
|
||||
|
||||
- 启用 Auto Sync 时,Argo CD 可能会自动应用被污染的 cached manifest。
|
||||
- 未启用 Auto Sync 时,当用户手动 sync 该 application 时,payload 仍可能被应用。
|
||||
- 最终影响受目标 application 的 destination 以及 Argo CD 可用的 Kubernetes permissions 限制。
|
||||
- 启用 Auto Sync 时,Argo CD 可能会自动应用被污染的缓存 manifest。
|
||||
- 未启用 Auto Sync 时,用户手动 sync application 仍可能应用 payload。
|
||||
- 最终影响受目标 application 的 destination 以及 Argo CD 可用的 Kubernetes 权限限制。
|
||||
|
||||
## ApplicationSet Attacks
|
||||
|
||||
ApplicationSet 尤其敏感,因为它会根据 generator output 创建或更新 `Application` objects。
|
||||
ApplicationSet 尤其敏感,因为它会根据 generator 输出创建或更新 `Application` 对象。
|
||||
|
||||
Review:
|
||||
检查:
|
||||
```bash
|
||||
kubectl get applicationsets.argoproj.io -A -o yaml
|
||||
kubectl get appprojects.argoproj.io -A -o yaml
|
||||
```
|
||||
Interesting patterns:
|
||||
有趣的模式:
|
||||
|
||||
- Git generators reading attacker-writable files that control app names, paths, projects or destinations.
|
||||
- Pull request generators for public repositories where untrusted contributors can influence generated applications.
|
||||
- Template fields that allow broad destination clusters/namespaces.
|
||||
- AppProjects that permit `sourceRepos: ["*"]` or broad `destinations`.
|
||||
- Generated applications that inherit automated sync and pruning.
|
||||
- Git generators 读取 attacker-writable files,而这些文件可控制 app names、paths、projects 或 destinations。
|
||||
- 面向 public repositories 的 Pull request generators,其中 untrusted contributors 可以影响生成的 applications。
|
||||
- 允许使用 broad destination clusters/namespaces 的 Template fields。
|
||||
- 允许 `sourceRepos: ["*"]` 或 broad `destinations` 的 AppProjects。
|
||||
- 继承 automated sync 和 pruning 的 Generated applications。
|
||||
|
||||
## Post-Exploitation
|
||||
|
||||
From an Argo CD pod shell, prioritize:
|
||||
从 Argo CD pod shell 中,优先检查:
|
||||
```bash
|
||||
env
|
||||
cat /proc/1/environ 2>/dev/null | tr '\0' '\n'
|
||||
@@ -171,24 +171,24 @@ mount | grep -E 'secret|token|config'
|
||||
```
|
||||
有用的目标:
|
||||
|
||||
- 窃取 `REDIS_PASSWORD` 或 Redis TLS/client 材料。
|
||||
- 窃取 `REDIS_PASSWORD` 或 Redis TLS/client material。
|
||||
- 从挂载的 secrets 或 Argo CD Kubernetes secrets 中提取 repository credentials。
|
||||
- 识别 Argo CD 使用的 cluster credentials。
|
||||
- 读取生成的 manifests 和可能包含注入 secrets 的 plugin output。
|
||||
- 检查 custom plugins、SOPS、Helm secrets、Vault plugins 或 cloud CLIs 是否暴露了 decryption keys 和 cloud credentials。
|
||||
- 读取生成的 manifests 和 plugin output,其中可能包含注入的 secrets。
|
||||
- 检查 custom plugins、SOPS、Helm secrets、Vault plugins 或 cloud CLIs 是否暴露 decryption keys 和 cloud credentials。
|
||||
|
||||
## 检测与加固
|
||||
## Detection & Hardening
|
||||
|
||||
重要检查:
|
||||
重要检查项:
|
||||
|
||||
- 通过 NetworkPolicies 限制 `argocd-repo-server` 端口 **8081** 和 Redis 端口 **6379**,确保只有预期的 Argo CD 组件可以访问它们。
|
||||
- 在 Helm deployments 中,确认 network policies 确实被创建。Argo CD Helm chart values 过去通常将组件 network policy creation 默认设为 disabled。
|
||||
- 将 `argocd-server` 保持为经过认证的入口点。内部服务不应能被任意 workloads 访问。
|
||||
- 禁用未使用的 config management tools 和 plugins。
|
||||
- 使用 NetworkPolicies 限制 `argocd-repo-server` 端口 **8081** 和 Redis 端口 **6379**,确保只有预期的 Argo CD 组件可以访问它们。
|
||||
- 在 Helm deployments 中,确认确实创建了 network policies。Argo CD Helm chart 的 values 长期以来默认将 component network policy creation 设置为 disabled。
|
||||
- 保持 `argocd-server` 作为经过认证的入口点。内部服务不应被任意 workloads 访问。
|
||||
- Disable 未使用的 config management tools 和 plugins。
|
||||
- 限制 `AppProject` 的 `sourceRepos`、`destinations`、namespace permissions 和 cluster-scoped resources。
|
||||
- 避免存储过于宽泛的 repository credentials,以免被低权限 Argo CD user 触发复用。
|
||||
- 避免将 broad repository credentials 存储在低权限 Argo CD user 可以促使其复用的位置。
|
||||
- 监控 repo-server requests、Kustomize build options、plugin executions、Redis writes,以及对 `mfst|` / `git-refs|` keys 的异常访问。
|
||||
- 在发生 compromise 后,轮换 Argo CD local users、project tokens、repository credentials 和 cluster credentials。
|
||||
- 在发生 compromise 后,rotate Argo CD local users、project tokens、repository credentials 和 cluster credentials。
|
||||
|
||||
有用的命令:
|
||||
```bash
|
||||
@@ -197,15 +197,15 @@ 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
|
||||
## CodeQL 中的 Static Analysis Note:Typed API Requests
|
||||
|
||||
对于使用 gRPC/REST handlers 的 Go services,默认的 CodeQL remote sources 可能会在原始输入被 unmarshaled 成 typed request objects 之后漏掉 flows。对 Argo CD 风格的 services,一个有用的 model 是:
|
||||
对于使用 gRPC/REST handlers 的 Go services,当 raw input 被 unmarshaled 到 typed request objects 后,默认的 CodeQL remote sources 可能会遗漏 flows。对于 Argo CD-style services,一个有用的 model 是:
|
||||
|
||||
- Receiver type 例如 `Server` 或 `Service`。
|
||||
- 第一个参数是 `context.Context`。
|
||||
- 第二个参数是 typed request object。
|
||||
- Receiver type,例如 `Server` 或 `Service`。
|
||||
- First parameter 是 `context.Context`。
|
||||
- Second parameter 是 typed request object。
|
||||
|
||||
把这个第二个参数建模为 remote source,并为 `exec.Command` / `exec.CommandContext` arguments 添加 custom sinks。这有助于发现从内部 API request fields 到 command execution helpers 的 flows。
|
||||
将 second parameter model 为 remote source,并为 `exec.Command` / `exec.CommandContext` arguments 添加 custom sinks。这有助于发现从 internal API request fields 流向 command execution helpers 的 flows。
|
||||
|
||||
## References
|
||||
|
||||
@@ -217,3 +217,4 @@ kubectl describe networkpolicy -n argocd argocd-redis-network-policy 2>/dev/null
|
||||
- [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)
|
||||
{{#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}}
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
# Az - Container Registry Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Azure Container Registry
|
||||
|
||||
有关此服务的更多信息,请查看:
|
||||
|
||||
{{#ref}}
|
||||
../az-services/az-container-registry.md
|
||||
{{#endref}}
|
||||
|
||||
### `Microsoft.ContainerRegistry/registries/listCredentials/action`, `Microsoft.ContainerRegistry/registries/write`
|
||||
|
||||
具有 ACR management-plane 访问权限的身份可以将该访问权限转换为**可复用的 Docker 凭据**。如果已禁用 **admin user**,但该主体同时拥有 `registries/write`,则启用它、获取密码,然后直接针对 `<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>
|
||||
```
|
||||
这很有用,因为恢复的凭据可以在 Azure CLI 之外重复使用,以 **list、pull、push、overwrite,以及有时 delete** registry 内容,直到 admin account 被禁用或密码完成轮换。
|
||||
|
||||
### `Microsoft.ContainerRegistry/registries/pull/read`
|
||||
|
||||
使用 pull access 对镜像执行 **repository reconnaissance** 和 **secret hunting**。同时检查最终的 container configuration 和历史 filesystem layers,因为某一层中复制的文件即使之后被删除,仍可能可以恢复。
|
||||
```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>
|
||||
```
|
||||
高价值目标包括**环境变量**、**应用配置**、**部署脚本**、**证书**、**访问令牌**和**连接字符串**。在检查各层时,如需更多思路,请参阅 Docker forensics 页面:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
|
||||
{{#endref}}
|
||||
|
||||
### `Microsoft.ContainerRegistry/registries/push/write`
|
||||
|
||||
Push 访问权限可让攻击者**污染受信任的仓库**或**覆盖可变标签**,例如 `latest`、`prod` 或 `stable`。任何仍按标签而非 digest 部署的工作负载,都可能在下一次部署、扩容事件或重启时拉取攻击者的镜像。
|
||||
```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>
|
||||
```
|
||||
在替换 tag 之前,请确认下游 workloads 实际使用了哪些 repositories 和 tags。使用 **Digest-pinned** 的 consumers(`@sha256:...`)比基于 tag 的 consumers 更难重定向。
|
||||
|
||||
### `Microsoft.ContainerRegistry/registries/push/write`、`Microsoft.ContainerInstance/containerGroups/restart/action`
|
||||
|
||||
如果你既能**替换下游 container workload 使用的 image**,又能**重启**该 workload,那么恶意 entrypoint 就会在目标 container 的**网络和 managed identity 上下文**中执行。之后,该 image 可以从 IMDS 请求 tokens,并访问该 workload identity 可访问的 Azure resources。
|
||||
```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>
|
||||
```
|
||||
这会将 ACR tag overwrite 转化为 **code execution**、**secret theft** 或 **lateral movement**,影响任何信任被修改 tag 且暴露有用 identity 的 container consumer。
|
||||
|
||||
### 相关 privesc 路径:ACR Tasks managed identities
|
||||
|
||||
如果你还拥有 `Microsoft.ContainerRegistry/registries/tasks/write` 和 `Microsoft.ContainerRegistry/registries/runs/write`,请转到 ACR privesc 路径,直接滥用 task 的 managed identity:
|
||||
|
||||
{{#ref}}
|
||||
../az-privilege-escalation/az-container-registry-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
## 参考资料
|
||||
|
||||
- [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,11 +4,11 @@
|
||||
|
||||
## 基本信息
|
||||
|
||||
Azure Container Registry (ACR) 是一个安全的私有 registry,可让你在 Azure cloud 中**存储、管理和访问 container images**。它可与多个 Azure 服务无缝集成,提供大规模的自动化构建和部署工作流。凭借 geo-replication 和 vulnerability scanning 等功能,ACR 有助于确保 containerized applications 达到企业级安全性和合规性。
|
||||
Azure Container Registry (ACR) 是一个安全的私有 registry,可让你在 **Azure cloud 中存储、管理和访问 container images**。它与多个 Azure services 无缝集成,可大规模提供自动化的 build 和 deployment workflows。借助 geo-replication 和 vulnerability scanning 等功能,ACR 有助于确保 containerized applications 达到 enterprise-grade 的安全性和合规性。
|
||||
|
||||
### Permissions
|
||||
|
||||
这些是根据文档可授予 Container Registry 的**不同权限** [according to the docs](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager):
|
||||
以下是 [according to the docs](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager) 可针对 Container Registry 授予的**不同 permissions**:
|
||||
|
||||
- Access Resource Manager
|
||||
- Create/delete registry
|
||||
@@ -18,23 +18,23 @@ Azure Container Registry (ACR) 是一个安全的私有 registry,可让你在
|
||||
- Change policies
|
||||
- Sign images
|
||||
|
||||
另外还有一些可分配的**built-in roles**,也可以创建**custom roles**。
|
||||
此外,还可以分配一些 **built-in roles**,也可以创建 **custom roles**。
|
||||
|
||||

|
||||

|
||||
|
||||
### Authentication
|
||||
|
||||
> [!WARNING]
|
||||
> 即使 registry 名称包含大写字母,登录、push 和 pull images 时也务必要始终使用**小写字母**。
|
||||
> 非常重要:即使 registry name 包含大写字母,也应始终使用**小写字母**来 login、push 和 pull images。
|
||||
|
||||
有 4 种方式可以 authenticate 到 ACR:
|
||||
有 4 种方式可以向 ACR 进行 authentication:
|
||||
|
||||
- **With Entra ID**:这是 authenticate 到 ACR 的**默认**方式。它使用 **`az acr login`** 命令来对 ACR 进行 authentication。该命令会将凭据**存储**在 **`~/.docker/config.json`** 文件中。此外,如果你在一个无法访问 docker socket 的环境中运行该命令,比如 **cloud shell**,可以使用 **`--expose-token`** 参数获取用于 authenticate 到 ACR 的**token**。然后要进行 authentication,你需要将用户名设为 `00000000-0000-0000-0000-000000000000`,例如:`docker login myregistry.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password-stdin <<< $TOKEN`
|
||||
- **With an admin account**:admin user 默认是禁用的,但可以启用,之后就能使用 admin account 的**username** 和 **password** 访问 registry,并拥有对 registry 的完全权限。由于某些 Azure 服务会使用它,因此它仍然受支持。注意会为该用户创建**2 passwords**,两者都有效。你可以通过 `az acr update -n <acrName> --admin-enabled true` 启用它。注意 username 通常是 registry name(而不是 `admin`)。
|
||||
- **With a token**:可以创建一个带有特定 **`scope map`**(permissions)的 **token** 来访问 registry。之后可以使用 token 名称作为 username,并使用任意一个生成的 password,通过 `docker login -u <registry-name> -p <password> <registry-url>` authenticate 到 registry
|
||||
- **With a Service Principal**:可以创建一个 **service principal** 并分配像 **`AcrPull`** 这样的 role 来 pull images。然后就可以使用 SP appId 作为 username、生成的 secret 作为 password 来**login to the registry**
|
||||
- **With Entra ID**:这是向 ACR 进行 authentication 的**默认**方式。它使用 **`az acr login`** command 对 ACR 进行 authentication。此 command 会将 **credentials 存储**在 **`~/.docker/config.json`** file 中。此外,如果你在无法访问 docker socket 的 environment(例如 **cloud shell**)中运行此 command,可以使用 **`--expose-token`** flag 获取用于向 ACR 进行 authentication 的 **token**。之后进行 authentication 时,需要使用 `00000000-0000-0000-0000-000000000000` 作为 username,例如:`docker login myregistry.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password-stdin <<< $TOKEN`
|
||||
- **With an admin account**:admin user 默认处于 disabled 状态,但可以启用。启用后,即可使用 admin account 的 **username** 和 **password** 访问 registry,并拥有 registry 的全部 permissions。由于某些 Azure services 仍会使用它,因此仍支持此方式。请注意,此 user 会创建 **2 个 passwords**,且两者均有效。可以使用 `az acr update -n <acrName> --admin-enabled true` 启用它。请注意,username 通常是 registry name(而不是 `admin`)。
|
||||
- **With a token**:可以创建一个带有**特定 `scope map`**(permissions)的 **token**,用于访问 registry。然后,可以使用 token name 作为 username,并使用生成的 passwords 中的任意一个,通过 `docker login -u <registry-name> -p <password> <registry-url>` 向 registry 进行 authentication。
|
||||
- **With a Service Principal**:可以创建一个 **service principal**,并为其分配 **`AcrPull`** 等 role 以 pull images。之后,可以使用 SP appId 作为 username,并使用生成的 secret 作为 password **login to the registry**。
|
||||
|
||||
来自 [docs](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal) 的用于生成具有 registry 访问权限的 SP 的示例脚本:
|
||||
以下是 [docs](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal) 中用于生成一个对 registry 具有访问权限的 SP 的示例 script:
|
||||
```bash
|
||||
#!/bin/bash
|
||||
ACR_NAME=$containerRegistry
|
||||
@@ -51,39 +51,39 @@ echo "Service principal password: $PASSWORD"
|
||||
```
|
||||
### Encryption
|
||||
|
||||
只有 **Premium SKU** 支持 images 和其他 artifacts 的 **encryption at rest**。
|
||||
只有 **Premium SKU** 支持对 images 和其他 artifacts 进行 **encryption at rest**。
|
||||
|
||||
### Networking
|
||||
|
||||
只有 **Premium SKU** 支持 **private endpoints**。其他的只支持 **public access**。public endpoint 的格式是 `<registry-name>.azurecr.io`,private endpoint 的格式是 `<registry-name>.privatelink.azurecr.io`。因此,registry 的名称必须在整个 Azure 中唯一。
|
||||
只有 **Premium SKU** 支持 **private endpoints**。其他 SKU 仅支持 **public access**。public endpoint 的格式为 `<registry-name>.azurecr.io`,private endpoint 的格式为 `<registry-name>.privatelink.azurecr.io`。因此,registry 的名称必须在所有 Azure 中保持唯一。
|
||||
|
||||
### Microsoft Defender for Cloud
|
||||
|
||||
这允许你对 registry 中的 **images** 进行 **vulnerabilities** 扫描。
|
||||
此功能允许你对 registry 中的 **images** 执行 **vulnerabilities 扫描**。
|
||||
|
||||
### Soft-delete
|
||||
|
||||
**soft-delete** 功能允许你在指定天数内 **recover a deleted registry**。该功能默认 **disabled**。
|
||||
**soft-delete** 功能允许你在指定的天数内 **恢复已删除的 registry**。此功能默认处于**禁用**状态。
|
||||
|
||||
### Webhooks
|
||||
|
||||
可以在 registries 中 **create webhooks**。在这个 webhook 中,需要指定一个 URL,当执行 **push or delete action** 时会向该 URL 发送 **request**。此外,Webhooks 还能指定 scope,用来表示会受影响的 repositories (images)。例如,`foo:\*` 表示 repository `foo` 下的事件。
|
||||
可以在 registries 中 **创建 webhooks**。在此 webhook 中,需要指定一个 URL,当执行 **push 或 delete 操作时,将向该 URL 发送 request**。此外,Webhooks 可以指定 scope,以表明哪些 repositories(images)会受到影响。例如,`'foo:\*'` 表示 repository `'foo'` 下的事件。
|
||||
|
||||
从 attacker 的角度来看,最好在 registry 中执行任何操作之前先检查这一点,如果需要,可以临时移除它,以避免被发现。
|
||||
从攻击者的角度来看,在 registry 中执行任何操作**之前**检查这一点很有意义;如有需要,可以暂时移除它,以避免被发现。
|
||||
|
||||
### Connected registries
|
||||
|
||||
这基本上允许将一个 registry 中的 **images mirror** 到另一个 registry,通常位于 on-premises。
|
||||
这基本上允许将一个 registry 中的 **images 镜像**到另一个 registry,后者通常位于本地环境中。
|
||||
|
||||
它有 2 种模式:**ReadOnly** 和 **ReadWrite**。在第一种模式下,images 只会从 source registry **pulled**;在第二种模式下,images 也可以被 **pushed** 到 source registry。
|
||||
它有两种模式:**ReadOnly** 和 **ReadWrite**。在第一种模式下,images 只能从源 registry 中被 **pulled**;在第二种模式下,images 还可以被 **pushed** 到源 registry。
|
||||
|
||||
为了让 clients 能从 Azure 访问 registry,使用 connected registry 时会生成一个 **token**。
|
||||
当使用 connected registry 时,会生成一个 **token**,以便客户端从 Azure 访问该 registry。
|
||||
|
||||
### Runs & Tasks
|
||||
|
||||
Runs & Tasks 允许在 Azure 中执行你通常需要在本地或 CI/CD pipeline 中完成的 container 相关操作。例如,你可以在 registry 中 **build, push, and run images**。
|
||||
Runs & Tasks 允许在 Azure 中执行与 container 相关的操作,而这些操作通常需要在本地或 CI/CD pipeline 中完成。例如,你可以在 registry 中 **build、push 和运行 images**。
|
||||
|
||||
构建并运行 container 最简单的方法是使用常规 Run:
|
||||
构建和运行 container 最简单的方式是使用常规的 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
|
||||
```
|
||||
不过,这会触发一些从 attacker 角度看并不太有趣的 runs,因为它们没有附加任何 managed identity。
|
||||
然而,这会触发一些从攻击者角度来看并不太有趣的 runs,因为它们没有附加任何 managed identity。
|
||||
|
||||
不过,**tasks** 可以附加 **system 和 user managed identity**。这些 tasks 才是用于在 container 中 **escalate privileges** 的。关于 privileges escalation 章节,可以看到如何使用 tasks 来 escalate privileges。
|
||||
不过,**tasks** 可以附加 **system 和 user managed identity**。这些 tasks 才是用于在容器中**提升权限**的对象。在权限提升部分,可以了解如何利用 tasks 来提升权限。
|
||||
|
||||
### Cache
|
||||
|
||||
cache 功能允许从 **external repository** 下载 images,并将新版本存储到 registry 中。它要求通过从 Azure Vault 中选择 credentials 来配置一些 **credentials**。
|
||||
Cache 功能允许从**外部 repository 下载 images**,并将新版本存储在 registry 中。它要求通过从 Azure Vault 中选择凭据来配置一些**凭据**。
|
||||
|
||||
这从 attacker 的角度看非常有趣,因为如果 attacker 拥有足够的权限访问 credentials,就可以 **pivot to an external platform**,**download images from an external repository**,并且配置 cache 也可以用作 **persistence mechanism**。
|
||||
从攻击者角度来看,这非常有趣,因为如果攻击者拥有足够的权限访问这些凭据,就可以**转移到外部平台**;**从外部 repository 下载 images**并配置 cache 也可以被用作**持久化机制**。
|
||||
|
||||
## Enumeration
|
||||
|
||||
> [!WARNING]
|
||||
> 非常重要的一点是,即使 registry 名称包含一些大写字母,访问它时也应只在 url 中使用小写字母。
|
||||
> 非常重要的一点是,即使 registry 名称中包含大写字母,也只能在用于访问它的 URL 中使用小写字母。
|
||||
```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>
|
||||
```
|
||||
## 未经身份验证的访问
|
||||
## 未认证访问
|
||||
|
||||
{{#ref}}
|
||||
../az-unauthenticated-enum-and-initial-entry/az-container-registry-unauth.md
|
||||
{{#endref}}
|
||||
|
||||
## 权限提升 & Post Exploitation
|
||||
## Privilege Escalation & Post Exploitation
|
||||
|
||||
{{#ref}}
|
||||
../az-privilege-escalation/az-container-registry-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
## References
|
||||
{{#ref}}
|
||||
../az-post-exploitation/az-container-registry-post-exploitation.md
|
||||
{{#endref}}
|
||||
|
||||
## 参考资料
|
||||
|
||||
- [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)
|
||||
|
||||
Reference in New Issue
Block a user