0hardik1/kubesplaining

GitHub: 0hardik1/kubesplaining

一款 Kubernetes 安全评估 CLI 工具,通过图搜索构建从每个 Subject 到高价值目标的完整提权路径,并生成按风险优先级排序的多格式报告。

Stars: 76 | Forks: 7

# Kubesplaining [![最新版本](https://img.shields.io/github/v/release/0hardik1/kubesplaining?include_prereleases&sort=semver)](https://github.com/0hardik1/kubesplaining/releases) [![许可证](https://img.shields.io/github/license/0hardik1/kubesplaining)](LICENSE) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/820a44bb18055000.svg)](https://github.com/0hardik1/kubesplaining/actions/workflows/lint.yml) [![Go 版本](https://img.shields.io/github/go-mod/go-version/0hardik1/kubesplaining)](go.mod) [![Go 报告卡](https://goreportcard.com/badge/github.com/0hardik1/kubesplaining)](https://goreportcard.com/report/github.com/0hardik1/kubesplaining) 一个 Kubernetes 安全评估 CLI 工具,能够映射每个 RBAC subject 到 cluster-admin、host root 和 kube-system secrets 的提权路径,然后将这些链条生成为按风险优先级排序的 HTML / JSON / CSV / SARIF 报告。 * [实时示例报告](https://0hardik1.github.io/kubesplaining/) 灵感来源于 BeyondTrust Phantom Labs 的 [Kinnaird McQuade](https://www.linkedin.com/in/kmcquade3/) 及其为 AWS IAM 提供相同功能的 [Cloudsplaining](https://github.com/salesforce/cloudsplaining)。Kubesplaining 会读取运行中的集群或之前捕获的快照,根据技术库对其进行分析,并生成按优先级排序的发现结果列表:提供的是解释,而不仅仅是检测。 ## 为什么选择 kubesplaining 大多数 Kubernetes 扫描器只停留在“此资源配置不当”。Kubesplaining 回答了一个不同的问题:**攻击者实际上将如何穿透您的集群?** 根据您现有的 RBAC 绑定和 pod,它会从每个非系统 subject 开始遍历提权图,并告知您哪些 subject 可以到达 `cluster-admin`、host root 或 `kube-system` secrets,同时附带完整的跳板链。 它专注于攻击者实际利用的阵地: - **提权路径**:基于图的“subject A 可以变成 subject B 从而到达终点 X”的链条,通过 BFS 搜索指向四个终点(`cluster-admin`、`system:masters`、`node-escape`、`kube-system-secrets`)。 - **过度宽松的 RBAC**:通配符、模拟、bind/escalate、secret 读取、pod 创建、token 签发。 - **Pod 逃逸攻击面**:特权容器、host 命名空间、敏感的 hostPath 挂载、容器 socket 挂载。 - **网络隔离缺口**:缺少 NetworkPolicy 的命名空间、允许广泛互联网外流 的策略。 - **准入控制 绕过**:fail-open 的 webhook、objectSelector 绕过、敏感命名空间豁免。 - **Secrets 和 ServiceAccount 卫生**:传统 token secret、ConfigMap 中的凭据、默认 SA 挂载、DaemonSet token 爆炸半径。 每一项发现都指明了所使用的技术、展示了证据,并包含了修复建议。 **使用场景:** - **渗透测试 / 红队演练**:提权路径*即是*攻击计划。 - **新绑定添加前的安全审查**:查看它是否阻断了从不可信来源到终点的图路径。 - **CI 中的持续保障**:带有严重性预算的 `--ci-mode` 会在高危发现超过阈值时使流水线失败。 - **事件后重演**:捕获快照,离线分析,解释攻击者可能如何进行移动。 ## 快速开始 安装后(见下方 [安装](#installation)),将 Kubesplaining 指向您当前的 `kubectl` 上下文: ``` kubesplaining scan # writes ./kubesplaining-report/ open kubesplaining-report/report.html # macOS; xdg-open on Linux ``` 已经克隆了仓库?`make scan` 会构建二进制文件(Hermit 会自动下载固定的 Go 工具链)并一步到位地针对您当前的 `kubectl` 上下文运行它——无需单独安装。可以通过 `ARGS` 传递额外的标志,例如 `make scan ARGS="--severity-threshold high --only-modules privesc"`。 对于气隙环境 或审计工作流,请先捕获快照然后离线分析: ``` kubesplaining download --output-file snapshot.json kubesplaining scan --input-file snapshot.json ``` 对于无需集群访问权限的单次 manifest 检查: ``` kubesplaining scan-resource --input-file deployment.yaml ``` ## 安装 选择适合您的方式。这三种方式都会生成相同的 `kubesplaining` 二进制文件。 ### Go install ``` go install github.com/0hardik1/kubesplaining/cmd/kubesplaining@latest ``` ### 预构建二进制文件 从 [发布页面](https://github.com/0hardik1/kubesplaining/releases/latest) 获取与您的操作系统/架构匹配的压缩包,解压后将 `kubesplaining` 放入您的 `PATH` 中。每个版本附带: - `kubesplaining__Linux_x86_64.tar.gz` / `Linux_arm64.tar.gz` - `kubesplaining__Darwin_x86_64.tar.gz` / `Darwin_arm64.tar.gz` - `kubesplaining__Windows_x86_64.zip` - `kubesplaining__checksums.txt` (SHA-256) 校验 checksum 后,将二进制文件移至相应位置: ``` shasum -a 256 -c kubesplaining__checksums.txt sudo install kubesplaining /usr/local/bin/ ``` ### Homebrew 将在版本发布后作为快速跟进提供:`brew install 0hardik1/tap/kubesplaining` 将在 v1.0.0 之后不久上线。 ## 检查内容 目前跨 7 个模块有 41 个稳定的规则 ID,外加将它们串联起来的提权图。完整的逐条规则的严重性、检测逻辑和修复建议:[docs/findings.md](docs/findings.md)。 | 模块 | 规则数 | 关注点 | | --- | --- | --- | | **rbac** | 10 | 通配符 / 模拟 / bind-escalate / secret 读取 / pod 创建 / nodes-proxy / token 创建 | | **podsec** | 13 | 特权、host 命名空间、hostPath、容器 socket、runAsRoot、可变标签 | | **network** | 5 | 缺少 NetworkPolicy 的命名空间、广泛的互联网外流、未被选中的工作负载 | | **admission** | 3 | failurePolicy: Ignore、objectSelector 绕过、敏感命名空间豁免 | | **secrets** | 4 | 传统 SA token secret、类似凭据的 ConfigMap 键、CoreDNS 篡改 | | **serviceaccount** | 4 | 特权 SA、default-SA RBAC、DaemonSet token 爆炸半径 | | **privesc** | 4 个终点 | 指向 cluster-admin / system:masters / node-escape / kube-system-secrets 的图链条 | 每项发现都带有 `RiskCategory`(`privilege_escalation`、`data_exfiltration`、`lateral_movement`、`infrastructure_modification`、`defense_evasion`)标签,以便 HTML 报告可以按影响车道分组。 规则 ID 是一个**公共接口**:它们在各个版本中保持稳定,并在 `findings.json`、SARIF 输出以及 `scripts/kind-e2e.sh` 中的端到端断言中被引用。 ## 工作原理 四阶段流水线: ``` ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ Connection │ → │ Collection │ → │ Analysis │ → │ Report │ │ kubeconfig │ │ snapshot.json │ │ 7 modules ∥ │ │ html/json/ │ │ / in-cluster │ │ RBAC+workload │ │ findings[] │ │ csv/sarif │ └───────────────┘ └───────────────┘ └───────────────┘ └───────────────┘ ``` 最重要的边界:**收集器是唯一与 Kubernetes API 通信的部分**;分析器只消费 `Snapshot` 且从不进行网络调用。这正是 `download` → `scan --input-file` 能够用于离线分析的原因。只读访问就足够了:无需准入 webhook,无需代理,无需安装 CRD。 如需了解每个阶段的演练、提权图机制、数据模型和评分公式:[docs/architecture.md](docs/architecture.md)。 ## 样本发现 输出的实际样子。每条规则都会生成一个带有稳定 `RuleID`、严重性、证据和修复建议的 `Finding`;提权规则额外包含一个 `EscalationPath` 数组。
KUBE-PRIVESC-PATH-CLUSTER-ADMIN:Service Account 在 2 次跳板内达到 cluster-admin ``` { "id": "KUBE-PRIVESC-PATH-CLUSTER-ADMIN:foo:builder-bot", "rule_id": "KUBE-PRIVESC-PATH-CLUSTER-ADMIN", "severity": "CRITICAL", "score": 9.3, "category": "privilege_escalation", "subject": { "kind": "ServiceAccount", "namespace": "foo", "name": "builder-bot" }, "title": "ServiceAccount foo/builder-bot can reach cluster-admin equivalent in 2 hop(s)", "escalation_path": [ { "from_subject": "ServiceAccount/foo/builder-bot", "to_subject": "ServiceAccount/kube-system/replicaset-controller", "action": "pod_create", "permission": "create on pods", "gains": "run a pod that mounts the kube-system replicaset-controller token" }, { "from_subject": "ServiceAccount/kube-system/replicaset-controller", "to_subject": "ClusterRole/cluster-admin", "action": "wildcard_holder", "permission": "*/*/*", "gains": "this SA already holds cluster-admin equivalence" } ], "remediation": "Drop `create pods` from foo/builder-bot's role, OR move that workload off kube-system." } ``` HTML 报告将其渲染为一张包含每条边技术解释的逐跳卡片;SARIF 输出将链条保留在 `properties.escalationPath` 字段中,以便进行 IDE 集成。
KUBE-ESCAPE-001:带有 hostPath 挂载的特权容器 ``` { "id": "KUBE-ESCAPE-001:default:debug-shell", "rule_id": "KUBE-ESCAPE-001", "severity": "CRITICAL", "score": 9.5, "category": "privilege_escalation", "resource": { "kind": "Pod", "namespace": "default", "name": "debug-shell" }, "title": "Privileged container in default/debug-shell", "evidence": { "container": "debug", "securityContext": { "privileged": true }, "volumeMounts": [{ "name": "host-root", "mountPath": "/host", "hostPath": "/" }] }, "remediation": "Drop `privileged: true`; replace hostPath `/` with the specific files via ConfigMap / Secret / CSI." } ```
KUBE-RBAC-OVERBROAD-001:组直接绑定到 cluster-admin ``` { "id": "KUBE-RBAC-OVERBROAD-001::ops-team-admin", "rule_id": "KUBE-RBAC-OVERBROAD-001", "severity": "CRITICAL", "score": 9.0, "category": "privilege_escalation", "subject": { "kind": "Group", "name": "ops-team" }, "title": "Group ops-team is bound to cluster-admin", "evidence": { "clusterRoleBinding": "ops-team-admin", "roleRef": "cluster-admin" }, "remediation": "Replace cluster-admin with a least-privilege role scoped to what ops-team actually needs." } ```
完整的规则目录(每条规则的严重性、检测、修复):[docs/findings.md](docs/findings.md)。 ## 离线分析 收集器和分析器是解耦的:快照是一个普通的 JSON 文件。捕获一次,反复分析,适用于凭据不应保存在分析人员机器上的环境: ``` # 在带有 cluster credentials 的 jumphost 上: kubesplaining download --output-file snapshot.json # 将 snapshot.json 移动到你的笔记本电脑 / audit machine,然后: kubesplaining scan --input-file snapshot.json ``` 适用于: - **审计轨迹**:快照就是证据;重复运行会产生完全一致的发现。 - **气隙审查**:分析生产集群而无需将 kubeconfig 带离跳板机。 - **Manifest 扫描**:`kubesplaining scan-resource --input-file deployment.yaml` 针对单个 YAML 运行相同的分析器,无需集群。 ## CI 集成 SARIF 输出可与 [GitHub 代码扫描](https://docs.github.com/en/code-security/code-scanning) 集成,因此发现结果将显示为 PR 注释。在专用的 GitHub Action 发布之前(版本发布后的快速跟进),`docker run` 形式可直接运行: ``` # .github/workflows/kubesplaining.yml name: Kubesplaining on: [push, pull_request] jobs: scan: runs-on: ubuntu-latest permissions: security-events: write steps: - uses: actions/checkout@v6 - name: Scan manifests run: | docker run --rm \ -v "${{ github.workspace }}:/work" -w /work \ ghcr.io/0hardik1/kubesplaining:latest \ scan-resource --input-file manifests/ --output-format sarif \ --output-dir /work/kubesplaining-report - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: kubesplaining-report/results.sarif ``` 或者使用 `--ci-mode` 让超出预算的发现导致构建失败: ``` kubesplaining scan --ci-mode --ci-max-critical 0 --ci-max-high 0 ``` 当 critical / high(严重/高)级别的发现数量超过配置的阈值时,`--ci-mode` 会以非零状态退出;可结合 `--severity-threshold` 来限定计数范围。 ## 排除项 `scan`、`scan-resource` 和 `report` **默认自动应用 `standard` 排除项预设**,因此关于内置 Kubernetes 底层设施的发现会被预先抑制。这涵盖了 kube-system / kube-public / kube-node-lease 命名空间、kube-controller-manager service account(`clusterrole-aggregation-controller`、`generic-garbage-collector` 等)、`system:*` 用户/组/角色,以及 `kubeadm:*` 组和 bootstrap 角色。所有这些都不是操作员在不破坏集群的情况下可以更改的,因此将它们显示为风险只会掩盖那些真正可操作的内容。 使用 `--exclusions-preset` 选择不同的基线: | 预设 | 行为 | | --- | --- | | `standard`(默认) | 自动应用。过滤 kube-system / system:* / kubeadm:* 噪音。 | | `minimal` | 仅过滤 `kube-public`、`kube-node-lease` 和 `system:*`。 | | `none`(别名 `strict`) | 无内置过滤:所有发现浮出水面,包括控制平面噪音。 | 使用 `--exclusions-file path.yml` 在此基础上叠加自定义规则。用户文件与预设**合并**,因此您会保留默认设置并添加您自己的抑制项(特定的 service account、预期的工作负载、自定义 rule-ID 模式)。生成一个初始文件: ``` kubesplaining create-exclusions-file --preset standard --output-file exclusions.yml ``` 完整的 YAML 架构(Global / RBAC / PodSecurity / NetworkPolicy 部分,所有匹配器均支持 shell 风格的 glob)请参见 [docs/exclusions.md](docs/exclusions.md)。 要审查默认设置隐藏了什么,请使用 `--exclusions-preset=none` 重新运行并进行 diff 对比。 ## 备忘录 ### 命令 | 命令 | 用途 | | --- | --- | | `kubesplaining scan` | 分析(实时或 `--input-file`)并写入报告。 | | `kubesplaining download` | 从实时集群捕获 `snapshot.json`。只读。 | | `kubesplaining scan-resource` | 扫描单个资源 manifest 以进行快速检查。 | | `kubesplaining report` | 从现有的 findings JSON 重新渲染报告。 | | `kubesplaining create-exclusions-file` | 生成一个初始 exclusions YAML。 | | `kubesplaining version` | 打印构建信息。 | ### 常用标志 | 标志 | 默认值 | 用途 | | --- | --- | --- | | `--severity-threshold` | `low` | 隐藏低于此严重级别的发现(`critical` / `high` / `medium` / `low` / `info`)。 | | `--output-format` | `html,json` | 以逗号分隔的列表:`html`、`json`、`csv`、`sarif`。 | | `--output-dir` | `./kubesplaining-report` | 报告写入位置。 | | `--only-modules` / `--skip-modules` | — | 限定分析器范围(`rbac`、`podsec`、`network`、`admission`、`secrets`、`serviceaccount`、`privesc`)。 | | `--max-privesc-depth` | `5` | 提权图的 BFS 深度上限。 | | `--ci-mode` | off | 超过阈值时以非零状态退出。 | | `--ci-max-critical` / `--ci-max-high` | `0` / `0` | CI 模式下允许的各严重级别的最大数量。 | | `--exclusions-preset` | `standard` | `standard` / `minimal` / `none`。 | | `--exclusions-file` | — | 用户提供的 YAML,在预设之上合并。 | | `--input-file` | — | 使用快照 JSON 代替实时收集。 | | `--namespaces` / `--exclude-namespaces` | — | 按命名空间过滤实时收集。 | | `--parallelism` | `10` | 实时收集期间的最大并行 API 请求数。 | ### 输出格式 | 格式 | 使用场景 | | --- | --- | | HTML | 人工审查;自成一体,可离线工作,包含针对各项发现的教育性说明 | | JSON | 编程式消费,快照 diff | | CSV | 分类电子表格 | | SARIF | GitHub 代码扫描,IDE 集成 | ## 常见问题解答 **为什么 `system:masters` 在某些集群中被标记而在另一些中没有?** 提权分析器跳过 `system:*` 主体作为*可遍历的中间节点*(这样路径就不会通过控制平面进行洗钱),但如果您可以模拟或以其他方式提权至 `system:*`,它*确实会*将 `system:*` 报告为可达终点目标。如果分析器没有看到任何人具备这种能力,该规则将保持静默。 **提权路径有多准确?** 每一次跳板都根据快照的 RBAC 和 pod 状态进行了验证。分析器不会推测。误报来源于那些在*结构上*可能但在操作上被抑制的链条(例如,一个 SA 绑定到一个从未实际使用过的角色)。严重性会根据链条长度进行衰减(跳板数 ≥ 3 时下降一个等级);使用 `--max-privesc-depth` 来限制 BFS 的激进程度。 **我可以针对我的生产集群运行它吗?** 可以。只读访问就足够了。不会安装任何 webhook、CRD、agent 或 pod。被禁止的列表请求会被降级为警告而不是致命错误,因此被锁定的集群依然能产生有用的输出。 **为什么没有准入 webhook?** 超出了范围。其意图是*评估*,而不是*强制执行*。如果您想要强制执行,请根据发现结果生成 Kyverno / Gatekeeper 策略,并将其移交给您的策略引擎。 **为什么发现默认被排除?** `standard` 预设抑制了控制平面的噪音(kube-system、system:*、kubeadm:*),操作员在不破坏集群的情况下无法更改这些内容。使用 `--exclusions-preset=none` 重新运行可查看所有内容。 ## 接下来去哪 - **完整规则目录**(已实现 + 计划中):[docs/findings.md](docs/findings.md) - **架构深入探讨**(分阶段演练、评分、数据模型):[docs/architecture.md](docs/architecture.md) - **排除项 YAML 架构**(预设、部分、glob 语义):[docs/exclusions.md](docs/exclusions.md) - **路线图与状态**:[PLAN.md](PLAN.md) - **发布与更新日志**:[CHANGELOG.md](CHANGELOG.md) / [GitHub Releases](https://github.com/0hardik1/kubesplaining/releases) - **贡献**:[CONTRIBUTING.md](CONTRIBUTING.md) - **安全披露**:[SECURITY.md](SECURITY.md)(仅限 GitHub 私有漏洞报告) - **许可证**:[Apache-2.0](LICENSE) - **端到端验证**:`make e2e` 使用 `testdata/` 中故意带有风险的 manifest 配置一个本地 kind 集群,并断言预期的发现结果
标签:CLI, CSV导出, EVTX分析, Go, HTML报告, Kubesplaining, Pod逃逸, RBAC, Red Teaming, Ruby工具, SARIF, WiFi技术, 协议分析, 反取证, 图谱分析, 子域名突变, 安全扫描, 安全评估, 容器逃逸, 恶意样本开发, 日志审计, 时序注入, 权限提升, 特权升级分析, 请求拦截