0x40532d1d06f08434ba58826eebe839e4ed7d858f1cde4a81fd0c7d733dd21d1b

BLOCK #29·10·2026 · SIGNATURE REQUEST

签名之夜

一场六十四亿美元的链上劫案

一部关于 Web3 黑客攻击的中篇小说 · 8 章 + 附录

开始阅读 ↓

作者说明: 本书是一部虚构小说,灵感来自 2026 年 10 月 29 日某头部交易所热钱包被盗事件的公开报道(包括该交易所 2026 年 11 月 3 日发布的初步调查报告,以及 CoinDesk、Elliptic、Chainalysis、WIRED 等媒体与机构的分析)。书中的交易所“天枢交易所”、所有人物、对话、公司名与内心活动均为虚构;时间线与技术手法参考公开资料,但做了文学化处理。书中所有技术描写均停留在概念层面,不包含可复现的攻击步骤、恶意代码或真实攻击者地址。写这本书的目的只有一个:让读者在故事里看懂 Web3 黑客是怎么得手的,以及我们怎样才能不成为下一个缺口。

主要人物

  • 林泽:天枢交易所钱包 DevOps 工程师,六月的“第一块多米诺骨牌”。
  • 周一航:天枢交易所软件工程师,二十九岁,正在悄悄找下一份工作。
  • 韩笑:天枢交易所钱包工程师,林泽的同组同事。
  • 沈墨:天枢交易所首席安全官(CSO),事件响应总指挥。
  • 陆鸣:链上取证公司“链镜”的首席分析师,一个习惯用颜色给钱包地址分类的人。
  • “掌柜”:一个代号为“商人”的国家级黑客小组的行动负责人。
  • “艾米莉”“大卫”:并不存在的人。

CHAPTER 01 / 08

第一章

六月的安装包

2026 年 6 月,新加坡,凌晨一点。

林泽的显示器上开着十一个终端窗口,像一面墙上挂满了钟。他负责天枢交易所钱包系统的部署与运维——用他自己的话说,就是“给全世界第二大的保险柜换锁芯的人”。那天晚上他要搭一套新的测试环境,顺手想试试最近在开发者圈子里刷屏的那个 AI 编程助手。

群里人人都在用。有人说它能一口气重构三千行代码,有人说用了它之后每天能早下班两个小时。林泽打开搜索引擎,输入工具的名字,再加上“Homebrew 安装”。

第一条结果并不是官网,而是一个排版漂亮、带着“赞助”小字的页面。标题写着“官方一键安装指南”,下面是一行看起来再普通不过的安装命令——和他这辈子在 macOS 上复制过的几百行命令长得一模一样。

他犹豫了大约一秒。页面上的 Logo 是对的,配色是对的,甚至连文档的字体都一样。凌晨一点的大脑不擅长怀疑。

他复制,粘贴,回车。

进度条走得很顺。终端里滚过一串依赖包的名字,最后跳出一个绿色的“安装成功”。AI 助手的图标出现在菜单栏里,冲他眨了眨眼。林泽打了个哈欠,合上了电脑。

他不知道的是,就在那串滚动的文字里,有一个小小的脚本悄悄多干了一件事:它把这台电脑的主机名、登录用户、所在网段、浏览器里保存的会话信息,打成一个压缩包,发往了一个伪装成“遥测服务”的地址。

第二天上午十点,林泽的工位前站了两个人。

一个是安全运营中心的值班分析师,另一个是首席安全官沈墨本人。沈墨四十出头,短发,说话不快,但每一句都像是事先校对过。

“林泽,昨晚一点零七分,你的电脑向一个外部地址发送了大约四十兆的数据。”沈墨把平板递到他面前,“我们的终端检测规则标记了它——一个本不该联网的安装脚本,在安装结束后又起了一个子进程。”

林泽的脸一下子白了。他想起那个“赞助”页面,想起那一秒的犹豫。

“我……我只是装了个 AI 编程工具。”

“我知道。”沈墨的语气没有责备,“你不是第一个。今年到现在,我们已经拦下了三十多次同一类型的尝试——假面试、假开发工具、投毒的软件包、伪装成插件的浏览器扩展、假的视频会议客户端。这个月你是第四个点中假安装页面的人。”

接下来的四个小时像一场外科手术。林泽的笔记本被装进防静电袋带走;他的所有凭证——单点登录密码、SSH 密钥、云平台访问令牌、代码仓库令牌——被逐一吊销重发;他被要求重新注册硬件安全密钥。到下午,他领到了一台全新的电脑,系统是安全团队用标准镜像刚刚灌好的。

“结束了吗?”他问。

沈墨看了他一眼,没有马上回答。

“设备换了,钥匙换了,”她说,“但有一样东西换不了。”

“什么?”

“对方已经知道你是谁了。他们知道天枢有一个叫林泽的人负责钱包部署,知道你在哪个团队、和谁协作、平时用什么工具。那四十兆数据里,有你的通讯录缓存和日历截图。”她停顿了一下,“我们能换锁,但没办法让小偷忘记这栋楼的平面图。”

同一时间,在几千公里外一间没有窗户的房间里,一个被同伴称作“掌柜”的男人正看着屏幕上展开的一张关系图。

