在实际的测试中,登录时通常可以使用账号密码登录以及短信验证码登录,账号密码的暴力破解,是否成功取决于用户使用的字典是否包含在你的攻击字典中,如果存在,则可以成功爆破,如果不存在则无法成功爆破,但这不是今天的重点,今天的重点是针对使用短信验证码登录时如何破解验证码的问题。
在设计短信验证码登录时,由于开发者的安全意识不足,可能会将验证码携带在数据包中返回给客户端,这种属于逻辑问题,一旦出现,那么可以接管所有人的账户,通常存在的概率不大,今天要讨论的是通用方案,暴力猜解验证码,实现账号接管。
通常短信验证码是纯数字组合且以 6 位数字居多,那么从 000000 到 999999 全部遍历一边,需要尝试 1000000 次,只要时间足够长,一定是可以猜出验证口令的,这种适用于验证接口没有任何防护的情况。
今天讨论的一个场景是,网站针对每个用户验证码在尝试五次失败之后会将验证码设置失效,也就是每个验证码只能尝试验证五次,这就杜绝了上面的问题,尝试一百万次之后获得真实验证码,那么有什么办法绕过吗?
用户一次完整的验证主要是两个步骤:
1、服务器生成验证码并将其发送给用户
2、接收用户提供的验证码然后与服务端生成的验证码进行比对
服务器设置的验证五次后失效的策略是在第二步,假如第一步未做速率限制,那么反过来,如果攻击者使用固定的五个验证码,然后强制服务器端生成 200000 次新的验证码,这样也是可以成功获得真正的验证码。
为了更好的理解,简单画了个图,比如真实的验证码是 645274,如果是按照标准的暴力破解方式,那么效果如图:
这种方式是无法获得真实的验证码,因为到第六次的实时候,验证码已经失效,那如果是使用第二种攻击方式,效果如图:
只要目标服务器生成的验证码正好是 645274,那么我们的暴力破解就成功了,从统计上看,5 次尝试机会,针对 6 位数的验证码,成功匹配的概率是 200000 分之一。
所以在开发使用短信验证码进行验证的功能是,不仅仅是要在验证的第二步进行速率限制,还要在第一步的验证码生成时也要做速率限制,不然会给攻击者可乘之机,在做漏洞发现时,这个也是一个需要注意的点。