利用业务系统短信验证漏洞
凌晨两点十七分,利用漏洞我的业务验证手机屏幕亮起一条短信验证码,来自某知名电商平台。系统问题在于,短信我根本没在登录任何账号。利用漏洞更诡异的业务验证是,这条验证码请求来自一个陌生IP,系统归属地显示在三千公里外的短信某个城市。我盯着那串六位数字看了几秒,利用漏洞然后意识到——有人正在用我的业务验证手机号尝试登录。而且,系统他们可能已经成功了。短信
这不是利用漏洞什么高深莫测的攻击手法。业务系统的业务验证短信验证漏洞,说白了就是系统开发者偷懒留下的后门。最常见的形态是响应包里的验证码明文返回。你提交一个获取验证码的请求,服务器把验证码发到你手机的同时,也原封不动地塞进了HTTP响应里。用Burp Suite拦截一下,一切尽收眼底。更蠢的版本是验证码直接写在前端JS代码里,连抓包都省了。
另一种经典场景是验证码不失效。很多系统只校验验证码是否正确,却不校验它是否过期、是否被使用过。这意味着什么呢?我拿到一个验证码,用它完成登录,退出,再登录,还是同一个验证码,依然有效。如果这个验证码恰好是四位纯数字,暴力破解只需要一万次尝试。而很多系统压根没有尝试次数限制,或者限制只在前端做,绕过前端直接发请求,无限次尝试随便来。
我亲眼见过一个极端案例。某银行网银系统的短信验证码,竟然是根据手机号和时间戳用固定算法生成的。也就是说,只要知道对方手机号,就能推算出任意时刻的验证码。这已经不是漏洞了,这是给攻击者递刀。发现这个问题的安全研究员提交报告后,银行连夜修复,但谁也不知道在这之前有没有人已经利用过。
还有一种更隐蔽的玩法,叫"并发绕过"。有些系统确实做了验证码校验,但逻辑是先校验验证码,再校验手机号是否匹配。如果你在极短的时间内同时发送两个请求,一个用正确的验证码和错误的手机号,另一个用错误的验证码和正确的手机号,服务器可能因为竞态条件而放行第二个请求。这种攻击对开发者来说极其隐蔽,因为单看日志,每个请求都是失败的,但组合起来就成功登录了。
短信轰炸也是这个漏洞的衍生品。攻击者抓取到获取验证码的接口后,循环调用,就能让目标手机不停收到垃圾短信。更恶劣的是,有些系统的验证码模板里包含了用户输入的参数,攻击者可以注入恶意内容,让短信内容变成诈骗信息。我有个朋友就收到过"您的账户已被冻结,请点击链接激活"的短信,发件人号码看起来跟官方客服一模一样。
这些漏洞的本质,是开发者把验证码当成了安全边界,却忘了验证码本身只是安全链条中的一环。短信通道本身也不可靠——SS7协议漏洞让全球范围内的短信拦截成为可能,伪基站更是能在百米内截获验证码。你把所有信任都押在一条短信上,那这条短信被劫持的时候,你的账户就裸奔了。
修复手段其实不复杂。验证码必须一次性使用,必须设置合理有效期,必须绑定会话ID,必须限制尝试次数。响应包里绝不能出现验证码字段。更重要的是,核心操作不能只靠短信验证码这一层保护,要叠加设备指纹、行为分析、地理位置校验。但现实是,很多业务为了用户体验,砍掉了所有额外的安全措施,把验证码当成了万能钥匙。
写到这里,我看了眼手机,那条凌晨的验证码短信还在。我没有收到任何登录成功的通知,但我知道,那个陌生IP至少已经拿到了获取验证码的接口权限。至于他们有没有绕过其他校验,我不得而知。我唯一能做的,是改了密码,开了二次验证,然后祈祷这家电商平台的开发者已经修复了那个漏洞。大概率没有。