图的中心是一个名字:林泽。从他身上延伸出十几条线——他的组长、他的同组同事韩笑、经常和他在日历里约会议的几个后端工程师。每一个名字旁边都标注着职位、社交账号、公开的技术博客和招聘平台上的简历状态。

“设备丢了。”手下汇报,“对方安全团队反应很快,四个小时就把他所有的凭证都换了。”

掌柜没有生气。他用鼠标在关系图上慢慢画了一个圈,把林泽周围那一圈人都圈了进去。

“没关系。”他说,“我们本来就不是来偷这一把钥匙的。我们是来认识这家人的。”

他把鼠标停在一个名字上:周一航,软件工程师,招聘平台状态——“开放机会”。

CHAPTER 02 / 08

第二章

完美的面试

九月的第一个周一,周一航收到了一条私信。

发信人的头像是一个穿灰色西装、站在玻璃幕墙前的中年男人,名片上写着“Head of Projects”,公司是一家在招聘平台上有认证标识、有三百多名员工、有一长串融资新闻的 Web3 基础设施公司。

“周先生您好,我们在做下一代跨链结算网络,看到您在高并发撮合系统方面的经验,非常契合我们的核心团队。薪资区间可以比您目前高出 40% 到 60%,全远程,可以聊聊吗?”

周一航二十九岁,在天枢交易所写了三年撮合引擎周边的服务。他喜欢这份工作,但房租涨了,女朋友在问明年结婚的事,而他的职级已经卡了一年半。他在平台上把状态调成“开放机会”,原本只是想看看市场行情。

他回了一句:“可以,方便的话请发一下 JD。”

第一轮是视频面试。

屏幕那头的 HR 叫艾米莉,二十七八岁,笑起来有两个酒窝,背景是一间洒满阳光的共享办公室,身后偶尔有人端着咖啡走过。她的普通话带一点台湾腔,英语切换得很自然。

“我们 CEO 特别看重候选人的工程品味,”她说,“所以流程会稍微长一点,希望您别介意。”

她问了周一航的项目经历、离职动机、期望薪资,问得专业又体贴。聊到一半,她忽然笑着说:“对了,您是不是也喜欢徒步?我看您的头像是在山上拍的。”

“对,麦理浩径。”

“天哪,我上个月刚走完!”艾米莉眼睛一亮,“我把我的账号给您,里面有好多照片,您看看是不是同一段。”

她发来一个社交账号。周一航点开——几百张照片,跨越五六年:毕业典礼、和闺蜜去清迈、家里的柯基、生日蛋糕上的蜡烛、在山顶比剪刀手。评论区里有朋友在调侃她,有她妈妈留的“早点回家”。

一个活生生的人。

周一航后来无数次回想这一刻。那些照片是真的吗?也许是从某个真实的女孩那里偷来的,也许是 AI 一张张生成、再花几年时间慢慢“养”出来的。他永远不会知道答案。他只知道,在那一刻,他心里那根叫作“警惕”的弦,被一只小柯基轻轻按住了。

第二轮换到了一个即时通讯软件上。

“我们 CEO 大卫想亲自跟您聊,”艾米莉说,“他在不同时区出差,文字沟通更方便。”

大卫的头像是一张模糊的侧脸,说话风格干脆利落,满嘴都是“共识层”“结算终局性”“我们不做 PPT 项目”。他和周一航聊了四十分钟架构,问题刁钻却又恰到好处地让人有表现欲。最后他说:

“技术聊得很愉快。我们最后一关是一个小作业:仓库里有一个撮合服务的原型,性能有瓶颈,你帮我们看看能优化多少。不限时间,周末做完就行。做得好,下周一直接发 offer。”

他发来一个代码仓库的链接。仓库看起来非常专业:清晰的 README、完整的单元测试、几十次提交历史、几个“贡献者”的头像。README 第一节写着:

“快速开始:克隆仓库,执行依赖安装,然后运行测试。”

那是周五晚上九点。周一航的私人笔记本放在家里,电池坏了一直没修。而他面前这台公司配发的工作电脑,开发环境齐全,跑测试最方便。

“就跑一下测试,”他对自己说,“能有什么事。”

他在工作电脑上克隆了仓库,敲下了那行安装依赖的命令。

CHAPTER 03 / 08

第三章

一行安装命令

安装命令执行了二十三秒。

在周一航看来,这二十三秒和过去几年里任何一次安装依赖都没有区别:终端里刷过几百行包名和版本号,偶尔夹着几条黄色的“已弃用”警告,最后停在一个干净的提示符上。他运行测试,四十七个用例全部通过。他打开撮合引擎的核心循环,开始思考怎么减少锁竞争。

可是在那二十三秒里,有一件他看不见的事情发生了。

【掌柜视角】

“他跑了。”

房间里响起一声压低的欢呼。掌柜抬手制止了它。屏幕上,一个新的“信标”刚刚点亮——一台位于新加坡、属于天枢交易所内网的工作电脑,第一次向他们的指挥服务器打了招呼。

这个仓库是他们花了两个月打磨的作品。代码本身几乎完全正常,甚至写得比很多真实开源项目还要好;那四十七个测试是真的,能通过也是真的。秘密藏在依赖清单里:其中一个依赖包带着一段“安装后自动执行”的钩子脚本。

