当前时间: 2026-03-26 12:41:11
更新时间: 2026-03-26
分类:软件教程
评论(0)
你最信任的工具,正在成为你最致命的后门
一个月内,两起供应链攻击,两套剧本,同一个结局:你以为安全的地方,早已沦陷。
事件速览
2026年2月初,全球最流行的文本编辑器之一 Notepad++ 的更新基础设施遭到入侵。安全公司 Rapid7 将此次攻击归因于中国 APT 组织“莲花(Lotus Blossom)”,攻击者通过劫持“更新服务器”,向特定目标投放了一个从未被记录过的后门程序——Chrysalis。
2026年3月24日,AI 开发者常用的 Python 库litellm在 PyPI 上出现两个含恶意代码的版本(v1.82.7 和 v1.82.8)。攻击者是代号TeamPCP的黑客组织——他们并没有去硬攻 litellm 本身,而是先攻破了广泛用于安全扫描的开源工具Trivy(由 Aqua Security 维护),将其发布通道变成窃取凭证的武器,进而把 litellm 的 PyPI 发布密钥偷了出来,最终绕过一切代码审查,往官方仓库里塞进了木马。AI 的天塌了,甚至连 OpenClaw 新发布的版本里都被发现有这个问题集成。
两起事件乍看相似:都是供应链攻击,都布局深远。但细看之下,手法截然不同,值得分开剖析。
第一幕:Notepad++ 被“寄生”
攻击者拿下的不是代码,是托管服务器
莲花组织没有去攻破 Notepad++ 的 GitHub 仓库,甚至没有触碰任何一行源代码。他们做了一件更聪明的事:攻入了 Notepad++ 当时使用的托管服务商。
根据 Notepad++ 作者侯今吾(Don Ho)的披露以及 Rapid7 的调查报告,攻击者早在 2025 年 6 月就已获得托管服务器的访问权限,并在随后数月内保持潜伏。他们获得的权限极高,使得常规的服务器检查和重启都难以发现其存在。
2025 年 9 月,托管服务商进行了一次例行的内核与固件更新,意外清除了攻击者的服务器级权限。但攻击者仍握有内部服务的凭证,足以继续部分流量重定向,一直持续到 2025 年 12 月初才彻底失去控制。
旧版更新程序是突破口
Notepad++ 的更新组件 WinGUp 在 8.8.9 版本之前存在一个验证缺陷:它会检查下载的文件,但没有严格执行证书匹配与数字签名的完整校验。只要攻击者能控制服务器上的更新配置脚本(getDownloadUrl.php),就能欺骗 WinGUp 去下载并运行一个名为 update.exe 的恶意安装程序。
用户看到的界面是正常的 Notepad++ 安装界面,但后台早已开始加载 Chrysalis 后门。
精准投放,不撒网
这次攻击最值得注意的一点是:攻击者并不对所有用户下毒。
他们修改了 getDownloadUrl.php 脚本,通过识别请求者的 IP 地址和地理位置进行筛选。来自政府机构、电信运营商、金融机构的请求,会被重定向到恶意服务器;普通用户收到的,依然是正常的更新包。
据 Kaspersky 的遥测数据,在整个攻击周期(2025 年 7 月至 10 月)内,受感染机器不足二十台,目标集中在东南亚和中美洲的政府、金融机构,以及越南的 IT 服务提供商。后续 Palo Alto 的调查表明,目标范围实际更广,波及美国和欧洲的能源、制造、云服务企业。
在企业环境中,Notepad++ 往往是系统管理员、网络工程师和 DevOps 人员的常用工具——这可能是莲花组织选择它的原因之一。更值得注意的是,侯今吾不仅仅政治倾向很强,而且还特别喜欢在 Notepad++ 软件界面上公开他的政治倾向,把一个生产力工具变成他私人的政治宣传板。这可能是莲花组织找上他的原因之一。
事件收尾
2026 年 2 月,事件正式曝光,侯今吾宣布将网站迁移至更安全的托管商,并于此前发布了 8.8.9 版本修复了更新验证机制,后续 8.9.2 版本引入了强制 XML 数字签名校验(XMLDSig)。
第二幕:litellm 中毒——安检仪里装了炸弹
如果说 Notepad++ 事件是“劫持了运货的车”,那本次 litellm 投毒事件则是“在安检仪里装了炸弹”。
攻击者:TeamPCP 是谁
“TeamPCP”这个名字来自攻击者的自我标榜:他们将恶意工具命名为“TeamPCP Cloud Stealer”,并在攻陷 Aqua Security 的内部 GitHub 仓库后,把所有 44 个仓库的描述改成“TeamPCP Owns Aqua Security”。这是他们主动留下的签名,而非受害方的名称。
时间线:一场精密的三段式攻击
第一阶段:突破 Trivy 发布通道(2026 年 2 月底)
TeamPCP 利用 Trivy 项目 GitHub Actions 配置中的一个常见疏忽:pull_request_target 触发器设置不当,允许来自外部 Fork 的恶意 PR(通过自动化机器人账号hackerbot-claw)访问仓库的机密信息(Secrets)。
攻击者借此窃取了一个高权限个人访问令牌(PAT)。他们短暂接管了 Trivy 仓库,删除了大量历史版本,并尝试向 VS Code 插件市场(Open VSX)发布带毒版本。Aqua Security 的团队随后发现异常,进行了清理并重置了令牌——但清理并不彻底,部分凭证仍然有效。Aqua Security 事后承认:“我们轮换了 secrets 和 tokens,但这个过程不是原子性的,攻击者可能拿到了刷新后的令牌。”
第二阶段:全面接管(2026 年 3 月 19 日)
攻击者用残余凭证卷土重来,这次控制了官方自动发布机器人 aqua-bot。他们对 trivy-action 仓库的 75 个版本标签(Git Tags)进行了强制重写,将这些标签悄悄指向包含恶意代码的提交。
结果是:任何在这段时间内通过版本标签(而非固定 commit SHA)引用 Trivy 的 CI/CD 流水线,都会拉到一个“毒版本”。而且,由于正常的 Trivy 扫描依然在运行并输出正常报告,许多用户根本不会察觉任何异常。
第三阶段:收割 litellm(2026 年 3 月 24 日)
litellm 的 CI/CD 流程中,使用了 Trivy 来扫描代码安全性,且没有锁定版本(apt install trivy,直接拉最新版)。3 月 23 日,流水线运行时拉取了已被污染的 Trivy,其中隐藏的恶意代码在 CI 环境的内存中读取了环境变量,抓走了 litellm 用于向 PyPI 发布更新的PYPI_PUBLISH令牌。
3 月 24 日 10:52 UTC,攻击者用这枚令牌,绕过 GitHub 上的一切代码审查,直接从自己的机器上向 PyPI 上传了带毒的 litellm v1.82.7 和 v1.82.8。
这两个版本在 PyPI 上存活了约三小时,随后被下架。litellm 的月下载量约为 9500 万次。
木马的三层设计
凭证收割
扫描 SSH 密钥、AWS/GCP/Azure 云凭证、Kubernetes Secrets、环境变量文件(.env)、加密货币钱包,用 RSA-4096 加密后发送到攻击者控制的仿冒域名models.litellm[.]cloud。
横向移动
利用 Kubernetes Service Account Token 枚举集群节点,向每个节点部署一个特权 Pod(命名为node-setup-*)。
持久化后门
在 ~/.config/sysmon/sysmon.py 写入持久化脚本,并注册为systemd服务,每 50 分钟向 C2 地址拉取新的执行指令。
v1.82.8 还加入了一个更激进的触发方式:在 Python 包的安装目录写入litellm_init.pth文件。.pth文件会在每一次 Python 进程启动时自动加载,意味着不需要 import litellm,只需要安装了这个包,恶意代码就会运行。
更糟糕的是:这个恶意版本通过了所有标准的包完整性校验,因为恶意内容是用合法凭证发布的,哈希值完全正确。
攻击的实际规模:远不止 litellm
这场攻击的波及范围,已经远超最初的 Trivy 和 litellm。
据 Mandiant 咨询部门 CTO Charles Carmakal 在 RSA 大会期间披露,目前已知超过 1000 个 SaaS 环境受到了这个攻击者的直接影响,预计还将扩展至数千乃至上万个下游受害者。
Trivy 攻击发生后数天,安全公司 Checkmarx 的 GitHub Actions 也遭到同样手法的攻击。Sysdig 确认,恶意载荷、加密方案和 tpcp.tar.gz 命名约定完全一致,攻击者复用了从 Trivy 事件中窃取的凭证,在下游仓库中持续投毒。
与此同时,TeamPCP 还将攻击扩展到 npm 生态,借助窃取的发布令牌感染了超过 66 个 npm 包(141 个恶意构件版本),并在其中植入了一个自我传播的蠕虫 CanisterWorm——每一个安装了被污染包且拥有 npm 发布令牌的开发者或 CI 流水线,都会成为蠕虫的下一个传播节点。
此外,TeamPCP 还攻入了 Aqua Security 的内部 GitHub 组织(aquasec-com),在 102 秒内批量篡改了 44 个内部仓库的名称和描述,暴露了包括 Tracee 内部代码、CI/CD 流水线配置、Kubernetes operator 和团队知识库在内的大量内部资产。
发现靠的是运气
最初发现这次攻击,靠的几乎是纯属意外。FutureSearch 的一位研究员在 Cursor IDE 里测试一个 MCP 插件,该插件将 litellm 作为间接依赖引入,结果机器因指数级的进程 fork 耗尽了内存,才引起注意。
攻击者还试图压制这次披露:在 GitHub 的漏洞报告 Issue#24512下,88 个机器人账号在 102 秒内刷了大量无意义的评论;随后,Issue 被以”not planned”关闭——大概率是攻击者用已控制的维护者账号所为。
两起事件的核心教训
这两起事件用不同的方式,指向同一个脆弱性:现代软件开发中,信任是可以被传递和滥用的。
莲花 / Notepad++:告诉我们软件本身的代码可以干净,但运行代码的基础设施(托管服务商、更新服务器)如果被攻破,代码的安全性就毫无意义。更新通道和签名验证不是可选项,是必选项。
TeamPCP / Trivy / litellm 事件:告诉我们”你最信任的安全工具,往往就是你最脆弱的后门”。凭证轮换必须彻底且原子性,不能留死角;CI/CD 流水线拉取的每一个工具都是信任边界的一部分;版本标签不等于内容不变,锁定到 commit SHA 才是固定的锚点。
如果你现在就在用 litellm
如果版本是1.82.7 或 1.82.8,停止一切,立即:
视所有曾可被该环境访问的凭证为已泄露,全量轮换:SSH 密钥、云服务 Access Key、数据库密码、LLM API Key
检查环境中是否存在 litellm_init.pth、~/.config/sysmon/sysmon.py或名为node-setup-* 的 Kubernetes Pod
写在最后
供应链攻击不是新概念,但它正在变得越来越精准、越来越难防。攻击者不再正面强攻你的防火墙,他们只需要找到你信任链上最薄弱的一环——可能是你的更新服务器,可能是你的安全扫描工具,可能是你的构建流水线。
你不能信任所有东西。但你可以把信任的边界画得更清晰,把验证机制做得更严格,把每一次密钥泄露后的清理工作做得更彻底。
草蛇灰线,伏脉千里。攻击者有的是耐心。防御者能做的,是让自己的每一道锁都对得上它的钥匙。
参考来源:Rapid7 实验室技术报告、The Hacker News、The Register、Snyk 安全分析、Wiz 威胁情报、Aqua Security 官方公告、litellm 官方安全通告(docs.litellm.ai)