场景:2026年9月下旬,某金融科技公司内部npm镜像站突发异常。多名开发者在构建流水线中发现构建产物被注入可疑代码,安全团队随即启动溯源,一场围绕供应链投毒的暗战就此展开。
攻击 / 事件时间线
初始投毒:镜像站沦陷
攻击者通过弱口令爆破进入内部npm镜像站(Verdaccio)管理后台,利用其publish权限向三个高频依赖包(@corp/utils、@corp/logger、@corp/api-sdk)发布恶意版本。恶意代码藏于postinstall脚本中,执行时从snippet.host拉取Base64编码的载荷,解码后落地为/tmp/.cache/node并赋予执行权限。
Verdaccionpm publishsnippet.hostBase64编码
横向扩散:CI/CD流水线失守
恶意包被CI流水线自动拉取,postinstall脚本在构建节点执行。脚本首先检测/proc/1/cgroup判断是否在容器环境,随后收集环境变量中的CI_JOB_TOKEN、NPM_TOKEN及AWS_ACCESS_KEY,通过curl外带至攻击者C2(185.199.xx.xx)。攻击者利用窃取的令牌向制品库推送更多恶意包,形成二次扩散。
CI/CDcurl环境变量窃取C2
持久化:后门植入与定时任务
攻击者在构建节点植入systemd服务node-cache.service,伪装为缓存清理程序,实际每30分钟从C2拉取指令。同时修改~/.npmrc指向恶意registry,确保后续安装持续投毒。为规避检测,恶意进程名伪装为node,并利用LD_PRELOAD劫持readdir隐藏自身文件。
systemdLD_PRELOADrootkitnpmrc劫持
告警触发:SOC发现异常外连
SOC的NDR系统捕获到构建节点向未知IP 185.199.xx.xx的周期性HTTPS外连,流量特征为固定User-Agent和心跳间隔。同时,Sysmon日志显示node进程异常创建systemd服务。蓝队结合YARA规则扫描镜像站存储,发现三个恶意包版本,确认供应链投毒事件。
NDRSysmonYARA威胁情报
蓝队视角 · 发现与处置
SOC值班人员首先通过NDR告警发现构建节点异常外连,结合威胁情报确认C2 IP为已知恶意地址。随后使用Sysmon日志回溯进程链,发现node进程创建了可疑systemd服务,并调用curl外带数据。蓝队立即隔离受影响构建节点,暂停CI/CD流水线,对镜像站进行快照取证。通过YARA规则扫描npm存储目录,定位三个恶意包并下架。同时重置所有CI/CD令牌和云凭证,排查是否有其他节点被感染。最终确认攻击者通过弱口令进入镜像站后台,完成投毒。
涉及关键技术 / 工具
npm postinstall脚本投毒CI/CD环境变量窃取LD_PRELOAD rootkit隐藏
防护经验总结
- 对内部npm镜像站启用强口令+双因素认证,限制发布权限至白名单账户,并开启操作审计日志。
- 在CI/CD流水线中禁用postinstall脚本执行(npm config set ignore-scripts true),并对构建节点实施网络微隔离,仅允许白名单外连。
- 部署YARA规则定期扫描制品库,监控package.json中postinstall、preinstall等钩子,发现异常立即阻断并溯源。
#供应链攻击#npm投毒#CI/CD安全#溯源复盘