现代软件包管理器——无论是 JavaScript 世界的 npm,还是 Python 世界的 pip——都允许软件包在安装时执行一段脚本,原本是为了编译本地模块、下载二进制文件这些正当用途。开发者早就习惯了这个机制,习惯到没有人会去读它。

这段脚本经过了多层混淆,读起来像一团乱码。它做的事情可以用几句话概括:先检查自己是否运行在沙箱或虚拟机里,如果是,就安静地什么也不做;如果不是,就从网上取回真正的载荷;载荷利用了一个当时还没有被公开的漏洞——也就是所谓的“零日漏洞”——悄悄替换掉了这台电脑上一个合法开发工具的组件。

“为什么要替换开发工具?”行动组里最年轻的成员小金问。

“因为终端安全软件信任它。”掌柜说,“一个每天都在编译代码、读写文件、访问网络的开发工具,突然多做了一点点事,谁会觉得奇怪?杀毒软件盯的是陌生人,我们就把自己变成熟人。”

替换完成后,载荷做了三件事:每隔一段随机时间,用伪装成普通 HTTPS 流量的方式联系指挥服务器(C2),领取新指令;把最初那段钩子脚本、下载记录和临时文件全部抹掉;把仓库里那个依赖的版本悄悄“修正”回干净版本。

如果有人第二天去审查这个仓库,看到的将是一份毫无问题的代码。

“终端检测没有报警?”

“没有。”操作员盯着回传的日志,“他们的检测产品在运行,但它看到的只是一个已签名的开发工具在做开发工具的事。”

掌柜点了点头。他在关系图上周一航的名字旁边,画了一个小小的绿色对勾。

“不要急。”他说,“接下来几个星期,什么都别做。只看,只听。让他们觉得这台机器和昨天一样干净。”

周一,周一航提交了作业,附上了一份五页的性能分析报告。他觉得自己写得很漂亮。

艾米莉回复:“太棒了!大卫说你的方案是他见过最好的。我们内部走一下流程,这周给你答复。”

然后,艾米莉的账号就再也没有亮起过。

一周后,周一航发消息问进度,显示“对方已注销”。他愣了一会儿,自嘲地笑了笑,以为自己只是又碰上了一家“画饼”公司。他把这件事讲给女朋友听,女朋友说:“算了,至少练了练手。”

他没有想到,他练的不是手。他交出去的,是天枢交易所内网的一扇门。

CHAPTER 04 / 08

第四章

借来的手

10 月 20 日,星期二。

距离周一航按下回车,已经过去了七个星期。这七个星期里,他的工作电脑一直在“说话”,只是说得很轻:它把周一航每天打开的内部网页、调用的内部服务、加入的群聊名单,一点一点地汇报出去。攻击者像一个借住在别人家里的房客,熟悉了每一扇门、每一盏灯的开关。

他们发现了一个有意思的东西。

天枢交易所去年上线了一个内部 AI 助手,员工们亲切地叫它“小枢”。小枢能回答内部文档问题、帮忙排查环境故障,还有一项很受欢迎的功能:工程师可以让它“帮我在某某同事的机器上跑一下诊断”,它会通过公司的设备管理通道,在对方电脑上执行一些维护任务——收集日志、检查配置、重启服务。

为了让它好用,小枢被赋予了相当大的权限。为了让它更好用,审批流程被设计得很“顺滑”:同一部门、同一项目组的请求,默认自动通过。

“这就是我们要的那只手。”掌柜说。

【韩笑视角】

那天下午三点,韩笑正在写一份钱包签名服务的季度复盘。屏幕右下角弹出一个提示:“小枢正在为您执行例行环境诊断,预计耗时两分钟。”

她瞥了一眼,没在意。这种提示一周要弹好几次,公司内部群里还有人做过表情包:“小枢又来体检了”。

两分钟后,提示消失了。她的电脑风扇转了一会儿,然后安静下来。

她不知道,这次“体检”的请求并不是来自 IT 部门,而是来自周一航的账号;而那个请求里夹带的诊断脚本,为攻击者在她的电脑上留下了一条新的通道。同一个下午,林泽的电脑也接受了一次“体检”。

林泽的那台新电脑,是六月那次事件之后安全团队亲手交给他的。它很干净——直到这一天。

攻击者进入林泽的电脑后,没有着急做任何事,而是开始翻找。他们要找的东西很明确:令牌(token)。

在云原生的世界里,工程师很少再用用户名和密码登录服务器。取而代之的是各种各样的令牌——访问云平台的令牌、拉取代码的令牌、部署容器的令牌。它们通常是一长串字符,静静地躺在某个配置文件或命令行工具的缓存里,谁拿到它,谁就是它的主人。

“找到了。”小金的声音有点发抖。

那是一个容器部署平台的令牌,属于林泽。它的权限远远超过了一个工程师日常工作所需:它可以在生产环境的钱包集群里部署新的容器。更要命的是,它的有效期很长——为了方便林泽在半夜处理紧急发布,有人在几个月前把它的过期时间调成了九十天。

掌柜看着这串字符,沉默了很久。

“记住这一天。”他终于开口,“我们现在有了三个人:一个是门,一个是手,一个是钥匙。”

周一航是门——攻击者进入内网的入口。

韩笑是手——一台在钱包团队内部、日常就会访问签名相关系统的电脑。

