有趣的漏洞
上个月我调试一个老旧的有趣后台系统,发现一个让人哭笑不得的漏洞漏洞——密码框输入`admin' OR '1'='1`,居然真的有趣能登录进去。那套系统是漏洞2008年写的,数据库查询直接拼字符串,有趣连参数化都没做。漏洞我盯着屏幕上弹出的有趣欢迎界面,愣了好几秒。漏洞
这不是有趣什么高深的黑客技巧,教科书里最基础的漏洞SQL注入。可它就这么躺在生产环境里,有趣躺了整整十五年。漏洞更讽刺的有趣是,这个系统的漏洞登录页面右上角还挂着一行小字:“本系统已通过等保三级认证”。
漏洞最有趣的有趣地方,往往不在技术本身,而在它暴露出的荒诞感。有次我帮朋友排查一个电商网站,发现优惠券系统存在一个逻辑漏洞:用户下单时先使用优惠券,然后修改订单金额为负数,系统会把负数的金额直接退回到支付账户。朋友说这漏洞是某个离职程序员故意留的后门,代码注释里写着“给后来人的礼物”。
我见过最优雅的漏洞是时间戳碰撞。某签到系统用毫秒级时间戳做唯一标识,理论上不可能重复。但有个用户写了个脚本,每次签到前手动把系统时间调慢两小时,于是他能把同一时刻的签到记录连续提交五次。这不算破解,更像是在跟系统玩捉迷藏——系统以为时间不可逆,但人家直接改了你家的钟。
有些漏洞藏在人性的缝隙里。某社交App的找回密码功能,安全问题设置的是“你小学班主任的名字”。我试着输入“李老师”,提示错误;输入“王老师”,也错误;最后输入“老师”,居然通过了。原来开发时只验证了答案中是否包含“老师”两个字。这算不算漏洞?从技术角度说,是;从产品角度说,这分明是给所有健忘症用户留的暗门。
还有一类漏洞让人想拍桌子。某银行App的转账功能,金额字段是前端校验的。用抓包工具改一下请求体,把转账金额从100改成0.01,系统照样执行。客服解释说是“为了提升用户体验,减少了不必要的服务端验证”。用户体验提升了,但银行的风控部门大概要哭晕在厕所。
真正让我着迷的,是漏洞背后的时间差。老系统里的漏洞像是埋在地下的陈年旧酒,越陈越香——前提是你得先活到能挖出它的那天。新系统里的漏洞则像刚出锅的爆米花,噼里啪啦响个不停。前阵子某云服务商爆出权限绕过漏洞,从发现到修复只用了47分钟,但在这47分钟里,已经有安全研究员用漏洞顺手修改了自己服务器的计费时长。
漏洞这东西,说到底是代码和现实之间的裂缝。代码里写的是逻辑,现实里跑的是意外。你永远猜不到哪个犄角旮旯的逻辑会在什么场景下被触发,就像你永远不知道哪个用户会闲到去修改系统时间,或者把密码框当成SQL练习场。
每次修完漏洞,我都会把原始代码翻出来看看。那些写于不同年代的代码风格各异——有的缩进乱七八糟,有的变量命名随心所欲,有的注释比代码还长。它们像地质层一样叠在一起,每一层都记录着某个程序员的某个下午,某个加班的深夜,或者某次不为人知的妥协。
漏洞是代码的伤疤,但伤疤下面藏着的是活生生的历史。