BlackHatUSA2026:GitHub入侵检测"

admin 2026-10-21 05:11:14 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

Black Hat USA 2026:GitHub入侵检测

原创

Max Luo
Max Luo

白帽子罗棋琛

2026年8月23日 08:19
广东

在小说阅读器读本章

去阅读

GitHub 正在告诉你仓库被入侵:用事件流构建代码托管 EDR

Black Hat USA 2026 议题笔记:GitHub Can Tell You're Being Hacked. You're Just Not Listening: Building EDR for GitHub from Its Own Event Stream

终端 EDR 的基本逻辑,是持续记录进程、文件、网络和身份行为,再从关联事件中识别攻击链。代码仓库同样有进程入口、身份切换、持久化、凭据使用和证据销毁,只是这些动作换成了 Commit、Tag、Workflow、OIDC、Release 和 Webhook。

不少团队已经把 GitHub Audit Log 接入 SIEM,却仍然很难发现供应链攻击。原因通常不是“没有日志”,而是只盯着单条高危事件。攻击者使用的动作往往都是平台允许的:推送 Commit、移动 Tag、修改 Workflow、触发发布、删除运行记录。风险来自对象之间不正常的关系。

公开课件把这套检测思路称为 GitHub EDR:监听平台活动,保存可比较的历史状态,用行为规则检测,再把相关信号拼成调查时间线。

图 1:用 GitHub 自身事件流构建 EDR 的议题课件封面

下面的表结构、查询和接收器代码,是根据课件架构整理的最小实现,不是项目仓库源码。

1、先把 GitHub 当作生产运行环境

对现代软件供应链来说,GitHub 不只是代码存储。它同时承担:

  • 身份和授权:用户、GitHub App、Deploy Key、GITHUB_TOKEN;
  • 执行环境:GitHub Actions Runner;
  • 云身份交换:OIDC 联邦和 Trusted Publishing;
  • 制品发布:Release、Package、Action Tag;
  • 审批与变更:Pull Request、Branch Protection、Environment;
  • 取证记录:Workflow Run、Commit Graph、Webhook 和 Audit Log。

这意味着仓库安全不能只检查默认分支上的代码 diff。攻击者可以不改业务代码,通过移动 Release Tag、污染 Actions 缓存、覆盖 Workflow、伪造作者元数据或者让 OIDC 工作流在错误上下文中运行,完成同样的供应链投毒。

图 2:课件归纳的六类 GitHub 攻击技术

课件把常见手法分为六组:制品投毒、OIDC 滥用、Workflow 注入与触发器滥用、身份和 Commit 元数据伪造、证据销毁,以及通过 Fork 或游离对象注入恶意代码。

检测设计应围绕这些 TTP,而不是围绕某一次事件的 IOC。仓库名、攻击账号和恶意 Hash 会变,Tag 批量移动、作者与实际推送者不一致、发布工作流突然获得 id-token: write 等行为模式更稳定。

2、Git 元数据不是认证身份

Git Commit 中的 author.name、author.email、时间戳、Committer、Message、Tree 和 Parent 都可以由提交者设置。GitHub UI 可能根据邮箱把 Author 显示成一个真实账号,甚至带头像和可点击链接,但这不证明该账号完成了推送。

真正经过 GitHub 身份认证的,是事件中的 Pusher 或 Sender。

图 3:应比较可伪造的 Commit Author 与经过平台认证的 Pusher

数据入库时必须同时保留两类身份:

sql

CREATE TABLE github_commit_event (     delivery_id         TEXT PRIMARY KEY,     repo_full_name      TEXT NOT NULL,     commit_sha          TEXT NOT NULL,     author_name         TEXT,     author_email        TEXT,     author_login        TEXT,     committer_login     TEXT,     pusher_login        TEXT NOT NULL,     sender_login        TEXT NOT NULL,     ref                 TEXT NOT NULL,     received_at         TIMESTAMPTZ NOT NULL,     raw_payload_sha256  TEXT NOT NULL );  CREATE INDEX ON github_commit_event (repo_full_name, received_at); CREATE INDEX ON github_commit_event (author_email, received_at);

