代码没丢,密钥先没了
📋 总体概括
GitHub Actions被注入恶意workflow窃取SSH密钥与云凭据,npm上MALFEX行动用8个恶意包长期收割开发者终端。两起事件指向同一个判断:攻击者已经越过代码本身,盯上了流水线和开发机上的身份与凭据。本文拆解手法、数据与防御清单。
📄 正文
两起看起来不相干的攻击事件,指向了同一个方向。
第一起:攻击者向 GitHub 仓库注入伪装成安全检查的恶意 GitHub Actions workflow,瞄准了 2,577 个密钥。第二起:npm 上一个代号 MALFEX 的持续性行动,通过 8 个恶意包向 Windows 开发机投放信息窃取木马,背后疑似只有一个运营者,从 2023 年 8 月活动至今。
一个打流水线,一个打开发机,落点却相同——不是你的代码,而是你代码旁边躺着的那些密钥、令牌和登录态。这篇文章把两起事件拆开看,再合起来看,你会发现软件供应链的攻击面,已经从「仓库」推进到了「仓库周围的一切」。
🎣 2577 个密钥被瞄准,26 个被偷走
最危险的攻击,往往长得像安全检查。
据 GBHackers 披露的 researchers 分析,这批恶意 workflow 被设计成安全检查的样子混入 GitHub Actions,实际做的事是读取 runner 环境中的敏感信息:SSH 私钥、云厂商凭据、各类 access token。攻击者一口气瞄准了 2,577 个 secrets——从云控制台到代码签名密钥,几乎覆盖了开发者日常持有的全部身份凭证。
但「瞄准」不等于「偷走」。研究人员最终确认成功外传的 secrets 是 26 个,来自 13 个仓库。换句话说,从投毒到真正得手,转化率只有 1% 左右。
这个数字值得认真读。它说明两件事:其一,恶意注入和有效载荷执行之间隔着一整条链路——workflow 要被触发、runner 要真的持有目标密钥、环境隔离和 secret masking 要恰好失守,任何一环卡住都会让攻击落空;其二,即便只有 1%,26 个密钥里只要有一把能打开云控制台或者生产环境,对一个团队来说就是全损。
产业逻辑很直白:CI/CD runner 已经成了密钥的集中营。环境变量里塞着云密钥、registry 令牌、部署凭据,而 runner 又天然需要执行「外部提交的代码」。这两件事叠在一起,流水线就成了新的终端。圈内有句流传已久的话:开发者是新的边界——但这条边界上,跑着的还是十年前设计权限模型的那些假设。
📦 藏在 ASCII 艺术里的 RAT
如果说 workflow 注入是「点穴」,MALFEX 就是「撒网」。
这个 npm 供应链行动共投放了 8 个恶意包,分发 Windows 恶意软件,载荷包括 Overlord RAT 远控木马、一个名为 movinlike 的信息窃取器,以及一个藏在 ASCII-art 工具里的独立下载器。偷什么?浏览器保存的密码、Discord 令牌、加密货币钱包——标准的开发者终端「全家桶」。
更值得注意的是画像:行动从 2023 年 8 月持续至今,且疑似由单一运营者操盘。其中下载量最大的包 function-flag,累计下载 37,419 次,并且长期携带着恶意代码。
这个案子最有教学价值的地方在于载荷设计。ASCII-art 工具是个绝佳的伪装——开发者在终端里看到一段字符画,心理预期是「无害的极客玩具」,很难联想到里面埋着下载器。而 RAT 和信息窃取器分层投放,意味着攻击者既能批量收割低价值凭据,也能对高价值目标做深度驻留。
把两起事件放进同一张图里看,结论很清楚:npm 投毒在左下偏中——门槛低、单点价值不高,但胜在规模化、可持续,一个人就能运营两年多;Actions 密钥注入则直奔右上——门槛稍高,但一旦得手,直接拿到云和企业级身份。一个人运营的 npm 行动是现金流,CI/CD 注入是期权。攻击者两个都要。
两起事件的手法对比,放在一张表里更直观:
| 维度 | GitHub Actions 注入 | MALFEX npm 行动 |
|---|---|---|
| 攻击载体 | 恶意 workflow,伪装安全检查 | 8 个恶意 npm 包 |
| 目标环境 | CI/CD runner | 开发者 Windows 终端 |
| 窃取对象 | SSH 密钥、云凭据、access token | 浏览器密码、Discord 令牌、加密钱包 |
| 投放载荷 | 外传式密钥窃取 | Overlord RAT + 信息窃取器 + 下载器 |
| 规模 | 瞄准 2,577 个 secrets,确认得手 26 个 | function-flag 单包 37,419 次下载 |
| 持续时间 | 集中式行动 | 2023 年 8 月至今,疑似单人运营 |
🧭 攻击面迁移:从仓库到仓库周围的一切
安全行业花了很多年教大家保护代码:扫描漏洞、审计依赖、SAST/DAST 全家桶。但这两起事件说明,代码本身已经不是最薄弱的环节了。
真正的变化在于:软件生产过程中的每一个「信任决策点」都被武器化了。workflow 执行是信任——runner 默认相信被触发的代码值得执行;包下载是信任——开发者默认相信 npm 上 37,419 次下载代表社区背书;甚至 ASCII 艺术也是信任——它利用的是「看起来无害」的视觉预期。
行动开始活跃
恶意包陆续上架
长期携带恶意代码
被研究人员披露
`
(上面这条时间线也暴露了另一个问题:一个疑似单人运营的行动,在公开平台上潜伏了两年多才进入研究者视野。开源供应链的检测滞后性,远比大多数团队想象得严重。据多位做开源安全治理的从业者私下观察,多数企业对 npm 依赖的审查仍停留在「知名包就没问题」的直觉阶段,下载量恰恰是最容易被高估的信任信号。)
产业层面的判断有三条:
第一,身份与访问安全正在成为供应链安全的主战场。偷代码的价值在下降,偷凭据的价值在上升——因为凭据可以直接兑换成云资源、数据访问和横向移动能力。
第二,开发侧安全预算会持续向两个方向倾斜:CI/CD 的权限治理,和开发终端的检测能力。这两块过去在安全预算里几乎排不上号。
第三,「注入多、得手少」的 1% 转化率提醒我们:防御不必追求完美,只要在链路上多设置一两个真实有效的断点,就能把攻击者的 ROI 打到不值得。
🛡️ 一份能落地的防御清单
理论讲完,说点能周一早上就做的。
针对 workflow 注入,核心是把 runner 从「密钥集中营」改造成「最小权限沙箱」:workflow 权限默认收紧到只读,fork PR 一律不自动注入 secrets,长期静态密钥尽量替换成 OIDC 短期令牌——攻击者即便读到,令牌也已经过期。再配上 runner 出口流量的白名单管控,外传通道会被大幅压缩。
针对 npm 投毒,重点是打破「下载量即信任」的幻觉:依赖锁定版本、新包进入构建前过一遍行为审查(尤其警惕下载器、混淆代码、postinstall 脚本),开发终端上 EDR 不应是可选项——浏览器密码、Discord 令牌、加密钱包全都躺在这台机器上。
`infographic
{"type":"problemsolution","title":"开发侧攻击面收敛清单","items":[{"problem":"workflow权限过宽,runner持有大量长期密钥","solution":"默认只读权限+OIDC短期令牌替代静态密钥"},{"problem":"fork PR可被用于注入恶意workflow","solution":"fork PR不自动注入secrets,人工审批后执行"},{"problem":"runner可自由外联,密钥外传无阻拦","solution":"出口流量白名单,阻断未知域名"},{"problem":"依赖盲目信任下载量与社区背书","solution":"锁定版本+新包行为审查+postinstall脚本排查"},{"problem":"开发机缺乏终端检测,密码与令牌裸奔","solution":"EDR覆盖开发终端,凭据托管替代浏览器存储"}]}
`
不必追求五条全做到。前两条——最小权限和 fork 隔离——能挡住绝大多数 CI/CD 注入的实际得手路径;对 npm,锁定版本加脚本审查已经是性价比最高的起步动作。
小结:攻击者不看代码,看钥匙
把两起事件放回一起:GitHub Actions 注入瞄准 2,577 个 secrets 得手 26 个,MALFEX 单人运营两年收割开发机。手法不同、载体不同,但攻击者的账本是同一本——代码在仓库里,钥匙在流水线和开发机里,而后者几乎没人认真看守。
接下来的看点有两个:一是 OIDC 短期凭证和 scoped token 能否在主流 CI/CD 平台上成为默认配置;二是开源注册中心会不会被迫引入更强的发布者验证与行为审计机制。在此之前,建议每个团队先做一件小事:列出你们所有 workflow 能读到的密钥清单——看清家底,是收敛的第一步。
本文由本站 AI 辅助聚合生成,原始来源如下: