第13章 · 蜜罐
法尔汉把自己关在屏蔽室里三周。不是夸张——是真的三周没有离开那个地下空间超过两小时。沈姐每天把三餐放在门口的铁架上,敲两下门就走。偶尔有人从门缝里看到他蜷在显示器前的背影,屏幕上的代码像瀑布一样滚动,他的头发比三周前长了一截,眼窝深陷得像一个长期藏在隧道里的人。
陆远负责给女儿送饭、喂药、哄睡,然后剩下的时间全部站在屏蔽室的门口。他没有敲门。他只是在等。
第三周的最后一个晚上,门开了。
法尔汉站在门框里,脸上那种陆远从未见过的表情——不是疲惫,不是成功后的兴奋,是一种介于恐惧和困惑之间的、极其陌生的神色。他手里捏着一块移动硬盘的线缆,线在他手指间绕了好几圈,攥得很紧,指节发白。
“你过来看。”他的声音沙哑得像砂纸摩擦木板。
陆远走进屏蔽室。空气里弥漫着一股电子元件长时间高温运行后的焦糊味和法尔汉三周没洗澡的体味。三块显示器并排排列,每块上面都开着密密麻麻的数据窗口——频谱分析、协议栈对比、固件反汇编、形式化验证工具的输出。他逐行扫过去。
然后他看到了那个结论。
法尔汉没有让他猜。他在中间那块屏幕上点开了一个文件,标题栏写着:「漏洞 ML-Core-7 · 形式化验证报告 · 第 47 轮」。报告摘要只有一段话,字体默认大小,没有加粗,没有高亮,像一个最普通的实验结果记录。但陆远读完之后,感到自己的后背正在缓慢地渗出一层冷汗。
摘要:目标代码段(ML-Core-7,固件偏移量 0x7A3F_1C44-0x7A3F_1D8F)在 1,247 项已知攻击模型下全部呈现漏洞特征。进一步分析显示:该代码段与固件中其余部分的编码风格存在系统性差异——变量命名惯例不一致、注释密度与周围代码不匹配、异常处理路径异常完整。综合评估:该代码段不满足自然发生的软件缺陷的统计分布。它是被有意插入的。
法尔汉没有说话。他点开了另一个窗口——一个他在过去三周里搭建的自动化对比工具的输出。工具将”漏洞”代码段与星链固件中其余六千多个模块的编码风格进行了逐项对比,生成了一个可视化的雷达图。在变量命名、注释频率、错误处理完整性、边界条件覆盖等七个维度上,那个漏洞的评分都远远偏离了固件的基线分布——它不是偏离了一点点,是偏离到了另一个物种的程度。
陆远盯着那个雷达图看了很久。他发现自己的大脑在拒绝接受这个结论的含意,但工程直觉已经先于理智完成了判断。
“真正的系统漏洞,”法尔汉的声音从身后传来,像在自言自语,“通常伴随着签名不一致——开发团队换人了,草稿被推翻了,边缘情况被忽略了。它们有指纹。它们不完美。你在固件里找到一个漏洞的时候,你应该能在它周围看到人的痕迹——粗糙的边界处理、被注释掉的调试代码、有两三个未处理的分支。”
他沉默了。
“但这个漏洞——它太干净了。干净得像教科书上的例题。没有未处理的分支。没有遗漏的边界。没有任何一根暴露在外的线头。就像一个老师把一道完美解的题目放在桌上,等着学生来抄。”
陆远终于开口了。他的声音比他预想中要平静:“这不是漏洞。这是一个精心设计的后门。它在等我们走进去。”
法尔汉点了点头。那个点头的动作很轻,但陆远看到他垂在身侧的左手在轻微地颤抖——不是恐惧的颤抖,是一种被验证了最坏的猜测之后,肾上腺素退潮带来的生理性震颤。
“我在最后一轮验证里反查了这个后门的父模块,”法尔汉说,声音在压制某种东西,“它的上层是星链核心网的一个模块——入口-7号协议。它的签名链一直追溯到米兰·沃伊诺维奇的私人开发环境。”
陆远没有接话。屏蔽室里的散热风扇在低声旋转,发出一种均匀的、接近白噪音的嗡鸣。他觉得自己站在一个很深的地方,头顶的重量正在一点一点地增加。
“你——”陆远的话卡了一下,“你确定?”
“米兰的每一个代码提交都有一个独特的编译签名。编译器版本、优化参数、系统时间戳的编码方式——每个人的开发环境都会在二进制文件里留下不可伪造的指纹。”法尔汉在键盘上敲了几个命令,调出一个窗口,“对比了三组样本:一组来自米兰公开的代码提交,一组来自星链固件中其他模块的匿名提交,一组就是这个漏洞的二进制指纹。匹配度 99.8%。”
陆远不再确认了。他坐在法尔汉旁边的椅子上,椅子的一条腿有点短,坐下去的时候轻微地晃了一下。他没有扶稳,任由那个晃动持续了两三秒。
“我们的SkyWalker——从第一天开始就是可追踪的。”他慢慢地说。这不是问句。
“每一次通信,每一次数据包注入,每一条通过QKD侧信道传输的信息——都被标记了。不是内容,内容我们有加密。是连接本身——什么时候连的、从哪颗卫星接人的、数据量多大、路由路径是怎样的——所有这些元数据都被镜像到了米兰的审计系统里。”
法尔汉的声音没有任何感情波动了——那是精神资源被燃烧殆尽之后的一种机械般的平稳。“三周。我们以为自己在黑暗中建了一条秘密通道。实际上我们是在一盏探照灯下面施工。”
屏蔽室安静了很久。头顶的通风管道传来远处服务器机柜的低频轰鸣,像某种被困在地下深处的巨大动物在缓慢地呼吸。
陆远站起来,走到屏蔽室的墙边。铜网覆盖的墙壁摸上去有一种凉丝丝的金属质感,指尖的触感从皮肤一直传到颅骨深处。他把额头贴在铜网上,闭着眼睛站了大概十秒钟。
“有烟吗?”他问。
“我不抽烟。”
“我也不抽。”陆远把额头从铜网上移开,转过身,“但我们可能需要抽一根。”
他们没有烟。陆远从桌上一杯三天前的冷水里捞出一块冰,含在嘴里。冰冷的触感让他的思路清晰了一些。
“继续看日志,”他说,“米兰的设计日志。你才看了开头。”
法尔汉看了他一眼——不是确认的表情,是一种带着某种近似惊讶的重新审视。
“你不想放弃?”
“我女儿的药还能吃二十三天。”陆远说,“二十三天之后,如果SkyWalker不能上线——不管是不是陷阱——她都会断药。陷阱和不是陷阱,对我来说结果是一样的。区别只是我被抓之前她还有没有药。”
法尔汉没有再说话。他转回屏幕,打开了那个被他挂在后台三天的解密任务。
解密程序已经完成了百分之百。窗口底部显示着一行绿色文字:「解密完成 · 输出目录:/home/farhan/analysis/milan_logs/」。
他打开了输出目录。里面大约有三百多个文件——不是完整的日记,是米兰的技术设计日志片段,被法尔汉的匿名联系人从星链内部的版本控制系统的冷存储中泄露出来的。日志时间跨度从2049年到2055年,不是连续的,每隔几周或几个月才有一条。但在那些碎片中,有一个主题在反复出现。
法尔汉按时间排序,从最早的一条开始看起。
2049年3月11日 项目:入口-7号协议。初步架构审查已完成。需求文档中存在一个预期之外的条款:“审计模块应支持对伪造终端连接的自动标记与归因。” 这份需求来自高层,不是技术团队提出的。我没有反对。但我在架构中预留了一个额外的条件分支——它在需求文档中没有对应的条目。记录于此,以备日后核查。
2050年7月28日 入口-7的第一阶段审计实现已提交。核心逻辑:允许未经授权的终端建立连接(这违反了入口-3的认证策略),但所有流量会被标记并镜像到中央审计系统的隔离存储区。预期用途:追踪高级别威胁的源头。设计上——这是一个完美的蜜罐。我不知道将来谁会走进来,但我知道如果他走进来,我就能知道他是谁、从哪里来、想做什么。
2051年12月4日 今天我坐在终端前问了自己一个问题:如果蜜罐里捕获的不是猎物——是猎人呢?
法尔汉的手指在触摸板上停住了。他回头看了一眼陆远。陆远也看到了那个句子,但他没有说话,只是用下巴点了一下屏幕,示意法尔汉继续往下翻。
2052年1月19日 我正在重读自己2049年写的一条注释。那条注释被埋在一个任何人都不会去检查的固件区域——引导加载程序的异常处理分支,系统崩溃时才会执行的代码路径。我写的是:“每一个陷阱都是双向的。” 我不确定自己五年前写这句话的时候在想什么。但今天我重读它的时候,我忽然笑了一下——不是开心的笑——是一种被五年前的自己提醒了的感觉。
2052年3月8日 如果我在审计入口的设计中隐藏一个嵌套入口——一个不被任何审计系统记录的入口——那会怎样?我在问自己这个问题。这不是需求文档里的内容。不是高层授意的。甚至不是我能向任何人解释的。但它在技术上是可行的。入口-7的审计模块需要从核心网的路由表中读取连接日志,写入隔离存储。如果我在”读”的过程中插入一个条件——当某些特定的连接特征出现时——不是写入隔离存储,而是写入另一个地址空间。一个没有被记录在任何路由表中的地址空间。
日志在这里断开了。下一段已经是2052年9月。
2052年9月22日 我做了那个嵌套入口。花了我六十三天。大部分工作是在深夜完成的,在酒店的房间里——我拒绝透露出差时住的是哪家酒店,不想留下任何可以被关联的地点记录。嵌套入口的激活条件是一组特定的QKD信道噪声特征——不是信号内容,是物理层的噪声模式。就像一把锁,钥匙不是数据,是数据诞生之前就已经存在的物理层特征。我不知道我什么时候会用这把钥匙。也许永远不会。 但我把它放在那里了。
法尔汉的呼吸变轻了。
他继续往下翻——后面的日志内容逐渐偏离了技术主题,更多是关于米兰的个人思考。2053年有一条提到了”米娅第一次不接我电话”。2054年有一条只有一句话:“入口-7已经被触发了。不是被我的人。是被一个我没预料到的人。我没有标记它。我不知道自己为什么没有标记它。”
最后一条日志的时间戳是2055年12月。
2055年12月31日 新年夜。贝尔格莱德下雨。我坐在办公室里听雨声。入口-7在过去一年里被触发了四十七次。四十七个不同的人走过了我七年前设计的那扇门。他们没有一个知道那扇门是我留的。他们以为自己很聪明,找到了星链的漏洞——但他们找到的是我放在那里等他们找到的东西。 但是—— 这四十七次触发中,有一次不一样。有一个终端在触发入口-7之后没有按照预期的路径走。它的连接模式不是偷流量,不是破解账号——它在读取QKD信道的元数据。它在学习星链的噪声特征。 它在我设计的陷阱旁边挖了一条小隧道。 我不知道是谁。但我想知道。
日志到此结束。没有后续。
法尔汉靠在椅背上,三块显示器的蓝光映在他的脸上。他的眼白布满了血丝,嘴唇干裂,整个人看起来像是刚从一场漫长的溺水中被捞出来。但他的瞳孔里有一种光——不是兴奋,是一种极其复杂的、混合了恐惧和希望的东西。
“这个疯子——”法尔汉的声音嘶哑得几乎听不清,“他在自己的蜜罐下面藏了另一个入口。一个连星链审计系统都不知道的入口。他可能没有告诉任何人。他甚至可能不确定自己要不要用它——但他把它放在那里了。”
陆远站在屏幕前,把那几段日志在脑子里又重新过了一遍。他的思维正在以他能感觉到的方式升温——那些碎片正在被拼成一个图像,一个他不敢相信但又无法否认的图像。
“米兰故意留下了信号指纹克隆的漏洞,让法尔汉找到。然后他在法尔汉必然会发现的入口-7协议里设计了一个蜜罐——一个完美的陷阱。但他又在蜜罐的底层藏了另一个门——一个他不记录在任何文档中、不告诉任何人的门。”
陆远说着,声音越来越慢,像在走一条自己都不太相信的路。
“他在日志里写的那个嵌套入口——激活条件是QKD信道噪声特征。那不是普通的噪声特征。那是未来的SkyWalker协议的特征。”
法尔汉转过头来看着他。两个人的目光在屏蔽室黯淡的光线下相遇。
“米兰在等他自己的陷阱被人发现,”陆远说,“然后他在等发现陷阱的人聪明到能继续往下挖。”
“他是一个把自己的陷阱设计成路标的人。”
他们都沉默了。
屏蔽室里的沉默持续了大概二十秒。然后法尔汉发出一声很轻的笑——不是开心,是一种在极度疲惫中终于看到了一点东西的、近乎神经质的笑。
“你知道吗,”他说,“我花了三年时间逆向星链的固件,两年时间发现入口-7,三周时间确认它是个陷阱。我以为我已经输了。”
他转向屏幕,光标在终端窗口里闪烁。
“但如果米兰在陷阱下面还藏了另一层——如果那些日志是真的——那我们还没有全输。”
“也许米兰——他想要有人赢。”
贝尔格莱德,同一时刻。
米兰坐在办公室的终端前,没有开主灯。房间的照明只来自三块屏幕的背景光,在墙壁上投射出模糊的蓝白色轮廓。窗外多瑙河的对岸亮着稀疏的灯火,雨正在下——不是暴雨,是那种不急不慢的、能连续下好几天的欧洲秋雨,打在窗户玻璃上发出细密而均匀的声音。
他已经坐在这里三个小时了。
屏幕上的数据显示着数据党最近的活动模式。法尔汉的SkyWalker测试信号——那些隐藏在QKD信道元数据中的空洞——出现在他的审计系统中,被标记、被分类、被归档。一切都在按照陷阱的设计运作。蜜罐在被触发。审计系统在记录。分析算法在绘制目标网络的组织拓扑。
三年前他埋下的那颗种子,正在按照他预期的方式生长。
但他没有关闭那个嵌套入口。
他打开了那个只有他知道的私人目录——一个被隐藏在固件引导程序异常处理分支中的、没有记录在任何设计文档中的地址空间。目录的访问日志显示:上一次被访问是三十四个月前,他自己在深夜调试时打开的。之后没有任何人碰过它。
它还在那里。安静。完整。像一把从未被使用过的钥匙,被人藏在一块松动的砖头后面。
米兰把手指放在键盘上,没有敲下去。
他在想什么?他自己也不太确定。
他在想陆远——那个中国人。他已经在审计系统中看过他的完整轨迹:从一开始的救女儿信号克隆,到被塞拉斯追捕,到被法尔汉接入数据党,到SkyWalker协议的开发,到拉各斯之行。每一步都在米兰的预料之内——除了一个变量。
那个变量很小,小到几乎可以忽略不计。
但米兰注意到了。
在所有的入侵者中,陆远是唯一一个在看到星链的漏洞之后——没有立刻用来牟利,没有用来传播数据,没有用来证明自己有多聪明——的那个人。他看到了漏洞,然后他修好了自己的手机,说了声谢谢,就走了。
这个细节让米兰无法解释地在意。
他的目光落在屏幕上那个嵌套入口的图标上——一个他从未命名过的、用十六进制代码标记的文件夹。里面有一段他六十三天写出来的代码,一段从未被编译进任何正式固件版本中的代码。他在2052年9月22日凌晨四点写完最后一行,然后锁上了那个目录。
他在等一个能走到这一步的人。
但那个人真的出现的时候,米兰发现自己坐在终端前,手指悬在键盘上方,没有按下任何键。
他的女儿在数据党那边。
他的陷阱正在被触发。
他的嵌套入口在等待被使用。
而他——这个设计了一切的人——忽然不知道自己希望哪一个门被打开。
他站起来,走到窗边。雨还在下,贝尔格莱德老城区的屋顶在雨夜中泛着暗淡的湿光。他想起父亲在1991年冬天走出家门时说的那句话——“确保线是通的。”
他花了三十年建了一条全人类最庞大的线路。
但线路通了吗?他真的连接了任何人吗?
米兰把手掌按在冰冷的玻璃上。雨水在玻璃的另一面流淌,把他的指纹和掌纹模糊成一片。
他走回桌前,没有碰那个嵌套入口。
他打开日记本,拿起钢笔,写了一行字:
2057年9月12日。蜜罐被触发了。三级。他们发现了第一层。现在他们在找第二层。我还没有决定要不要让他们找到。
他合上笔记本。
窗外的雨声越来越大。十二万颗卫星正在他头顶以每秒七公里的速度飞行,在它们内部循环着的代码中,有一小段——一段从未被签入任何版本管理系统的代码——正在以电磁的形式静静地存在于千兆字节的固件中。
像一封从未被寄出的信,被夹在一本没人读的书里。
米兰关掉了屏幕。
黑暗里,他坐在办公椅上,没有动。
他在等。
等明天。