最基础的身份不一致检测可以直接写成 SQL:

sql

SELECT     repo_full_name,     commit_sha,     author_login,     pusher_login,     received_at FROM github_commit_event WHERE author_login ISNOT NULLANDlower(author_login) <>lower(pusher_login)   AND received_at >= now() -interval'24 hours';

这条规则本身只能作为低置信度信号。机器人代提交、Web UI 合并、自动同步和 Release Bot 都可能造成 Author 与 Pusher 不同。真正可疑的是它与其他条件同时出现:未签名 Commit、直接推送默认分支、修改 .github/workflows/、Pusher 首次出现在该仓库,或者相同伪造邮箱短时间横跨多个无关组织。

跨组织关联还需要调用 Commit Search API 或自建索引。课件给出的思路是:对每个 author != pusher 的事件,统计同一 Author Email 出现在多少个不相关 Owner 中。批量攻击工具复用伪造身份时,这个特征比单仓库告警更有价值。

3、Webhook 不是完整历史,Tag 投毒必须做状态差分

供应链攻击里一个常见动作,是把多个版本 Tag 同时移动到被污染的 Commit。依赖方如果写的是 uses: org/action@v1,下一次运行就会解析到新对象。

GitHub Activity 页面并不完整展示 Tag Push。课件引用的 Webhook 行为还指出:一次推送超过三个 Tag 时,不会为这些 Tag 创建事件。这意味着最需要检测的批量 Tag 移动,恰好可能绕过只依赖 Webhook 的采集器。

图 4:可靠检测需要通过 Tags API 保存并比较 Tag 指向

正确做法是周期性获取 git/refs/tags,建立不可变快照:

sql

CREATE TABLE github_tag_snapshot (     repo_full_name  TEXT NOT NULL,     tag_name        TEXT NOT NULL,     target_sha      TEXT NOT NULL,     observed_at     TIMESTAMPTZ NOT NULL,     PRIMARY KEY (repo_full_name, tag_name, observed_at) );

下面的查询检测一个采集周期内被移动的 Tag:

sql

WITH ordered AS (     SELECT         repo_full_name,         tag_name,         target_sha,         observed_at,         lag(target_sha) OVER (             PARTITIONBY repo_full_name, tag_name             ORDERBY observed_at         ) AS previous_sha     FROM github_tag_snapshot ) SELECT repo_full_name, tag_name, previous_sha, target_sha, observed_at FROM ordered WHERE previous_sha ISNOT NULLAND previous_sha <> target_sha;

单个 Tag 移动可能是正常维护。应继续计算四个特征:同一时间窗内移动的 Tag 数量、是否集中指向同一 Commit、目标 Commit 是否可从受保护分支到达、移动后是否迅速回滚。最后一种“flip-flop”常用于投毒后恢复现场。

4、OIDC 让 Workflow 本身成为身份

过去攻击发布链路,常见目标是仓库 Secret 中的 NPM_TOKEN。使用 OIDC Trusted Publishing 后,长期 Secret 减少了,但攻击目标发生了变化:不再需要窃取 Token,只要让一个拥有 id-token: write 的 Workflow 在攻击者可控的上下文中运行。

图 5:需要检测新增或被修改的 OIDC 授权工作流

因此,检测对象要从 Secret Access 扩展到 Workflow 身份边界:

yaml