林泽是钥匙——一个能在生产环境部署容器的令牌。

“还缺什么?”小金问。

“一个合适的夜晚。”掌柜说,“值班的人最少、眼睛最累、市场最热闹的那种夜晚。”

他在日历上圈了一个日期:10 月 29 日。

CHAPTER 05 / 08

第五章

冷与热

10 月 29 日,17:15(UTC)——新加坡时间 10 月 30 日凌晨 01:15

韩笑早就下班了。她的电脑锁着屏,放在公司工位上,风扇以最低转速嗡嗡地响。

屏幕没有亮,但电脑里有人登录了。

攻击者通过七个星期前埋下的通道,进入了韩笑的电脑。从这一刻起,在天枢交易所的所有日志里,接下来发生的每一个动作,看起来都是“钱包工程师韩笑,在她自己的设备上,做她的日常工作”。

要理解接下来发生的事,得先知道交易所的钱是怎么放的。

天枢交易所里躺着几百亿美元的用户资产。绝大部分放在“冷钱包”里——私钥被拆分保存在离线的硬件设备里,锁在不同城市的保险库中,要动用一次,需要多名高管到场、多重审批,耗时以天计。冷钱包就像银行的金库:安全,但笨重。

可是用户每分每秒都在提币。为了让提币几分钟就能到账,交易所会把一小部分资产放在“热钱包”里——它们一直在线,由自动化系统随时签名转账。热钱包就像银行柜台的现金抽屉:方便,但必须时刻有人盯着。

对天枢这样的头部交易所来说,“一小部分”也是一个天文数字:几十亿美元。

那么,谁来给热钱包签名?

天枢用的是 MPC——多方安全计算(Multi-Party Computation)。在 MPC 钱包里,世界上从来不存在一把“完整的私钥”。私钥被数学方法拆成好几份“密钥分片”,分别保存在不同的服务器上。每次签名时,这几台服务器各自用自己的分片参与一轮计算,共同算出一个合法的签名,但任何一台都看不到完整的私钥。

这是一项了不起的发明:偷走任何一台服务器,都拿不到钥匙。

但 MPC 解决的是“钥匙会不会被偷”的问题,没有解决另一个问题:如果有人能让这套系统心甘情愿地替他签名呢?

在天枢的架构里,所有 MPC 节点前面有一个“签名服务”。正常情况下,用户提币请求要先经过风控引擎、额度检查、地址白名单、人工复核等一系列关卡,最后才由提币系统把一笔“已批准”的交易交给签名服务。签名服务信任提币系统——因为它们都在同一个内网、同一个集群里。

攻击者要做的,就是绕过前面所有的关卡,直接走到签名服务的面前。

18:40(UTC)

用韩笑的电脑作为跳板,攻击者拿出了林泽的那个部署令牌。

他们在生产钱包集群里部署了一个新的容器。这个容器的名字起得很讲究,和集群里其他几十个运维容器的命名规则完全一致,看上去像是某次例行维护留下的临时任务。

容器里只有一个脚本。脚本的逻辑并不复杂:以内部服务的身份,直接调用签名服务的接口,提交它自己构造好的转账交易。

签名服务看到的是:一个部署在自己集群里、由合法令牌创建、来自内部网络的请求。它没有理由怀疑。

“测试交易成功。”小金报告,“一笔很小的金额,正常签出,正常上链。”

掌柜盯着屏幕上那个哈希值看了很久。

“我们已经站在柜台里面了。”他说,“接下来,不要贪快,要贪稳。按清单来。”

19:56(UTC)

最后一轮准备完成。攻击者在韩笑电脑上的会话结束了。

此时的天枢交易所,值班室里坐着三个人。一个在处理一条关于某个山寨币充值延迟的工单,一个在看监控大屏上的流量曲线,还有一个刚刚去泡了第三杯咖啡。这是一个普普通通的夜晚,市场有点热,提币量比平时高了百分之二十,一切都在正常波动范围内。

20:05(UTC)

第一笔交易离开了。

五个 XRP 热钱包,在四分钟内,几乎同时向外发出了转账。

20:09(UTC)

233,460,000 枚 XRP,已经不属于天枢交易所了。

监控大屏上的余额曲线,像是被人一刀砍断。

CHAPTER 06 / 08

第六章

作战室

20:14(UTC)——新加坡时间凌晨 04:14

沈墨的手机在床头柜上震动的时候,她正梦见自己在一条走不完的走廊里找一扇门。

“沈总,”值班主管的声音在发抖,“热钱包……热钱包在大额异常出账。XRP 走了两亿三千万枚,SOL 走了九十多万枚,OP 也在走。告警刚刚触发。”

沈墨坐起来,看了一眼时间。她没有问“怎么会”,只问了三个问题:

“现在还在出吗?”

“在。”

“提币系统暂停了没有?”

“正在走暂停流程。”

“不用走流程了,我授权,全平台立即暂停提币。十分钟后作战室见。”

20:31(UTC)

天枢交易所二十七楼的作战室,平时是一间普通的会议室,墙上挂着三块屏幕。这一夜,屏幕上一块是热钱包余额,一块是链上浏览器,一块是内部日志检索。

人陆续到齐:钱包团队负责人、基础设施负责人、法务、公关、两名风控分析师。林泽是穿着拖鞋跑进来的,头发还湿着。韩笑在路上,电话一直开着免提。

