最近安全部门对WEB系统进行了一次漏洞整改,发现了某个系统存在验证码绕过风险。
根据安全部门提供的信息,该漏洞构造场景是通过一层中间代理(Burpsuite Proxy)拦截客户端与服务端的请求,通过篡改报文中的账户信息,使用当前请求正确的验证码,从而无限次数的暴力破解账户信息(系统设计年代久远,当时设计可能对WEB攻击考虑不太全面)。
先简单介绍下该系统的鉴权流程:
用户输入账户信息+验证码(刷新页面或手动刷新验证码会从服务器获取验证码,但该验证码缓存于session中),服务端接收到账户信息+验证后会先校验验证码是否正确,若不正确则,返回反之与数据库做对比,符合则返回,客户端接收服务端的请求,若成功则跳转,返回根据不同的错误码提示相应信息,并重新获取服务端生成的新验证码,重新缓存。
看完流程可以很容易想到一个问题:验证码此时并不会重置,一切重置验证码的操作都在浏览器,所以在Session不失效的时效内,可以无限重用验证码。
下面示例使用Burpsuite(以下简称B) 拦截请求,暴力破解的场景。
1.首先配置Burpsuite的代理监听
Proxy->Options->Proxy Listeners->Add 以127.0.0.1:8080为例
2.配置客户端网络代理(以火狐为例)
选项->高级->网络->连接设置->使用手动代理 根据实际情况把代理设置为127.0.0.1::8080
3.访问到系统登录页面,然后打开Burpsuite的拦截Proxy->Intercept->Intercept is on
此时浏览器的请求就会被工具拦截了,任意输入账户信息+验证码登录,B拦截到请求后把验证码参数改为正确的验证码,然后把请求send to Repeater(编辑重发),因为对验证码的刷新操作都在于浏览器收到结果之后,所以此时修改用户名和密码的组合就可达到暴力破解的地步了
ps:通过火狐自带的编辑重发请求的功能也可实现,详情请自行百度。
搞清楚原理之后很容易想到的方法就是在每次验证码通过之后,我们尝试重置session中的验证码,并在入口加一层空的判断,若被重置过的,则提示验证码过期即可。
但是仅仅这样也无法避免问题,session信息也可能被黑客得到,我们可以尝试把session信息缓存到第三方缓存系统中如Memcached,Redis等。这样系统入口安全问题又能得到进一步保障了。