137
考完试的第一天,雨晴是被手机震醒的。
群里小叶子在问“考完了吗”,消息一条接一条,手机在枕头旁边嗡嗡响。她伸手摸过来看了一眼,九点多。橘子皮不在床上,蹲在窗台上,尾巴垂下来,正在看外面的鸟。雨晴躺了几秒,回了一句“考完了”。小叶子秒发了一个放烟花的动效图。她把手机放下,又躺了几分钟,然后起来。
洗漱的时候对着镜子看了看,头发又长了一点,快到肩膀了。她用手拢了一下,碎发掉下来,没扎。换衣服,白T恤,深蓝色薄卫衣,黑色休闲裤。五月底的郑州,穿卫衣有点热了,但她懒得换。
去厨房热了杯牛奶,站着喝完。橘子皮从窗台上跳下来,走到食盆前蹲着,仰头看她。雨晴过去倒了粮,猫低下头开始吃,吃得吧嗒吧嗒响。
坐到书桌前,打开笔记本。周正平昨天发的消息还挂着:“新项目,区块链的,做不做?报酬八千。”她回了“做”,消息已经发出去了。周正平没再回。她打开邮箱,下载附件。一个APK文件,几十兆,还有一份需求文档。
区块链钱包APP。她看过这个词,但完全不懂。什么是区块链,什么是智能合约,什么是共识机制。脑子里一片空白。她打开浏览器,搜了一下“区块链安全测试”,出来一大堆。挑了篇看起来最基础的,从头开始看。区块、链、哈希、公私钥、去中心化。看到第三段的时候卡住了,有一个概念没看懂。又看了一遍,大概明白了,但不敢确认。
在群里发了一条消息:“有人懂区块链吗?”
深海鱼秒回:“我懂一点。你要做区块链项目?”
“嗯。刚接的。完全不懂。”
“你先看这个教程。”深海鱼发了一个链接。雨晴点开,是某安全团队写的区块链安全入门系列,一共十几篇。她打开第一篇,从头开始看。看到第五篇的时候,橘子皮跳上书桌趴在她面前。她没抬头,继续看。
中午自己煮了碗面,吃完继续。看完了第八篇,大概知道了区块链的基本结构。交易、区块、链、挖矿、共识。概念能说出来,但让她解释细节,还是说不清楚。
下午,深海鱼在群里问她:“看得怎么样了?”
雨晴:“看了八篇。大概知道是什么了。”
深海鱼:“那你先搭环境。用这个测试链。”又发了一个链接。雨晴点开,是某测试链的文档。注册账号,下载客户端,同步节点。同步了两个小时还没好,她看了一下进度,百分之三十。关了电脑,去厨房做饭。
晚上林听夏没来,说店里忙。雨晴一个人吃了饭,洗完碗,坐回书桌前。节点同步完了。她开始按照文档的步骤,创建钱包地址,生成公私钥。在测试链上领了一些测试币。然后开始测APP。
先用Burp抓包,看数据传输。请求和响应都是加密的,解不开。她在群里问深海鱼:“区块链APP的流量怎么测?”
深海鱼:“很多用的是WebSocket,不是HTTP。你看看是不是。”
雨晴看了一下抓包记录,果然是WebSocket。她配置Burp支持WebSocket,重新抓。这次能看到请求内容了。但数据还是加密的,看不懂。换了个思路,从客户端入手。解压APK,看代码。代码混淆过了,变量名都是abcd,很难读。花了半小时,找到了网络请求的关键代码。加密方式用了AES,密钥硬编码在代码里。她把密钥复制出来,解密了一段请求,看到了明文参数。
开始测业务逻辑。创建钱包、转账、查询余额。测转账功能的时候,发现一个问题:没有签名校验。她抓到了转账请求,修改了金额参数,把1改成100,重放,成功了。账户余额增加了100。这是一个严重的漏洞——签名缺失,任何人都可以伪造转账请求。她把测试步骤记录下来,截图。
再测私钥管理。APP把私钥加密存储在本地的SharedPreferences里,加密密钥也是硬编码的。她写了一个小脚本,解密了私钥。拿到了用户的私钥。这意味着如果攻击者拿到手机,可以解密私钥,转走所有资产。又一个高危漏洞。
测到凌晨一点,一共挖了四个漏洞:签名缺失、私钥存储不安全、AES密钥硬编码、WebSocket接口无访问控制。橘子皮早就睡了,在椅子上盘成一团,尾巴盖着鼻子。她站起来伸了个懒腰,去洗了澡。躺在床上,脑子里还在转那些概念——区块、哈希、公私钥。不知道什么时候睡着了。
第二天上午,继续写报告。
把四个漏洞按严重程度排好。最严重的是私钥存储不安全,给了“严重”评级。签名缺失给了“高危”。AES密钥硬编码给了“中危”。WebSocket接口无访问控制给了“中危”。每个漏洞都写了详细描述、复现步骤、截图、修复建议。私钥存储那个,修复建议写了三条:使用Android Keystore系统存储私钥,不要硬编码密钥,启用设备锁定保护。
下午,报告发给周正平。周正平回了一个“收到”。
群里小叶子问:“姐,你那个区块链项目做完了?”雨晴说“还没,等反馈”。小叶子发了一个猫加油的图。深海鱼说:“第一次做区块链,能挖到漏洞就不错了。”雨晴说“挖了四个”。深海鱼发了一个大拇指。洛神说“厉害”。何意味发了一个猫震惊的图。
晚上,雨晴正在吃饭,手机震了。周正平打电话来了。
“报告客户看了,问了你几个问题。”
“什么问题?”
“私钥存储那个,他们问Android Keystore够不够安全。”
“够。比硬编码安全。密钥存在硬件里,提取不出来。”
“行,我跟他们说。还有一个,签名缺失那个,他们问能不能加个简单的签名就能防住。”
“能。HMAC-SHA256就行。密钥放服务端,不要放客户端。”
周正平在电话那头记了一下。“你那个修复建议写得很清楚,他们照着做了。辛苦了。”
挂了电话。雨晴继续吃饭。醋溜土豆丝凉了,有点腻。
周五,成绩出来了。
班主任在班里念了排名。雨晴坐在后排听着。前十名没有她。前十五名——她听到自己的名字,第十二名,总分三百五十二。比上次进步了七分。刘心怡第十三名,三百四十八。
班主任念完之后说:“前三十名的同学下学期进重点班。名单贴在公告栏,自己去看。”
下课的时候,公告栏前挤了一堆人。雨晴没去。刘心怡跑过去看了,跑回来的时候脸上是笑的。
“进了。你十二,我十三。都进了。”
“嗯。”
“你就不能表现出来一点高兴?”刘心怡看着她。
“高兴。”
“你脸上写着‘高兴’两个字吗?”
雨晴嘴角弯了一下。刘心怡看着她那个表情,笑了一下,然后突然伸手抱了她一下。雨晴僵住了,手臂垂着,不知道该放哪。刘心怡很快松开了,退后一步,脸上还挂着笑。
“下学期重点班见。”
“嗯。”
刘心怡转身走了。雨晴站在原地,看着她的背影消失在走廊拐角。她抬起手看了看手腕上的两条手链。小锁和小星星在阳光下闪了一下。
晚上,林听夏来的时候,雨晴正在做饭。醋溜土豆丝,番茄蛋汤,还多炒了一个菜——青椒炒肉。
“今天怎么多炒了一个?”林听夏换了鞋,走到厨房门口。
“考完了。成绩出来了。”
“多少?”
“第十二名。进了重点班。”
林听夏看着她。“恭喜。”
“嗯。”
两个人坐下来吃饭。雨晴吃了几口,说“那个区块链项目做完了”。林听夏问“多少钱”。雨晴说“八千”。林听夏夹了一块土豆。“你存了多少了?”雨晴想了想。“没算过。够用了。”林听夏没再问了。
吃完饭,雨晴洗碗的时候,林听夏站在旁边擦盘子。水龙头哗哗地响。
“你暑假还出差?”林听夏问。
“可能。周总没定。”
“那你暑假不在家?”
“不知道。可能几天。”
林听夏把擦干的盘子放进柜子里。雨晴关掉水龙头,甩了甩手上的水,林听夏递过擦手巾。
“我走了。”
“嗯。”
门关上了。雨晴坐到书桌前,打开笔记本。群里小叶子在问“姐,你那个小程序什么时候发正式版”,雨晴说“这几天”。站长发来一条消息:“清泉,你考得怎么样?”雨晴说“进了重点班”。站长发了一个大拇指。
她打开论坛,把小程序码重新生成了一版,修了几个小bug。在站务版块发了正式版的帖子:“新月港湾医院查询小程序正式版发布。”把小程序码贴上去,写了更新说明。发完之后刷新了一下,帖子下面已经有人回复了。“终于正式了”“谢谢清泉”“辛苦了”。
雨晴看着那些回复,嘴角弯了一下。橘子皮跳上书桌趴在她面前,她摸了摸猫的头。
手机震了。林听夏发来的消息:“到家了。”
雨晴回了一个“嗯”。
她又看了一眼论坛的帖子,有人问“清泉,这个小程序会一直维护吗”,她想了想,回了一个“会”。
关了笔记本。橘子皮还趴在桌上,她把它抱起来放在腿上。猫的体温隔着裤子传过来,暖融融的。
下周就要开始暑假了。