name:publishon:push:tags: [\"v*\"] permissions:contents:readid-token:writejobs:release:environment:productionruns-on:ubuntu-latest

上面的配置并非天然不安全,但任何涉及以下变化的 Commit 都应提高风险分:

  • 新增 id-token: write;
  • 触发器从受保护分支扩大到任意 Tag、Fork PR 或手工输入;
  • 删除 environment 审批;
  • 将 pull_request 改成 pull_request_target,同时 Checkout 不可信 PR 内容;
  • 发布 Job 使用可变第三方 Action Tag;
  • Workflow 由直接 Push 修改,而不是经过受保护 PR。

可以在入库的 Workflow 版本表上做差分:

sql

SELECT     current.repo_full_name,     current.path,     current.commit_sha,     current.pusher_login FROM workflow_version currentJOIN workflow_version previous   ON previous.repo_full_name = current.repo_full_name  AND previous.path = current.path  AND previous.version = current.version -1WHERE current.has_oidc_write =trueAND previous.has_oidc_write =false;

云侧也要把 OIDC Subject、Repository、Ref、Workflow Path 和 Environment 写入访问日志。只在 GitHub 侧看到 Workflow 修改,却无法关联它最终换取了哪个云角色,调查链仍然是不完整的。

5、采集层必须同时有实时流、快照和对象检查

课件给出的 GitHub EDR 架构分成四步:Collect、Enrich、Detect、Act。Webhook Receiver、Snapshot Collector 和 CLI 负责采集,PostgreSQL 保存事件与上下文,SQL 查询运行行为规则,前端和 CLI 输出时间线。

图 6:采集、状态存储、检测与调查分层

三个数据源各自有明显缺口:

图 7:Webhook、GitHub API 和 Git 对象检查需要互相补位

Webhook 实时、字段丰富,但可以被禁用,接收失败后的事件也可能永久丢失。接收器首先要验证签名并对 Delivery ID 去重:

python

import hashlib import hmac   defverify_webhook(secret: bytes, body: bytes, signature: str) -> bool:     ifnot signature.startswith(\"sha256=\"):         returnFalse     expected = hmac.new(secret, body, hashlib.sha256).hexdigest()     supplied = signature.removeprefix(\"sha256=\")     return hmac.compare_digest(expected, supplied)

GitHub API 适合周期性快照和基线比较,不容易被攻击者关闭成“采集通道”,但 API 对象可能已经被删除,字段比 Webhook 少,还受 Rate Limit 约束。

Git Inspect 直接读取 Commit、Tree、Tag 和可达性关系,适合判断 Tag Provenance、游离 Commit 和不可能的 Parent 时间线。代价是需要 Clone 或对象抓取,不实时,成本也高。

因此,采集策略可以按层次安排:Webhook 负责低延迟信号;API 快照负责补洞和状态差分;只有命中候选规则的仓库再执行 Git Inspect。这样既保留证据,也避免对所有仓库持续全量 Clone。

Webhook 原始载荷不要只解析后丢弃。至少保存 Body Hash、Delivery ID、Event Type、接收时间和对象存储引用,以便在解析器升级后重新回放。

6、数据模型要能回答“之前是什么”

传统 SIEM 常把 GitHub 事件拍平成一行 JSON。这样可以搜索“谁删除了 Workflow Run”,却无法稳定回答:Tag 以前指向哪里、这个 Pusher 是否第一次修改发布 Workflow、当前 Release Asset 是否与昨天相同。

GitHub EDR 的核心不是告警规则数量,而是保存活动记忆。建议至少维护这些状态表:

text

repository_baseline      默认分支、保护规则、Webhook、成员和 App tag_history              Tag -> Commit 的时间序列 commit_identity          Author、Committer、Pusher、签名和可达性 workflow_version         YAML 摘要、触发器、权限、Action 依赖 workflow_run             触发 Ref、Actor、OIDC、Artifact、删除状态 release_history          Tag、Asset 摘要、签名、创建者和修改时间 finding                  规则、证据引用、风险分和处置状态

仓库快照还应带采集批次号。只有同一批次完整结束后才参与差分,避免 API 分页失败造成“对象被删除”的假阳性。

7、复合规则比单条高危规则更实用

课件展示的一个例子是:

  • 多个 Tag 同时指向同一 Commit,单独看是低危;
  • Tag 指向不在任何分支上的 Commit,单独看是中危;
  • 两者在同一仓库和时间窗内同时发生,升级为高危“批量 Tag 投毒到不可达 Commit”。

图 8:低、中置信度信号组合成高置信度攻击行为

SQL 可以直接表达这种相关性:

sql

SELECT     burst.repo_full_name,     burst.target_sha,     burst.moved_tag_count,     reach.is_reachable_from_default FROM tag_move_burst burst JOIN commit_reachability reach   ON reach.repo_full_name = burst.repo_full_name  AND reach.commit_sha = burst.target_sha WHERE burst.moved_tag_count >=4AND reach.is_reachable_from_default =falseAND burst.window_start >= now() -interval'15 minutes';

阈值不能从示例直接复制。大型 Monorepo、自动 Release 工具和版本回填任务可能正常移动多个 Tag。更稳妥的基线是每仓库统计过去 30 天的 Tag 变更分布,再对首次出现、超过历史高分位且同时具备不可达 Commit 的事件升级。

同样的复合思路还适用于:

  • Workflow 新增 OIDC 权限 + 直接 Push 默认分支 + 随后触发发布;
  • Author 与 Pusher 不同 + 相同伪造邮箱跨组织出现 + Commit 未签名;
  • 发布 Workflow 运行 + 日志随后删除 + Release Asset Hash 改变;
  • pull_request_target 读取 Fork 代码 + 使用可写 Token + 命中共享 Cache Key。

8、检测规则必须经过事件回放和噪声实验

课件没有只展示规则,还给出了一套验证过程:把已知事件重建成仿真场景,再用 GH Archive、GitHub API 和 Git Inspect 评估字段可用性、正常环境出现频率和已知事件召回率。

图 9:候选规则先经过事件仿真、数据补全和正常流量测量

每条规则至少需要四组固定样本:

yaml

rule_id:github.mass_tag_to_unreachable_commitpositive_fixtures:-mass_tag_force_move_to_dangling_commit-temporary_tag_swap_then_restorenegative_fixtures:-release_tool_creates_new_version_tags-repository_migration_rewrites_historyrequired_enrichment:-tag_snapshot-commit_reachabilitymetrics:-incident_recall-findings_per_1000_repositories-enrichment_api_cost

如果公共事件流缺少规则字段,应先通过 API 或 Git 对象补全,再测噪声;不要用缺字段的样本得出“零误报”。候选规则的结果不止保留“启用/禁用”,还可以选择降级、加 Allowlist、只做 Correlator,或者仅在高价值仓库启用。

9、Hardening 仍然优先于 Detection

检测不能替代平台加固。课件列出了 GitHub 在 2026 年前后增加或强化的多项机制,包括不可变 Release、Workflow 执行保护、actions/checkout 对特权 Workflow 获取 Fork PR 代码的限制,以及非协作者运行使用只读 Cache Token 等。

无论具体功能状态如何变化,企业侧都应先完成这些基础控制:

  1. Release 使用不可变资产和签名证明;
  2. 默认分支和 .github/workflows/ 目录要求 Code Owner 审批;
  3. OIDC Trust Policy 绑定 Org、Repo、Ref、Workflow 和 Environment;
  4. 第三方 Action 固定到完整 Commit SHA,而不是可移动 Tag;
  5. GitHub App 使用最小权限并定期复核安装范围;
  6. Webhook 配置、Branch Protection 和 Environment 进入配置漂移监控;
  7. 关键仓库保留外部事件副本,避免平台内证据被删除后无从恢复。

Detection 的作用,是发现控制被绕过、身份被合法滥用以及历史状态发生异常变化。不能把没有告警当成加固已经完成。

10、落地时先回答五个问题

准备建设 GitHub EDR 时,先确认:

  1. 是否同时采集 Webhook、API 快照和必要的 Git 对象,而不是只接 Audit Log;
  2. 是否保留历史状态,可以比较 Tag、Workflow、Release 和权限的前后变化;
  3. 是否区分 Git 元数据身份与 GitHub 认证身份;
  4. 是否能把 GitHub Workflow 关联到最终换取的云或制品仓库身份;
  5. 是否用仿真与正常数据共同验证规则,而不是看到 SQL 能返回结果就上线。

课件中的实现使用 PostgreSQL 保存统一视图,并通过 22 条规则和 12 条 Beta 规则覆盖多类供应链 TTP。这个数字本身不重要。更值得复用的是数据思路:实时事件负责告诉你“刚才发生了什么”,快照负责告诉你“对象变成了什么”,Git 图负责告诉你“这个对象从哪里来”。三者合起来,才具备接近 EDR 的调查能力。


资料来源

  • Itay Weinberger、Yair Mizrachi,Black Hat USA 2026:《GitHub Can Tell You're Being Hacked. You're Just Not Listening: Building EDR for GitHub from Its Own Event Stream》
  • Black Hat 官方 Session 页面

原始会议材料(仓库内)

  • 演讲课件 PDF

开源资料与原始议题 PDF

本文对应的 Markdown 原稿、Black Hat 原始议题 PDF 与配图已整理到 GitHub,可按文章编号查找和下载。

https://github.com/cybermaxluo/black-hat-usa-2026-talks

也可以点击文末“阅读原文”进入仓库。欢迎 Star、提交 Issue 或参与勘误。


BlackHatUSA2026:GitHub入侵检测" 网络安全文章

BlackHatUSA2026:GitHub入侵检测"

该文档基于BlackHatUSA2026议题,提出利用GitHub自身事件流构建代码托管EDR以检测供应链攻击。核心观点是攻击者常利用平台允许的动作如移动Tag、修改Workflow进行投毒,传统SIEM仅关注单条事件不够。关键发现包括身份不一致、Tag状态差分和OIDC权限变化是稳定检测模式。可操作建议是建立状态快照、进行身份差分并监控Workflow权限变更。
一个可以代替Trello的开源看板工具Kan,从零开始保姆级部署教程" 网络安全文章

一个可以代替Trello的开源看板工具Kan,从零开始保姆级部署教程"

本文详细介绍了开源看板工具Kan的部署教程,包括DockerCompose一键部署、环境变量配置、本地开发环境搭建、MCPServer集成AI功能以及日常运维与升级。Kan作为Trello的自托管替代品,支持看板协作、标签筛选和Trello数据导入。部署过程简单,建议配置认证、邮件和文件存储以发挥完整功能。MCPServer允许AI通过自然语言操作看板,提升效率。
黑客真人秀?IBM设局成功诱捕国家级网络间谍的内幕" 网络安全文章

黑客真人秀?IBM设局成功诱捕国家级网络间谍的内幕"

IBMX-Force通过搭建虚假电网公司和政府机构环境,成功诱捕国家级黑客组织ITG27,实时观测其攻击链:始于冒充尼泊尔外交部的鱼叉钓鱼邮件,经DLL侧加载部署ClaimLoader加载器,最终释放ToneShellv10后门。关键发现包括此前未知的HavenCode后门(无硬编码C2,支持VNC远程访问)以及操作员工作日08-18CST活动规律和手动操作特征。建议加强DLL侧加载检测、保留日志至少90天并部署欺骗技术。
BEAR-C2源码审计:仅监听器无implant的验证性C2框架" 网络安全文章

BEAR-C2源码审计:仅监听器无implant的验证性C2框架"

BEAR-C2是一个开源C2框架源码审计项目,核心发现是其仅实现了服务端(监听器、会话管理、GUI),但完全缺乏植入体(implant),无法直接用于实战。加密实现存在严重硬伤,如RC4密钥流复用和XOR单字节密钥,导致信道可被破解。项目更适合作为蓝队流量模拟器或教学演示工具,用于测试加密C2流量的检测规则。蓝队可在隔离环境利用其生成流量,并针对其加密缺陷和协议特征(如DoH端点、QUIC证书异常)构建检测规则。
评论:0   参与:  0