“比特币。”风控分析师突然喊出声,“比特币热钱包在出!”

所有人转向屏幕。一串转账正在被打包进区块:18,270 枚 BTC。

“提币不是已经停了吗?!”

“停的是提币系统。”沈墨的声音很平静,平静得让人害怕,“对方根本没走提币系统。他们是直接找签名服务签的。”

她转向基础设施负责人:“签名服务前面现在有什么请求在进来?”

日志被调出来。在过去三个小时里,有一个从未见过的容器在持续调用签名接口。部署它的令牌属于——

所有人的目光落到了林泽身上。

林泽的脸一点血色都没有。“不是我……我在家睡觉,我发誓……”

“我知道不是你。”沈墨说,“六月那次之后我就知道,总有一天会有人用你的名字做事。现在,把那个容器杀掉,吊销这个令牌,冻结所有钱包团队成员的部署权限。所有。包括我。”

21:20(UTC)

容器被删除了。签名服务被切断了外部调用,只保留紧急通道。比特币、XRP、SOL、OP 的出血都止住了。

作战室里有人长出了一口气。

“以太坊这边不对。”钱包团队的一名工程师盯着屏幕,声音越来越小,“我们的一个以太坊热钱包……余额还在往下掉。”

“签名服务已经断了,怎么可能还在出?”

工程师放大了一笔交易的详情。交易的发起方并不是天枢的热钱包,而是一个陌生地址;但钱,却是从天枢的热钱包里转出去的。

沈墨走到屏幕前,看了足足十秒钟。

“七七〇二。”她说。

【陆鸣视角】

同一时刻,链上取证公司“链镜”的首席分析师陆鸣,正在家里对着三块屏幕吃泡面。他的预警系统在二十分钟前跳出了一条红色警报:一个被他标记为“头部交易所热钱包”的地址,出现了 EIP-7702 授权。

他差点把泡面打翻。

EIP-7702 是以太坊在“Pectra”升级里加入的一项新功能。在它出现之前,以太坊上有两种账户:一种是普通人用私钥控制的“外部账户”(EOA),它只会老老实实地按主人签名一笔一笔转账;另一种是“合约账户”,可以写入复杂的程序逻辑。

EIP-7702 让普通账户也可以“借用”一段合约代码:账户主人签一份授权,声明“从现在起,我的账户按照某某合约的逻辑来执行”。这原本是为了让普通钱包也能用上批量交易、代付手续费、社交恢复这些高级功能——就像给一辆普通汽车装上自动驾驶。

但如果你签下的授权,把方向盘交给了一个“清扫合约”呢?

那么,从这一刻起,任何人只要调用你的账户,就会触发那个合约的逻辑——把里面的资产统统扫走。不需要你再签名,不需要经过你的任何审批,也不管你的提币系统是开着还是关着。

陆鸣调出那个热钱包的历史,倒吸一口凉气:攻击者在签名服务被切断之前,已经让它签出了五十笔交易。其中包括授权,也包括一组经过精心安排、提前占用了未来编号(nonce)的交易——每个以太坊账户的交易都必须按编号顺序执行,攻击者提前“排好了队”,让防守方很难用一笔新交易把队伍插断。

“他们在钱包里装了一台抽水机。”陆鸣喃喃自语,“而且把开关焊死了。”

22:05(UTC)

“撤销授权需要什么?”沈墨问。

“理论上很简单,”钱包团队负责人说,“账户主人再签一份新授权,把委托指向空地址,就能把清扫合约踢出去。”

“那就签。”

“问题就在这里。”负责人揉着太阳穴,“我们是 MPC 钱包。世界上没有一把完整的私钥可以拿出来直接签。要签名,就必须让 MPC 节点协同计算——而我们刚刚为了止血,把签名服务整个隔离了。重新打开它,我们不知道里面还有没有对方留下的东西。”

作战室安静了下来。这是一个残酷的悖论:让 MPC 安全的那个特性——没有单点私钥——此刻恰恰让他们无法迅速关掉那台抽水机。

沈墨沉默了几秒。

“那就造一条新的路。”她说,“在一个全新的、干净的环境里,只拉起完成撤销所需的最少 MPC 节点,只允许签这一类交易,每一步都由三个人同时盯着。要多久?”

“最快……两个小时。”

“一个半小时。开始。”

接下来的一个多小时,是很多人这辈子最漫长的九十分钟。工程师们在白板上画出撤销交易的每一个字段,逐字逐句地核对;有人负责盯着链上排队的交易,计算对方还能抽走多少;法务在一旁起草给监管机构的通报;公关的手机已经被记者打爆。

韩笑赶到时,看到墙上的日志里,攻击的源头赫然是她的电脑。她站在门口,整个人僵住了。

沈墨走过去,把一杯热水塞进她手里。“现在不是追责的时候。”她说,“你最懂签名服务的内部逻辑,过来帮他们核对字段。”

00:10(UTC),10 月 30 日——新加坡时间上午 08:10

撤销交易上链。以太坊热钱包的余额曲线,终于停止了下滑。

作战室里没有人欢呼。窗外,新加坡的天已经亮透了。

沈墨看着屏幕上的总损失估算,那个数字还在跳动,最终停在了大约六十四亿美元。

