arkanzasfeziii/BlackForge
GitHub: arkanzasfeziii/BlackForge
BlackForge 是一款 CI/CD 与供应链安全评估框架,用于模拟和检测 GitHub Actions、Jenkins、GitLab CI、ArgoCD 及制品仓库中的攻击向量与配置缺陷。
Stars: 0 | Forks: 0
# BlackForge — CI/CD 与供应链攻击框架
## 威胁模型
现代软件交付流水线在设计上是被信任的。CI/CD 系统在每次提交时都会执行任意代码,持有访问生产环境的凭证,且很少被纳入安全团队的监控攻击面。这种信任本身就是漏洞。
BlackForge 模拟了通过流水线——而非应用程序——进行渗透的攻击者:
| 阶段 | 故障点 | 对手操作 |
|---|---|---|
| **GitHub Actions** | Workflow 文件将 `github.event.head_commit.message` 直接插入到 `run:` 步骤中 | 通过 PR 标题或提交信息注入 shell 命令——无需合并 |
| **GitHub Actions** | 组织 secret 在各个仓库间的授权范围过广 | 枚举所有组织仓库,提取 secret 名称,生成泄露 PoC workflow |
| **Jenkins** | Script Console 可直接访问或在无身份验证下暴露 | 执行 Groovy payload:转储凭证、枚举节点、提取环境变量 |
| **Jenkins** | 内置凭证存储库在无角色作用域限制下通过 Credentials REST API 访问 | 获取 AWS、GCP、SSH 密钥和 API token 的明文凭证 |
| **GitLab CI** | CI/CD 变量被标记为 "protected" 但未标记为 "masked" | 从流水线日志中提取变量;通过 API 为任何可访问的项目转储未掩码的 secret |
| **GitLab** | Runner 注册 token 在项目设置中暴露 | 注册恶意 runner——拦截未来的流水线任务 |
| **ArgoCD** | 默认管理员凭证在部署后未轮换 | 访问所有受管集群、应用程序和已连接的仓库 |
| **Artifact Registries** | Nexus/Artifactory/Harbor 使用默认凭证部署并启用了匿名访问 | 拉取内部包,识别用于 dependency confusion 的内部 namespace 命名约定 |
| **Dependency Confusion** | 内部包与公共 registry 中的包同名且未启用 scope 保护 | 识别内部包名——为 confusion attack 的 payload 投递提供上游支持 |
**范围:** 授权的红队评估,用于模拟供应链攻陷向量和 CI/CD 流水线攻击路径。
## 开发背景
供应链是新的边界。攻击者不需要攻陷应用程序——他们攻陷构建和部署该应用程序的流水线。
在 SolarWinds 事件之后,业界承认构建系统是高价值目标。大多数组织的应对方式是向流水线中添加更多的 secret,却没有考虑这些流水线本身是否经过了足够的安全加固以承载这些凭证。
BlackForge 致力于回答以下问题:
- 你的 Jenkins Script Console 是否需要身份验证?
- 你的 GitHub Actions workflow 是否将不受信任的输入插入到 shell 命令中?
- 拥有只读 token 的攻击者能否从 GitLab 中提取未掩码的 CI/CD 变量?
- 你的 artifact registry 是否允许对内部包进行匿名拉取?
- 当 ArgoCD 仍然使用 `admin:password` 时会发生什么?
该框架系统地测试这些问题,覆盖了五个交付流水线攻陷影响最大的平台。
## 功能特性
### GitHub 攻击模块
- **Token 验证:** 验证发现的 GitHub PAT 的 scope 和权限
- **组织枚举:** 列出组织下的所有仓库、成员和团队结构
- **Secret 枚举:** 列出在组织和仓库级别定义的 secret 名称(值会被 GitHub 掩码——名称则暴露了实际存在的内容)
- **Workflow 注入检测:** 下载所有 workflow YAML 文件;扫描危险的插值模式—— `github.event.head_commit.message`、`github.head_ref` 以及 `run:` 块中的 PR 标题
- **Actions 运行日志扫描:** 解析历史 workflow 日志,查找意外打印的、匹配 `SECRET_PATTERNS` 的 secret
- **PoC workflow 生成器:** 生成可直接注入的 workflow,将 `secrets.*` 泄露到外部 endpoint——无需真实提交即可验证可利用性
### Jenkins 攻击模块
- **匿名访问检测:** 检查 `/api/json` 是否存在未授权访问
- **通过 Script Console 实现 Groovy RCE:** 在 Jenkins controller 上执行任意 Groovy—— `whoami`、`hostname`、完整的环境变量转储
- **凭证提取:** 使用 Groovy payload 遍历凭证存储库,为每个存储的凭证提取 ID、类型、用户名、密码、secret、API token 和私钥源
- **Credentials REST API 回退机制:** 尝试在带有和不带有身份验证的情况下,通过 `/credentials/store/system/domain/_/api/json` 列出凭证
- **任务和节点枚举:** 列出所有构建任务和已连接的构建代理
### GitLab 攻击模块
- **Token 验证和管理员检测:** 验证 token scope;检测管理员级别的访问权限
- **项目枚举:** 列出所有可访问的项目及其可见性和权限级别
- **CI/CD 变量提取:** 转储所有项目级别的 CI/CD 变量——标记出现在日志中的未掩码变量
- **Runner token 盗取:** 从项目设置中提取 runner 注册 token——实现恶意 runner 注册
- **流水线日志扫描:** 搜索匹配 `SECRET_PATTERNS` 的历史流水线任务日志中的 secret
### ArgoCD 攻击模块
- **版本指纹识别:** 通过 `/api/version` 检测 ArgoCD 部署
- **默认凭证暴力破解:** 测试 `admin:admin`、`admin:password` 及常见默认凭证
- **认证后枚举:** 在成功进行身份验证后,列出受管应用程序、已连接的集群和已注册的仓库
### Artifact Registry 模块
- **平台检测:** 通过响应头和 UI 指纹识别 Nexus Repository Manager、JFrog Artifactory 或 Harbor
- **匿名访问检查:** 测试在无凭证的情况下是否可以进行包拉取/浏览
- **默认凭证测试:** 批量测试已知默认凭证(`admin:admin123`、`admin:password`、`harbor:Harbor12345`)
- **Dependency confusion 检测:** 枚举内部包名和 namespace——呈现可用于 confusion attack 目标的候选项
### Secret 模式检测
BlackForge 会扫描 workflow 日志、流水线输出和环境变量转储,以查找:
```
AWS_ACCESS_KEY_ID · Google API Key · GitHub PAT (ghp_) · GitLab PAT (glpat-)
OpenAI Key (sk-) · PASSWORD · API_KEY · SECRET · PRIVATE_KEY
CONNECTION_STRING · ACCESS_TOKEN · DATABASE_URL
```
## 架构
```
Target (URL · token · platform)
│
▼
Platform Detection
┌──────────────────────────────┐
│ GitHub · Jenkins · GitLab │
│ ArgoCD · Artifact Registry │
└──────────────────────────────┘
│
┌──────┼──────┐──────┐──────┐
▼ ▼ ▼ ▼ ▼
GitHub Jenkins GitLab ArgoCD Artifact
Module Module Module Module Module
│ │ │ │ │
└──────┴──────┴──────┴──────┘
│
▼
SECRET_PATTERNS Scanner
│
▼
JSON Report
(platform · action · finding · severity)
```
## 攻击流程
1. **平台枚举** —— 通过 URL 模式、响应头和指纹识别目标组织部署了哪些 CI/CD 平台
2. **身份验证测试** —— 验证提供的 token/凭证;检测匿名访问路径;暴力破解已知默认凭证(Jenkins、ArgoCD、Artifactory)
3. **Workflow 分析 (GitHub)** —— 从组织仓库中拉取所有 workflow YAML 文件;解析 `run:` 块中是否存在对 `github.event.*` 值的危险插值;标记注入向量
4. **凭证提取 (Jenkins)** —— 如果 Script Console 可访问,执行 Groovy payload 以转储完整的凭证存储库——AWS 密钥、SSH 私钥、API token、服务账号密码
5. **变量提取 (GitLab)** —— 转储所有可访问项目的 CI/CD 变量;标记任何包含凭证模式的未掩码变量
6. **PoC 生成** —— 为每个已确认的注入向量生成概念验证 workflow 或 Groovy payload,以展示实际影响(secret 泄露、命令执行)
7. **Dependency confusion 攻击面** —— 从 artifact registry 枚举内部包名称;将缺乏 scope 保护的 namespace 作为 confusion attack 的候选项报告
8. **报告** —— 针对每项发现输出结构化的 JSON,包含平台、采取的操作、发现详情和严重性分类
## 用法
```
# 安装依赖项
pip install -r requirements.txt
# GitHub: 枚举 org、扫描 workflows、检查 injection vectors
python blackforge.py --platform github --token ghp_xxxx --org target-org
# GitHub: 扫描 Actions 运行日志以查找暴露的 secrets
python blackforge.py --platform github --token ghp_xxxx --org target-org --modules logs
# Jenkins: 测试匿名访问 + 尝试 Groovy RCE
python blackforge.py --platform jenkins --url https://jenkins.internal.corp
# Jenkins: 通过 Groovy 进行已认证的 credential dump
python blackforge.py --platform jenkins --url https://jenkins.corp --username admin --password found-pass
# GitLab: 转储所有项目中未掩码的 CI/CD 变量
python blackforge.py --platform gitlab --token glpat-xxxx --url https://gitlab.corp.com
# ArgoCD: 默认 credential brute-force + 认证后枚举
python blackforge.py --platform argocd --url https://argocd.k8s.corp
# Artifact registry: 检测平台、测试匿名访问、寻找 confusion candidates
python blackforge.py --platform artifact --url https://nexus.corp.internal
# 全面 engagement — 所有平台
python blackforge.py --modules all --output supply-chain-findings.json --yes
```
## 输出
```
14:02:11 [INFO] [GitHub] Token validated — scope: repo, admin:org, read:packages
14:02:12 [INFO] [GitHub] Organization: target-corp | 47 repos | 83 members
14:02:13 [CRIT] [GitHub/Workflows] Injection vector in .github/workflows/pr-check.yml:
run: echo "Building ${{ github.event.pull_request.title }}"
14:02:13 [CRIT] [GitHub/Workflows] PoC generated → inject.yml (exfiltrates secrets.*)
14:02:14 [CRIT] [GitHub/Logs] Secret leaked in run #482: AWS_ACCESS_KEY_ID=AKIA...
14:02:15 [CRIT] [Jenkins] Anonymous access confirmed — /api/json readable
14:02:16 [CRIT] [Jenkins/Groovy] RCE via Script Console — user: jenkins | host: build-01
14:02:17 [CRIT] [Jenkins/Groovy] Credential dump — 12 entries extracted:
aws-prod-key [AWS] AKIAIOSFODNN7EXAMPLE
deploy-ssh [SSH] -----BEGIN RSA PRIVATE KEY-----
gitlab-token [Secret] glpat-xxxxxxxxxxxx
14:02:18 [WARN] [GitLab] 6 unmasked CI/CD variables across 3 projects
14:02:18 [CRIT] [GitLab] Variable DB_PASSWORD (project: api-service) — unmasked, in logs
14:02:19 [CRIT] [GitLab] Runner token found: GR1348941xxxxxxxx — rogue runner feasible
14:02:20 [CRIT] [ArgoCD] Default credential accepted: admin:admin
14:02:21 [INFO] [ArgoCD] 8 managed applications | 3 clusters | 11 repositories
[✓] Supply chain audit complete — 9 critical findings | report: supply-chain-findings.json
```
## MITRE ATT&CK 覆盖范围
| 技术 | ID | 模块 |
|---|---|---|
| 供应链攻陷:CI/CD | T1195.002 | GitHubModule, JenkinsModule |
| 不安全的凭证:CI/CD 变量 | T1552.004 | GitLabModule, GitHubModule |
| 命令和脚本解释器:Groovy | T1059 | JenkinsModule |
| 有效账户:云账户 | T1078.004 | ArgoCDModule, ArtifactModule |
| 远程服务利用 | T1210 | JenkinsModule (Script Console RCE) |
| 窃取应用程序访问 Token | T1528 | GitHubModule, GitLabModule |
| 账户发现 | T1087 | GitHubModule (组织成员枚举) |
**战术:** TA0001 初始访问 · TA0006 凭证访问 · TA0003 持久化(恶意 runner) · TA0002 执行(Groovy RCE)
## 涉及的 CWE 覆盖范围
| CWE | 描述 | 涉及位置 |
|---|---|---|
| CWE-78 | 操作系统命令注入 | GitHub Actions workflow 注入 |
| CWE-94 | 代码注入 | Jenkins Groovy Script Console |
| CWE-312 | 敏感信息的明文存储 | GitLab 未掩码的 CI/CD 变量 |
| CWE-522 | 受保护强度不足的凭证 | Jenkins 凭证存储库、流水线日志 |
| CWE-306 | 关键功能缺失身份验证 | Jenkins 匿名 Script Console 访问 |
| CWE-1103 | 使用依赖于平台的第三方组件 | Dependency confusion 候选项 |
## 法律声明
BlackForge 专为已获得资产所有者明确书面授权的授权渗透测试和安全评估活动而设计。在没有明确授权的情况下,测试你不被允许评估的组织的 CI/CD 系统和供应链组件是违法行为。作者对任何滥用行为不承担责任。
标签:DevSecOps, Homebrew安装, StruQ, 上游代理, 文档安全, 逆向工具