array(5) { ["chapterid"]=> string(8) "49409198" ["articleid"]=> string(7) "7300050" ["chaptername"]=> string(7) "第5章" ["content"]=> string(7090) "端口镜像上线三天了。

林墨把实验室靠窗的工位改造成了一个临时监控台——两台显示器并排,左边跑Wireshark的实时抓包界面,右边是苏晚晴改过的检测脚本输出窗口。左边的画面像一锅煮沸的粥,蓝的灰的绿的数据包密密麻麻往上翻,你盯着看久了会产生一种错觉,觉得那些颜色是有意义的,像能读出什么来似的。其实读不出来。右边就好多了——大部分时候是空的,偶尔跳出一行红色标记,那就是被识别为异常的请求。

三天下来,异常请求一共四十七条。

林墨把四十七条请求导出到表格里,按时间排列。规律比他预想的更明显:所有请求都出现在凌晨一点十五分到两点四十分之间,间隔不固定,但每次会话持续时间都在八到十二分钟。准时来,准时走。

"他在跑自动化脚本。"苏晚晴站在他身后,看着表格说。

她今天穿了一件白衬衫,袖子卷到手肘,左腕上戴着一块卡西欧的电子表——最便宜的那种,塑料表带,没有智能功能。林墨注意到她从来不带手机进实验室,那块表是她唯一的时间工具。他问过一次为什么,苏晚晴说"手机会分心",语气就像在说"水是湿的"一样理所当然。

"自动化的特征很明显。"林墨点头,"每次会话的请求间隔误差在正负两百毫秒以内,人工操作做不到这么稳定。但脚本逻辑不复杂——他在用debug接口做条件查询,每次拉取不同院系的成绩数据。"

"他在找什么?"

"不是成绩本身。"林墨把表格拉到最右边——那是他自己加的分析字段,标注了每次请求查询的院系范围,"你看,他查了计算机学院、软件学院、网络安全学院、信息管理学院。四个学院,两届学生。但他没有查任何一门课的全部成绩——他查的是特定学号段。"

苏晚晴凑近屏幕,目光快速扫过学号段列表。

"这些学号段……都是2023级和2024级的。"

"对。"

七月的教学楼空调开得不情不愿——学校规定室外温度超过三十二度才开中央空调,今天预报三十一度,差一度。实验室的窗户开了条缝,外面传来零星的蝉鸣和远处篮球场的拍球声。暑期留校的学生不多,大部分实验室空着,走廊里偶尔走过一个穿拖鞋的人,踢踏踢踏的,像是在跟地砖较劲。

苏晚晴直起身。"他不是在查成绩高低,他是在做学号关联——把不同课程的选课记录交叉比对,还原学生的选课行为模式。"

"你选什么课,能暴露你很多信息。"林墨说,"你的专业方向、你的兴趣偏好、你跟谁选了同一门课、你有没有在辅修第二专业。这些信息拼起来,可以画出一个人的社交关系图。"

"他在做目标筛选。"苏晚晴说这话的时候语速没变,但林墨听出了其中的分量——她不是在问,是在确认。"他不是要改成绩。他是在用成绩系统作为数据源,筛选出特定特征的学生。"

"然后对筛选出来的目标做下一步动作。"

"下一步是什么?"

"不知道。"林墨靠回椅背。椅子的气压杆早就漏气了,他坐下去的时候会往下沉两厘米,站起来的时候又弹回来,发出一声像是叹气的闷响。他盯着屏幕上仍然在滚动的数据流。"但他花了至少三周时间在做数据收集,说明筛选目标对他来说很重要。重要到愿意冒着被发现的风险,持续访问教务系统。"

苏晚晴没有接话。她走到窗边,看了一眼外面——工科楼后面那排梧桐树叶子晒得打了卷,地上的影子缩成一小团。七月的苏州像个蒸笼,不是热,是闷,空气里有股黏糊糊的水汽,让你觉得自己在慢慢被煮熟。

"我去买杯水。"她说,"你要什么?"

"冰美式。便利店那种。"

"你喝了三年便利店咖啡,不腻?"

"习惯了。"

苏晚晴没有评价。她走出实验室的时候顺手把门带上了,走廊里的声控灯被她的脚步触发,亮了一串,又在她走远后逐一熄灭。

林墨一个人对着两台显示器。左边Wireshark的画面仍然在翻滚,右边检测脚本的状态栏绿得让人安心。他拿起桌上张浩留下的半瓶矿泉水——没盖盖子,不知道放了几天——闻了一下,没异味,喝了一口。

然后他注意到一个之前忽略的细节。

四十七条请求里,有三条的HTTP头部多了一个字段。不是debug参数,是另一个东西:

`X-Trace-ID: ZDP-XXXX`

XXXX是四位数字,每次不一样。ZDP-0231、ZDP-0419、ZDP-0387。

三天前在电缆层那台迷你主机的机箱上,他用手机拍过一组蚀刻字迹——ZDP-0451。

他把三条请求单独拎出来,放在屏幕中央。三个不同的Trace-ID,但前缀完全一致。他试着把四十七条请求重新过滤了一遍,只看带X-Trace-ID字段的——十一条。全部出现在凌晨时段,全部指向不同学号段。

十一次查询。如果每次覆盖五十到一百人的学号段,他筛选了至少五百到一千名学生。

苏晚晴推门回来,手里拎了两瓶水——不是咖啡,是冰的。她把一瓶放在林墨桌上,瓶身上凝着水珠,在桌面上留下一圈印子。

"我不喝冰水。"林墨说。

"今天三十一度,你喝。"

林墨拧开瓶盖喝了一口。冰水从嗓子下去的时候他打了个哆嗦——不是冷,是不习惯。他平时只喝两种温度的水:常温和咖啡。

"你看到那三条请求了?"苏晚晴站在他身后问。

"看到了。ZDP。"

"跟电缆层那台机器上的一样。"

"一样。"

苏晚晴拉了一把椅子坐到他旁边,把笔记本电脑打开,调出自己昨天做的OSINT检索记录。"我昨晚顺着ZDP这个关键词查了一圈——暗网论坛、安全社区、技术博客,什么都没找到。这个词在公开互联网上没有任何技术含义。它不是什么已知协议的缩写,不是哪个安全工具的代号。"

"一个生造的标识。"

"对。一个只在这个体系内部使用的标识。"

林墨没有说话。他转回屏幕,把检测脚本的过滤规则调了一下——在原有的debug参数检测之外,加了一条新规则:匹配所有包含X-Trace-ID字段且前缀为ZDP的HTTP请求。规则保存,脚本重新开始扫描历史流量。

三秒后,右边屏幕跳出十一条红色标记。

跟手动筛出来的一模一样。但脚本比人快——他花十分钟才看完的流量,脚本用了三秒。

"从现在起,自动监控。"林墨说,"只要ZDP前缀的请求再出现,脚本会实时告警。"

"告警发给谁?"

"你和我。"

苏晚晴点了点头,把手机拿出来,在脚本的后台配置里加了自己的接收号码。她做这件事的时候很自然,就像在食堂刷校园卡一样——不需要思考,手指自己知道该按哪里。" ["create_time"]=> string(10) "1785963689" }