这是人类历史上最大的一次加密资产盗窃。

CHAPTER 07 / 08

第七章

洗

【掌柜视角】

偷到钱,只是完成了一半。

掌柜比任何人都清楚这一点。区块链是一本公开的账本,世界上每一个人都能看到那些钱从天枢的热钱包流向了哪里。从第一笔 XRP 离开的那一刻起,一场新的赛跑就开始了:他们要在全世界的分析师、交易所、稳定币发行方反应过来之前,把这些钱变成“追不回来”的形态。

“第一优先级,稳定币。”他对屏幕前的五个操作员说,“二十分钟之内,全部换成以太币。”

为什么是稳定币?因为 USDT、USDC 这样的中心化稳定币,有一个对小偷来说致命的特性:发行方可以冻结它们。只要发行方把某个地址列入黑名单,那个地址上的稳定币就会变成一串无法转动的数字。

而以太币没有发行方,没有人能冻结它。

自动化脚本同时在多个去中心化交易所里下单,把一笔笔稳定币拆碎、兑换。大约二十分钟里,价值约三亿两千五百万美元的稳定币变成了 ETH。链上的价格被砸出了一个小坑,几个做市机器人兴奋地扑上来套利,完全不知道自己在为谁接盘。

“有一笔六千万的 USDT 来不及换了,”小金说,“滑点太大。”

掌柜想了想:“放进借贷协议。”

他们把这六千万美元的 USDT 存进了借贷协议 Aave,作为抵押品,借出了大约四千四百万美元的 WETH(包装后的以太币)。

小金一开始没明白。掌柜解释道:“抵押品被冻结了也没关系。我们拿走的是借出来的以太币——干净的、没人能冻结的以太币。那六千万,就当是交给协议的‘过路费’。”

这是一种冷酷的算术:用一笔随时可能被冻结的钱,换一笔永远不会被冻结的钱,哪怕要亏掉四分之一。

接下来是跨链。

脚本把资金拆成成百上千份,通过不同的跨链桥,从以太坊转到其他公链,再从其他公链转回来,或者转到第三条、第四条链上。每一次跨链,资金都会在一条链上“销毁”或“锁定”,在另一条链上“铸造”或“释放”——在普通的区块浏览器上,这两头之间的联系就断了,分析师必须专门去对齐两条链上的跨链记录,才能把线索重新接上。

在波场(TRON)链上,脚本先给每一个新地址转入一枚 TRX——不多不少,正好一枚。这一枚 TRX 是为了激活地址、支付后续转账的资源费用。几百个新地址,每一个都在同一时间段收到了正好 1 TRX。

“全部用脚本跑,”掌柜说,“人一碰就会出错。”

每一个脚本在完成任务后,都会执行最后一个动作:把自己从服务器上删掉,连同日志、配置和临时文件。行动结束时,他们用过的工具将一件都不剩下。

【陆鸣视角】

凌晨五点,陆鸣已经连续盯了九个小时屏幕。

他的取证平台上,被盗资金的流向被画成了一棵巨大的树:树根是天枢的热钱包,往下分出几十根主枝,再分出成百上千根细枝,一路延伸到十几条公链上。他给每一类地址涂上不同的颜色——红色是直接接收被盗资金的地址,橙色是第一层中转,黄色是跨链桥入口,紫色是可能流向交易所充值地址的终点。

他一边追,一边在一个行业应急群里飞快地发消息。

“USDT 发行方注意:以下地址仍持有被盗稳定币,请评估冻结。”

“各交易所注意:以下地址可能向你们的充值地址转账,请拦截。”

“某某跨链桥团队:你们的合约正在被用于转移被盗资金,请评估暂停。”

群里不断有人回复:“已冻结”“已标记”“已拦截一笔”。每一条“已冻结”,都意味着某笔钱从攻击者的口袋里被抢了回来。

这是一场以分钟计算的拔河。攻击者的脚本在跑,陆鸣和他的同行们在追。他知道,自己追不回所有的钱——那些已经换成 ETH 的资金,没有人能冻结——但每多冻结一个地址,攻击者能带走的就少一分。

天亮时,陆鸣看了一眼统计:在整个行业的协作下,约二十八亿五千万美元的资产被冻结或拦截。

他把这个数字发给了天枢交易所的沈墨。

沈墨只回了两个字:“谢谢。”

【那些看不见的人】

上午九点,吉隆坡的一家奶茶店里,二十四岁的店员阿凯在午休时打开天枢的 App,准备把这个月攒下的八百美元 USDT 提到自己的钱包里,给家里交房租。屏幕上跳出一行红字:“因系统维护,提币功能暂时关闭。”

他刷新了十几次。社交媒体上,“天枢被盗”的话题已经冲上了热搜,有人贴出链上浏览器的截图,有人在喊“快跑”,有人说“交易所要倒了”。他的手开始发抖,八百美元,是他三个月的积蓄。

同一时间,首尔的一位退休教师在电话里问儿子:“我放在里面的养老钱,还在不在?”迪拜的一个量化团队紧急平掉了所有仓位;拉各斯的一个小商户发现,他用来收货款的那条通道断了。

在作战室里,这些人只是监控大屏上一条陡然飙升的“客服工单”曲线。但沈墨知道,那条曲线上的每一个点,都是一个正在失眠的人。

