26

验证码的姿势学习 | Fisher's 安全日记

 3 years ago
source link: http://austfish.cn/2020/04/30/%E9%AA%8C%E8%AF%81%E7%A0%81%E7%9A%84%E5%A7%BF%E5%8A%BF%E5%AD%A6%E4%B9%A0/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

验证码的姿势学习

2020-04-30

验证码怎么玩?

0×01 前言

验证码机制

  1. 客户端发起请求
  2. 服务端响应并创建一个新的SessionID同时生成随机验证码,将验证码和SessionID一并返回给客户端
  3. 客户端提交验证码连同SessionID给服务端
  4. 服务端验证验证码同时销毁当前会话,返回给客户端结果。

0×02 客户端安全问题

  1. 有的网站验证码由本地js生成仅仅在本地用js验证。可以在本地禁用js,用burp把验证字段删除。
  2. 有的网站把验证码输出到客户端html中,送到客户端Cookie或response headers。
  3. 有些网站默认不显示验证码,而是在输入错误一定数量之后才需要验证验证码,开发人员可能在Cookie中写入一个标记loginErr,用来记录错误数量,则可以不更新Cookie中的loginErr值反复提交,验证码就不会出现。

0×03 服务端安全问题

  1. 验证码不过期,没有及时销毁会话导致同一验证码反复可用。攻击者可以在Cookie中带固定的sessionID和固定的验证码字符串。
  2. 没有对验证码进行非空判断,导致可以直接删除验证码参数。
  3. 产生的验证码问题有限

0×04 验证码问题汇总

4.1 验证码不刷新

导致验证码不刷新(固定)的原因是:登录密码错误之后,session中的值没有更新,验证码不变。验证码不刷新通常有以下两种情况:无条件不刷新、有条件不刷新。

4.1.1 无条件不刷新
无条件不刷新是指在某一时间段内,无论登录失败多少次,只要不刷新页面,就可以无限次的使用同一个验证码来对一个或多个用户帐号进行暴力猜解。

【测试案例 1】测试人员登录并抓取请求包,在不改变验证码的情况下,多次发送请求包,响应包中内容都是“用户名或密码错误”
【安全建议】建议针对一次请求生成的验证码只能用一次,用完立即过期。每次生成的验证码不允许跨会话和请求使用。

4.1.2 有条件不刷新
有条件不刷新多见于如下情况:登录失败之后,系统会打开一个新页面或者弹出一个新的警告窗口,提示用户登录失败,点击确定后返回登录界面且验证码刷新。这种情况下,只要我们不关闭新窗口或弹窗,配合使用Burpsuite的intruder模块就可以进行暴力破解了。

【测试案例 2】来看下某系统的验证码鉴权流程:

用户输入账户信息+验证码(刷新页面或手动刷新验证码会从服务器获取验证码,但该验证码缓存于session中),服务端接收到账户信息+验证后会先校验验证码是否正确,若不正确则,返回反之与数据库做对比,符合则返回,客户端接收服务端的请求,若成功则跳转,返回根据不同的错误码提示相应信息,并重新获取服务端生成的新验证码,重新缓存。

【问题描述】看完流程可以很容易想到一个问题:验证码此时并不会重置,一切重置验证码的操作都在浏览器,所以在Session不失效的时效内,可以无限重用验证码,这时就可以使用BurpSuite进行暴力破解了,验证码形同虚设。

4.2 验证码前端可获取

这种情况在早期的一些网站中比较常见,主要是因为程序员在写代码的时候安全意识不足导致的。验证码通常会被他们隐藏在网站的源码中或者高级一点的隐藏在请求的Cookie中,但这两种情况都可以被攻击者轻松绕过。

4.2.1 验证码隐藏在源码中
验证这种情况很简单,我们只需要记住验证码,然后右键打开网站源代码,Ctrl+F搜索,输入刚才的验证码,如果可以成功匹配到,那恭喜你,接下来就可以写工具,提取源码中的验证码并将其放入每次请求的报文中,来进行帐号破解,这里推荐使用python。

4.2.2 验证码隐藏在Cookie中
这种情况,我们可以在提交登录的时候抓包,然后分析一下包中的Cookie字段,看看其中有没有相匹配的验证码,或者是经过了一些简单加密后的验证码。

4.3 验证码空值绕过

验证码空值绕过,是在日常的渗透测试中很容易被我们忽略的一点,实际应用中我们可以通过直接删除验证码参数或者Cookie中的一些值来绕过判断,进行暴力破解。

4.4 验证码易识别

在平常的漏洞挖掘过程中,如果我们发现登录的验证码非常简单且易于识别,那我们就可以尝试使用自动化工具来进行登录破解了,如PKAV的HTTP Fuzzer。5. 存在无验证码页面经过测试,如果我们发现网站验证码自身并不存在缺陷,那我们接下来就可以尝试寻找一些其他的登录页面或接口来尝试暴力破解。

5.5隐藏的页面

这种页面通常是留给测试人员使用的,或者是一些忘记删除的老界面,利用的前提是该界面依旧可用,一般情况下,我们可以通过扫描器来发现这种页面。

5.6 微信公众号、APP登录页面

很多网站的web登录页面已经做的相当完善了,但是却在微信公众后的绑定接口或者是APP的登录界面上面栽了跟头,在渗透测试的过程中,一定不要忘了对公众号和APP的测试。

5.7. 其他绕过方法

5.71万能验证码
渗透测试的过程中,有时候会出现这种情况,系统存在一个万能验证码,如000000,只要输入万能验证码,就可以无视验证码进行暴力破解。

5.7.2验证码无效
这种情况下,无论我们输入什么数据,验证码都会判断通过,验证码形同虚设,这种情况我只遇到过一次。

5.7.3验证码数量有限
多见于计算类型的验证码,如1+8=?,这种类型的验证码严格意义上来说不能叫做验证码,多刷新几次验证码,我们可能会发现系统中的算数题目只有那么几道,这种情况下只要将验证码全部下载下来,生成一个md5库,然后将前端生成的验证码与本地文件进行对比即可。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK