(26)
再醒来的时候,闹钟还没响。窗外的天是灰白色的,分不清是几点。她摸到手机看了一眼——六点十分。比平时早了十分钟。她躺着没动,盯着天花板。那块水渍淡了一些,从夏天趴到现在,一动不动。她看了一会儿,然后坐起来,去洗漱。
周一、周二、周三,三天过得像同一天。早上热粥——现在她已经不会煮糊了,锅底抹一层油,火开到最小,粥煮二十分钟,刚好稠,不糊也不稀。放学回来写作业,写完作业看王知行给的U盘里的资料。钓鱼页面的模板她改了几个,换了不同的样式,有的做成银行登录页,有的做成邮箱登录页。她没真的发出去,只是在本地的虚拟机里测试,看着那些假的登录框在浏览器里加载出来,觉得有点像真的,又觉得哪里不对劲。
周三晚上,她给薄荷换了盆。陶土盆在阳台纸箱里放了一周,终于拆开了。她把薄荷从旧盆里倒出来,看见根已经长满了,白花花的,缠成一团。她按照网上看的教程,在新盆底铺了一层陶粒,加了一层土,把薄荷放进去,再填土,压实,浇水。水从盆底渗出来,滴在阳台的地砖上,她用抹布擦干净。薄荷站在新盆里,叶子还在垂着,但看起来精神了一点。她摸了摸叶子,指尖留下一股清凉的香味。
她给林听夏发了一张照片:“给薄荷换盆了。”
林听夏回:“好看。”
就两个字。雨晴盯着那两个字看了几秒,把手机放下,去洗漱。
周四。下午第三节课下课铃响的时候,雨晴已经在收拾书包了。刘心怡从旁边探过头来:“又去社团?”雨晴嗯了一声。“你最近去得挺勤的,”刘心怡说,“是不是有喜欢的人了?”雨晴愣了一下,手里的笔记本差点掉地上。“没有。”“那你急什么?”雨晴没回答,把书包拉链拉上,站起来走了。
走到门口的时候,刘心怡在后面喊了一句:“开玩笑的!别跑那么快!”
实验楼三楼,机房。门开着,键盘声噼里啪啦地响。雨晴走进去的时候,苏晚已经在老位置上了——最后一排靠窗,短头发,红色发卡别在刘海上。她今天穿了一件白色的卫衣,袖子卷到小臂,手腕上还是那块电子表。她面前开着两台显示器,左边是代码,右边是浏览器,正在飞快地敲键盘,手指在键帽上跳得很快,像在弹一首节奏很快的曲子。
雨晴在第二排靠过道的位置坐下。电脑已经开了,桌面还是那张深蓝色的星空图。她把笔记本放在旁边,打开终端,准备先把上次没看完的教程继续看。
“三文鱼大佬来了!”宋辞从第三排探过身子来,手里拿着一袋**虾条,嚼得咔嚓咔嚓响,“今天社长说要讲CSRF,你听过没?”
“没有。”雨晴说。
“我也没听过,”宋辞把虾条咽下去,压低了声音,“听说挺难的,我上次就没听懂。”
前排的陈思远没有回头,但雨晴看见他的手指在键盘上停了一下,然后继续敲。
刘景行站在前面,敲了敲白板。白板上已经写了几个字:CSRF——跨站请求伪造。下面画了几个箭头,指向“原理”“危害”“防御”。他今天穿了一件格子衬衫,眼镜片有点反光,看不清眼睛。
“CSRF,”他推了推眼镜,“Cross-Site Request Forgery,跨站请求伪造。简单说,就是攻击者让用户在不知情的情况下,执行一个不是用户本意的操作。”
他在白板上画了一个图。左边一个用户,中间一个网站,右边一个攻击者。箭头绕来绕去,雨晴盯着看了一会儿,觉得有点像地铁线路图,但又不太一样。
“举个例子,”刘景行转过身来,“你登录了银行网站,没有退出。这时候你点开了一个钓鱼页面,那个页面里藏着一行代码,会向银行网站发起转账请求。因为你的浏览器还带着登录状态,银行网站以为是你本人操作的,就把钱转走了。”
机房安静了。宋辞不嚼虾条了,周小茉抬起头来,牙套在灯光下闪了一下。苏晚的手指也停了,靠在椅背上,看着白板。
“听懂了吗?”刘景行问。
没人说话。雨晴低头在笔记本上写了几个字——“CSRF,利用登录状态,伪造请求”。她写的时候,苏晚从后排走过来,搬着椅子在她旁边坐下,动作很自然,像是本来就应该坐在这里。
“他讲的太干了,”苏晚小声说,声音压得很低,只有雨晴听得见,“其实就是——你在A网站没退出,又去了B网站,B网站偷偷让A网站帮你做了一件事。比如发帖、改密码、转账。”
雨晴点了一下头。苏晚这么一说,她好像明白了一点。
刘景行又讲了几分钟,讲防御方法——Token验证、SameSite属性、Referer检查。雨晴听不太懂后面那些,但她把关键词都记了下来。苏晚在旁边偶尔补充一句,有时候是解释术语,有时候是吐槽——“这个Token其实也不是百分百安全”“SameSite新版浏览器才支持”。雨晴点一下头,继续写。
讲完之后,刘景行让大家自己练习。机房里的键盘声又响起来了,噼里啪啦的,像下雨。雨晴打开浏览器,搜了一下CSRF的靶场,找到一个简单的练习环境。她按照教程一步一步操作,搭了一个测试页面,试着发了一个伪造请求。第一次没成功,第二次也没成功。她盯着屏幕上的报错信息,红色的字,一行一行的,有点刺眼。
“状态码403,”苏晚探过头来看了一眼,“可能是Token验证。你翻一下返回的HTML,看看有没有隐藏字段。”
雨晴按她说的,打开了页面源代码,搜索“csrf”和“token”,果然找到了一个隐藏的input框,里面有一长串字符。她把那个字符复制出来,加到了伪造请求的参数里,再发一次。这次成功了。页面上显示“修改成功”四个字,绿色的,小小的,在白色的背景上很不起眼。
“可以啊。”苏晚说。
雨晴靠在椅背上,呼出一口气。
活动快结束的时候,周小茉走过来,手里拿着笔记本,上面写了几行代码。她短头发,戴牙套,说话的时候嘴唇动得很小心,像是怕牙套刮到嘴。“雨晴,你帮我看一下这个表单提交,为什么数据收不到?”
雨晴看了一眼。周小茉写的是一个简单的登录表单,method是POST,action指向一个PHP文件。她检查了一下,发现action的路径写错了——少了一个斜杠。
“这里,”雨晴指了指屏幕,“应该是/upload/,不是upload。”
周小茉改了,再试一次。页面跳转了,显示“提交成功”。她笑了一下,牙套露出来,银色的,在灯光下闪了一下。“谢谢雨晴!”
“没事。”
宋辞从旁边路过,嘴里还嚼着什么,含混不清地说:“三文鱼大佬又帮人了。”雨晴没理他,把笔记本合上,塞进书包里。
放学的时候,天还亮着。秋天天黑得早,但今天阳光好,傍晚的光是金黄色的,从西边的窗户照进来,把整条走廊染成暖色调。雨晴和苏晚一起走出校门,梧桐树的影子投在地上,一道一道的,像斑马线。
“周末有空吗?”苏晚忽然问。
雨晴想了想。周六没什么事,周日也没什么事。林听夏不在,公寓里只有薄荷陪她。
“有空。”
“来我家玩吧,”苏晚说,语气很随意,像是邀请一个认识了很久的朋友,“我妈做饭很好吃。”
雨晴犹豫了一下。她不太习惯去别人家。以前在郑州的时候——不是现在住的那个家,是更早之前,和爸妈一起住的那个家——她几乎不去同学家,也不带同学来自己家。她不知道别人家的客厅是什么味道的,不知道别人家的饭桌是什么样的,不知道坐在别人家的沙发上应该说些什么。
“好。”她说。
苏晚笑了,嘴角翘起来,红色发卡在夕阳里闪了一下。“周六中午?我让我妈多做点。”
“好。”
周六,雨晴起得比平时早。她站在衣柜前挑了一会儿衣服,最后穿了那件浅蓝色的T恤——林听夏买的那件,优衣库的,领口有点大,但颜色很衬她的皮肤。她把头发梳了一下,刘海还是有点长,快要遮住眼睛,她用两个黑色的小发卡别了一下,露出额头。对着镜子看了看,觉得有点奇怪,又把发卡取下来了。
出门的时候,她给林听夏发消息:“姐姐,今天去苏晚家。”
林听夏回了一个字:“好。”
苏晚家在老城区,从地铁站出来走十分钟,穿过一条种满梧桐树的街道,拐进一个小区。小区不大,楼是六层的,没有电梯,外墙刷着米黄色的漆,有些地方掉了,露出底下灰色的水泥。苏晚家在四楼,雨晴爬上去的时候有点喘。
门开了。苏晚站在门口,穿着一件粉色的卫衣,头发散着,没有戴发卡。她看见雨晴,笑了一下:“进来吧。”
雨晴换了鞋,走进去。客厅不大,但很亮。阳光从南边的窗户照进来,落在沙发上,把沙发布罩上的碎花照得很清楚。电视柜上摆着一排照片,有苏晚小时候的,有她爸妈的,有一张全家福,三个人站在一个公园门口,苏晚扎着两个小辫子,笑得眼睛眯成一条缝。阳台上养了很多花——月季、绿萝、还有一盆开着小黄花的不知道什么名字。空气里有淡淡的饭菜香味,混着一点点洗衣液的味道。
“妈!我同学来了!”苏晚朝厨房喊了一声。
一个女人从厨房探出头来。她穿着一条深蓝色的围裙,头发盘起来,脸圆圆的,和苏晚长得很像。她看见雨晴,笑了,那种笑很暖,不是客气的,是真的高兴。
“你就是雨晴吧?苏晚老提起你。快去坐,饭马上好。”
雨晴说了声“阿姨好”,声音不大,但苏晚的妈妈听见了,又笑了一下,缩回厨房里去了。
苏晚拉着雨晴去她房间。房间不大,一张单人床,一张书桌,一个衣柜。书架上全是计算机书——《Web安全深度剖析》《白帽子讲Web安全》《JavaScript高级程序设计》——还有一些小说,东野圭吾的、村上春树的,塞在书架最下面一层。墙上贴着一张代码海报,是Python的装饰器语法,雨晴看不懂,但觉得挺好看的。
“你书架上的书你都看完了?”雨晴问。
“大部分吧,”苏晚坐在床上,抱起一个靠枕,“有些太深的没看完。”
雨晴站在书架前,抽出一本《白帽子讲Web安全》,翻了几页。里面有很多代码示例,有些她认识,有些完全不认识。她把书放回去,坐在书桌前的椅子上。椅子上放着一个坐垫,蓝色的,有点旧,但很干净。
“你一个人住?”苏晚忽然问。
雨晴愣了一下。“不是,我姐……她在郑州大学,周末回来。”她不知道自己为什么要说“周末回来”,林听夏明明不在。也许是因为习惯,也许是因为她不想解释太多。
“哦,”苏晚没追问,“你姐对你好吗?”
“嗯。”
“那就好。”
外面传来苏晚妈妈的声音:“吃饭了!”
苏晚站起来,拉着雨晴去客厅。桌上已经摆满了菜——红烧排骨、糖醋鱼、炒青菜、西红柿蛋汤,还有一碟凉拌黄瓜。苏晚的爸爸坐在桌边,已经盛好了饭,看见雨晴,点了一下头,没说话。他话不多,脸上有皱纹,头发有点白了,但眼睛很亮。
“坐坐坐,”苏晚的妈妈端着一碗汤走出来,把碗放在桌上,“多吃点,别客气。”
雨晴坐下来,拿起筷子。苏晚的妈妈给她夹了一块排骨,又夹了一块鱼,又夹了一筷子青菜。雨晴碗里的菜堆得像小山一样,她说了好几声“够了够了”,苏晚的妈妈还是继续夹。
“妈,你让她自己吃!”苏晚说。
“我这不是怕人家不好意思嘛。”
“她又不是外人。”
雨晴低头吃饭。排骨烧得很烂,筷子一夹就脱骨了,酱汁是甜的,咸的,混在一起,刚刚好。糖醋鱼的皮炸得脆脆的,浇了糖醋汁,酸酸甜甜的,鱼肉很嫩。她吃了一口,又吃了一口。
“好吃吗?”苏晚的妈妈问。
“好吃。”雨晴说。她是真心的。
苏晚和妈妈为了一个碗谁洗拌嘴。苏晚说“我来洗”,妈妈说“你洗不干净”,苏晚说“我怎么洗不干净了”,妈妈说“上次那个碗你洗了三遍还有油”。两个人你一句我一句,吵得很热闹,但不是真的吵架,吵着吵着就笑了。苏晚的爸爸在旁边不说话,但嘴角一直翘着。
雨晴看着她们,忽然有点羡慕。她想起自己在家的时候——不是林听夏的那个家,是巩义的那个家。饭桌上很少有人说笑,妈妈不说话,爸爸也不说话,有时候整顿饭都没有人开口,只有筷子碰碗的声音。她不知道原来吃饭可以这么吵,吵得这么开心。
苏晚的爸爸忽然夹了一筷子菜放到雨晴碗里,没说话,只是看了她一眼。雨晴说了声“谢谢叔叔”,他点了一下头,继续吃自己的。
吃完饭,苏晚真的去洗碗了。雨晴想帮忙,苏晚说“你是客人,坐着”。雨晴就坐在沙发上,看着苏晚在厨房里忙活。水龙头哗哗地响,苏晚低着头,一个一个地洗,泡沫从指缝里流下去。她洗得很认真,每一个碗都转着圈地冲,冲完了放在碗架上,码得整整齐齐。
洗完碗,苏晚擦干手,走过来:“走,去我房间,给你看个电影。”
“什么电影?”
“黑客题材的,很老的片子,但经典。”
她们坐在床上,苏晚把笔记本电脑放在腿上,打开了一个视频网站。电影开始放,画面是那种老电影的质感,颜色偏黄,分辨率不高。讲的是一个黑客被卷入了一场阴谋,用技术对抗系统。苏晚边看边吐槽——“这个漏洞根本不合理”“这个弹窗太假了”“他敲键盘的速度也太夸张了”。
雨晴看着屏幕,偶尔笑一下。不是那种礼貌的笑,是真的觉得好笑的笑。苏晚吐槽的时候声音很大,表情很夸张,雨晴看着她的侧脸,觉得这个人好像什么都能说,什么都能笑,什么都不怕。
“你笑什么?”苏晚忽然转头看她。
“没什么。”雨晴把目光移回屏幕。
电影放到一半,苏晚忽然按了暂停。“你姐什么时候回来?”她问,语气很随意,像是随口一问。
雨晴愣了一下。“快了。”
苏晚看了她一眼。那个眼神很短,短到雨晴不确定她是不是在看自己。然后苏晚按了播放键,电影继续。
雨晴靠在床头上,看着屏幕。她不知道苏晚为什么问这个,也不知道苏晚有没有信她说的话。她说了“快了”,但“快了”是多久,她自己也不知道。林听夏只说“快了”,没说具体的时间。也许是一周,也许是一个月,也许是更久。
电影放完了。字幕从屏幕下方升上来,一行一行的,白色的,在黑色的背景上慢慢往上移。苏晚伸了个懒腰,说“结局有点扯,但还行”。雨晴嗯了一声,从床上下来,把鞋子穿好。
“我该走了。”她说。
“我送你。”
苏晚送她到公交站。站台上有几个等车的人,有人在看手机,有人在抽烟,有人拎着菜篮子,里面装着刚买的菜。天快黑了,夕阳从西边照过来,把苏晚的红色发卡照得发亮。
“下周社团见。”苏晚说。
“嗯。”
公交车来了。雨晴上车,刷了卡,找了个靠窗的位置坐下。车开起来的时候,她回头看了一下——苏晚还站在站台上,朝她挥了挥手。她也挥了一下,然后转回头,靠着车窗。
窗外的街景往后退。梧桐树,路灯,行人,电动车,一家一家亮着灯的店铺。她把手机拿出来,给林听夏发消息:“苏晚妈妈做的红烧排骨很好吃。”
这次林听夏回得很快。不到一分钟。
“那我以后也学着做。”
雨晴盯着那行字,嘴角翘了一下。她把手机握在手心里,看着窗外。天越来越暗了,路灯一盏一盏地亮起来,橘黄色的光在车窗上一闪一闪地过去。她想,林听夏说“以后”。以后是多远?她不知道。但“以后”这个词,听起来比“快了”更近。
回到公寓,推开门,房间里很安静。冰箱嗡嗡地响,窗台上的薄荷站在新盆里,叶子还是垂着,但黄叶没有再增多。她走过去,摸了摸叶子,指尖凉凉的,带着那股熟悉的香味。
她走进卧室,躺在床上,抱着林听夏的枕头。拿出手机,把林听夏发的那条消息又看了一遍——“那我以后也学着做。”她把屏幕关掉,放在枕头旁边,闭上眼睛。
脑子里转着今天的事。苏晚家的饭桌,吵吵闹闹的拌嘴,那个夹菜不说一句话的爸爸,那个笑起来很暖的妈妈。还有苏晚问“你姐什么时候回来”时的眼神。她说“快了”。她不知道是不是真的快了。但她想,快了。应该是快了。
她翻了个身,把枕头抱得更紧。
窗外路灯的光从窗帘缝里漏进来,落在地板上,一小块,灰灰的。她盯着那一小块光,慢慢地,眼皮沉了下去。