上午十点,天枢发布第一份公告:热钱包遭遇安全事件,冷钱包资产安全,所有用户损失将由交易所全额承担,提币将在安全核查后分批恢复。

阿凯把公告看了三遍,还是不敢相信。直到三天后,他的八百美元 USDT 终于到账,他才在奶茶店的后厨里,长长地吐出一口气。

他永远不会知道林泽、周一航、韩笑这些名字。可他的房租,曾经和他们每个人按下的每一次回车,连在同一条链上。

CHAPTER 08 / 08

第八章

链上的指纹

10 月 31 日,新加坡

陆鸣两天两夜只睡了五个小时。

被盗资金的那棵“树”已经长到了一万多个节点。他把它投在会议室的大屏上,和链镜的几个分析师一起,一根枝一根枝地往下捋。

“这里。”一名年轻分析师突然指着屏幕一角,“这一簇地址,和我们的旧案库撞上了。”

陆鸣凑过去看。在跨链之后的某一层中转里,一部分天枢的被盗资金,流进了几个曾经出现过的地址——这些地址,在几个月前另一起交易所盗窃案、也就是瀚海交易所被盗案中,接收过被盗资金。两笔原本毫不相关的赃款,在同一批地址里汇合、混在了一起。

“混币是想让钱变得无法分辨,”陆鸣说,“但他们犯了一个所有洗钱者都会犯的错误:他们的‘洗衣机’只有那么几台。”

他们继续比对:同样的“1 TRX 激活”习惯,同样的跨链桥偏好,同样的拆分金额规律,同样在每天固定几个时段集中操作。这些特征,和过去几年被公开归因于同一个国家级黑客组织的多起案件,几乎一模一样。

“链上没有指纹,”陆鸣对年轻分析师说,“但人有习惯。习惯就是指纹。”

几天后,美国联邦调查局(FBI)发布声明,将这次攻击正式归因于朝鲜黑客组织 TraderTraitor。链镜等多家分析机构的链上证据,成为这份归因的重要支撑。

11 月 1 日

周一航是在新闻里看到那份初步时间线的。

“九月,一名软件工程师在招聘平台上被冒充的‘项目总监’接触……最终在工作电脑上下载并运行了一个‘面试作业’代码仓库……”

他坐在出租屋的地板上,把那段话看了二十遍。艾米莉的酒窝,那只柯基,大卫说的“你的方案是他见过最好的”。他想起那个周五晚上九点,想起自己对自己说的那句“就跑一下测试,能有什么事”。

那天下午,他敲开了沈墨办公室的门。

“是我。”他说,声音哑得几乎听不清,“九月那个面试,是我。”

沈墨让他坐下,听他从头讲完,然后安静地说:“我们三天前就从你的设备日志里查到了。我一直在等你自己来。”

“我会被开除吗?会被起诉吗?”

“调查结束前,你的权限会被暂停,这是程序。”沈墨看着他,“但我想让你知道一件事:今年我们拦下了五十七次这样的攻击。五十七次。对方是一个国家级的团队,每年花在一个目标上的时间和钱,比很多创业公司的全部预算都多。他们准备了几年的社交账号,零日漏洞,量身定做的仓库……你不是笨,你是被一支军队盯上了。”

她顿了顿。

“真正的问题不在你按下的那一个回车,而在于我们的系统允许一个回车就造成这么大的后果。那个 AI 助手的权限、那个九十天的令牌、那个只认‘内部请求’的签名服务——这些是我的责任。”

周一航低下头,眼泪终于掉了下来。

11 月 3 日

天枢交易所发布了初步调查报告。

报告用平实的语言,把从六月到十月底的每一个环节都摊开在阳光下:那个被篡改的 Homebrew 安装包,那场假面试,那个替换开发工具组件的零日恶意软件,那个被滥用的内部 AI 工具,那个权限过大的部署令牌,那个被直接调用的签名服务,那五十笔 EIP-7702 相关交易,以及那个在 MPC 架构下不得不临时搭建的撤销流程。

报告里也写明了几件事:没有任何私钥泄露;约二十八亿五千万美元已被冻结;所有用户损失由交易所全额承担,用户资产不受影响。

报告发布后的第一个小时,天枢的提币量是平时的六倍。很多用户在社交媒体上说:“钱是赔了,可我不敢再放在这里了。”也有人说:“愿意把这么丑的细节全写出来的交易所,我反而更信它。”

林泽在报告发布那天,给全公司写了一封信。信里他第一次公开讲了六月那个凌晨一点的“赞助”链接。信的最后一段是:

“我曾经以为安全是安全团队的事。现在我知道,每个人复制粘贴的每一行命令,都是这家公司的城墙。”

韩笑重新领到了一台电脑。她做的第一件事,是在工位上贴了一张便签:“小枢来体检之前,先问一句:谁派它来的?”

同一天,某个没有窗户的房间

掌柜看着屏幕上那份报告的译文,一字一句地读完。

行动的工具已经全部自毁,服务器已经被清空,参与行动的几百个地址里,有一部分钱已经变成了谁也冻结不了的以太币,正在慢慢流向他们熟悉的出口。按照他们的标准,这是一次巨大的成功。

可他注意到报告里的一句话:“我们将为所有签名请求引入独立的策略引擎,并在签名节点内部强制执行。”

他知道这意味着什么。下一次,同样的路走不通了。

他关掉报告,打开那张关系图。图上,天枢交易所的那一片已经变成了灰色。他滚动鼠标,屏幕上浮现出一张新的图,中心是另一家交易所的名字,名字周围,同样延伸出十几条线,每一个名字旁边,都标注着招聘平台上的状态——

“开放机会”。

尾声

在这场劫案里,没有人看见过一把私钥,也没有人破解过一行密码学。

黑客们做的,是一件古老得多的事情:他们找到了人,取得了信任,借用了权限,然后让一台本来值得信赖的机器,替他们签下了自己的名字。

区块链会永远记住这一夜发生的每一笔交易。而我们能做的,是让下一次,这本账本上少写几行。

APPENDIX

附录

别成为下一个缺口:给开发者与团队的实用防御清单

下面这份清单,对应小说里每一个被攻破的环节。你不需要全部做到,但每多做一条,攻击者就要多走一段路。

一、个人开发者:守住你的那台电脑

  1. 只从官方来源安装软件。 手动输入官网地址,不点搜索广告;安装命令从官方文档或官方仓库复制;对“一行命令安装”的脚本,先下载、先阅读、再执行。(对应第一章)
  2. 陌生代码一律进“隔离区”。 面试作业、陌生人发来的仓库、来路不明的示例项目,只在一次性虚拟机、云端开发环境或隔离容器里打开,绝不在工作电脑或存有钱包的电脑上运行。(对应第二、三章)
  3. 警惕安装钩子。 安装不信任项目的依赖时,禁用安装脚本(例如 npm 的 --ignore-scripts);锁定依赖版本,使用 lockfile;定期用依赖审计工具扫描。
  4. 工作设备与个人设备彻底分开。 不在工作电脑上找工作、做面试题、装私人插件;不在个人电脑上登录公司系统。
  5. 用硬件安全密钥代替短信和普通验证码。 支持 FIDO2/WebAuthn 的硬件密钥,能有效抵御钓鱼网站窃取登录凭证。
  6. 对“好得不真实”的机会保持怀疑。 薪资高出市场一大截、流程迅速转到私人聊天软件、催促你“今晚就跑一下”——这些都是信号。通过对方公司官网公布的渠道反向核实招聘者身份。
  7. 浏览器扩展做减法。 只装必要的、来自官方商店且评价可靠的扩展,定期清理;钱包所在的浏览器配置文件不装任何多余扩展。
  8. 个人钱包签名前看清内容。 遇到“授权”“委托”“升级账户(EIP-7702)”“无限额度批准”之类请求,确认目标合约来自可信的官方钱包,看不懂就不签。

二、团队与企业:让一个错误不会变成一场灾难

  1. 最小权限原则。 每个人、每个服务、每个 AI 工具,只拥有完成当前任务所需的最小权限。生产部署权限按需申请、用完即收。(对应第四章)
  2. 短期令牌 + 设备绑定。 用几十分钟到几小时有效的短期凭证取代长期令牌;令牌与设备、硬件密钥绑定;禁止在开发机上明文保存生产凭证。
  3. 把 AI 助手和自动化工具当作“员工”来管理。 它们需要独立身份、权限边界、操作审批与完整审计日志;“在同事电脑上执行任务”这类能力,必须由被执行方确认或多人审批。
  4. 网络分段与零信任。 办公网络与生产网络隔离;“来自内部”不等于“可信”,每一次访问都要验证身份、设备和上下文。
  5. 签名服务前必须有独立的策略引擎。 在签名节点内部强制校验:金额上限、频率限制、目标地址白名单、审批签名链、交易类型;任何未经过标准提币流程的请求一律拒绝并触发最高级告警。(对应第五章)
  6. 把 EIP-7702 授权等新型交易列为最高风险类型。 默认禁止热钱包签署委托授权,或仅允许签向经审计的白名单合约。(对应第六章)
  7. 热钱包严格限额,冷热分层。 热钱包只放“够用”的资金,按资产、按链设置余额上限,并配合自动补充与异常熔断。
  8. 为 MPC 钱包准备并演练“紧急预案”。 包括紧急暂停、紧急撤销授权、紧急迁移资产的独立流程(Break-glass Runbook),定期实战演练,不要等出事时才开始写。
  9. 终端检测要看“行为”,不只看“身份”。 已签名的开发工具突然读取浏览器凭证、频繁访问陌生域名、修改其他程序组件,都应告警。
  10. 提前建立行业应急联络网。 与稳定币发行方、主要交易所、跨链桥团队、链上取证公司建立分钟级联络通道,准备好冻结请求模板与法律授权流程。(对应第七章)
  11. 定期做“假面试”钓鱼演练与安全培训。 让员工知道这类攻击长什么样,并营造“主动上报不追责”的文化——越早上报,损失越小。(对应第八章)
  12. 事后透明复盘。 公开、诚实的事故报告,既能帮助整个行业学习,也是重建用户信任的最好方式。

三、一句话总结

攻击者不需要偷走你的钥匙,只需要让你的系统替他签名。 所以,防御的核心不是“把钥匙藏得更深”,而是:让每一次签名,都必须经过一个攻击者绕不过去的检查。

(全书完)