0x0 前言
做渗透测试也有一段时间了,每次对目标站点进行渗透的时候都发现登录方面的问题特别多,针对Web登录认证这块,我一直想要写个帖子进行全面点的总结,耐于目前处于实习阶段,工作也较多,所以推迟到了如今,话不多说,下面开始进行对Web登录认证类漏洞的安全验证设计机制进行探讨。
一、用户登录
当我们打开浏览器进行浏览网页的时候,或多或少会遇到一些用户后台界面,
而这些界面并非任意用户能访问,举个例子吧,就如同我们下班回家,需要进入家里,这时候家门就是一道认证,而我们手里的钥匙就是进去的凭证,但这道认证确并不安全,为什么呢,请往下看
存在的漏洞
1.用户枚举
这种漏洞在web用户登录时最为常见,当输入错误的用户名提示账号不存在,输正确的用户名提示密码错误,从而枚举用户名,如下图:
利用思路:使用工具进行暴力破解,如:BurpSuite、Hydra,当枚举出用户账号时,然后针对指定用户进行密码爆破,如果存在账号锁定这一策略,那么可制造脚本构造批量的恶意登录,导致大部分用户被锁(如管理员)无法正常登录后台业务
修复方案:
1.使用模糊的错误提示,如用户名或密码不正确
2.采用有效的验证码机制 (添加验证码也不一定能防止,下文详说)
2.账号锁定
说明:后端登录机制采取用户登录错误次数过多锁定账号
利用思路:写个脚本批量登录或利用bp爆破用户账号导致大部分用户被锁,致使业务系统不能正常运转
修复方案:
1.使用有效验证码方式防爆破
2.尽量不要使用登录次数太多锁定的方式,或者设置短时锁定
3.账号密码暴力破解
这里简述一下暴力破解
所谓暴力枚举,就是对密码字典中的密码逐个试,直到将用户名和密码试出来,但这种方法完全取决于字典是否包含密码,但是从理论上讲,只要我的数据字典足够大,就没有枚举不了的字符形式的密码,注意,我说的是字符形式,所以,现在出现了生物学密码,比如指纹识别,虹膜识别等。但最终,生物学密码也是会以数据的形式存入数据库
同理,我再举一个例子,当有一天我回家了,就如同往常一样,掏出手里的钥匙去开门,但这时候我手里的钥匙比较多,暂时分不清哪把钥匙是能开这个门的,面对这种情况,既然我分不清哪把是能开门的钥匙,而且我拿钥匙去开门又没有次数限制,那么我直接拿钥匙逐个的去开门尝试一下不就能得出结果了吗?这时候只要我手里包含着能开门的钥匙,那么我就能进去;同理,在我们进行web登录时,后台程序如果对我们登录错误的次数不做限制,且没有验证码等防御机制的情况下,那么此时的我们就可以利用字典(就如同刚刚例子手里所有的钥匙)针对该登录机制进行暴力破解了,这时候只要我们的字典包含着该站点的账号密码,那么我们即可成功进入后台,这因为站点对我们的非法登录错误次数不做限制,从而导致我们成功利用该漏洞,漏洞效果如下图:
这是之前复测遇到的一个站点,该站点对用户登录密码错误次数没有限制,且登录界面存在用户名枚举,这可导致攻击者枚举出指定用户,接着针对指定用户进行密码爆破,从而进入后台进行恶意操作
该站点传输使用了Base64加密,根据其特性,可把密码字典进行Base64加密后针对性的进行爆破破解,Base64加密的信息都是可以解密的,面对客户这些掩耳盗铃的修复方式也是很无奈
修复方案:
针对该漏洞,我们可以在登录认证时添加有效验证码机制,且服务端第一优先级先验证验证码的存在性和正确性,一个验证码使用一次后销毁,验证用户名和认证因子的匹配性、最后再触发相关功能,重要请求中要带有验证码机制,对不存在或者不正确的账号采用模糊的报错提示信息
4.xss
登录框存在xss,这种情况除了在ctf和靶场遇到外,实战我还没遇到过,此外本文只针对登录认证做探讨,想深入了解xss的同学可以自行网上找资料。
对此漏洞我们可以使用以下修补方案:
1.开启Http Only避免攻击者利用XSS攻击盗取用户cookie
2.对输出进行html编码,就是通过函数,将用户的输入的数据进行html编码,使其不能作为脚本运行,对所有的过滤、检测、限制等策略,建议在Web Server那一端去完成,而不是使用客户端的JavaScript或者VBScript去做简单的检查。因为真正的攻击者可以绕过你精心设计制作的客户端进行过滤、检测或限制手段
5.sql注入
用户名字段或者密码字段存在sql注入,比较典型的是万能密码登录(大家都知道)
利用方式:登录数据传输多采用post,这时候我们用bp改包找寻注入点或者丢sqlmap进行探测即可
修复方案:
1.使用参数化查询,检查变量数据类型和格式
2.采用sq语句预编译和绑定变量
二、用户注册
注册功能在网站中并不少见,同样的,这个功能点也存在众多问题
常见漏洞有下面几个:
1、用户枚举
注册时系统提示用户名已注册或用户未注册,这可导致通过爆破方式来批量枚举用户
账号存在时:
账号不存在时:
利用思路:
1.先枚举出用户名,然后针对该用户进行密码爆破,可利用社工库根据手机号等用户习惯生成字典进行爆破,这样成功率会提高不少
2.单个手机号获取短信无上限,可通过脚本不断向验证手机号或者邮箱发送短信或者邮件,导致接收方接受大量垃圾信息
3.登录认证存在账号锁定,写个脚本批量锁账号
修复方案:
1.短信发送设置时间间隔
2.短信发送设置发送次数限制
3.短信发送设置图形验证码,每次发送都要验证一次图形验证码
2、任意用户注册
注册功能的图形验证码失效,并且手机验证码无失效时间并且为4位数,因此可以通过爆破手机验证码可以使用任意手机号码进行注册
当短信验证码为错误时:
为正确时:
利用思路:
1.通过爆破手机验证码可以使用任意手机号码进行注册
2.枚举已有用户
修复方案:
1.设置有效及复杂的验证码
2.短信验证码位数设定为6,能增加爆破难度
3.设定错误注册限制,当用户短信验证码输错次数超过一定次数,该验证码便失效
3、sql注入
常见的有二次注入
举一个实战栗子:
该漏洞位于注册界面,攻击者可利用用户注册+修改密码重置admin密码,这里我注册一个admin’#的账号,登陆该账号后可以进行对admin密码修改;造成该漏洞的原因是,虽在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes 或者是借助 get_magic_quotes_gpc 对其中的特殊字符进行了转义,但在写入数据库的时候还是保留了原来的数据,但是数据本身还是脏数据,在将数据存入到了数据库中之后,开发者就认为数据是可信的,在下一次需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中’会被还原,这就形成了二次注入从而造成admin密码被重置
修复方案:
1.使用参数化查询,检查变量数据类型和格式
2.采用sq语句预编译和绑定变量
验证码
- 1.图片验证码
- 2.短信验证码
- 3.邮箱验证码
一、图片验证码
- 1.验证码复用,有条件不生效
- 2.验证码易识别
现如今前端开发使用最多的验证码非图片验证码莫属了,这种验证码在一定程度上,可以很好的规避攻击者针对登录认证漏洞的利用,但前提是这种验证码是有效,在我做渗透测试时,遇到太多由于开发不规范所引起的验证码安全问题,话不多说,下面开始探讨
1.验证码复用,有条件不生效
下面这个案例就比较有意思了
这是我刚刚进公司接到的第一个站,至今记忆犹新;
这个站的验证码机制存在的问题是:当同一个http请求到服务端以后最优先验证了账号密码的准确性,随后才对验证码做验证,这时,验证码不是最优先验证的,并且当账号密码为错误时,并不会刷新验证码,且这时候的验证码为有效的;验证码有条件不刷新,在验证码未遇到正确的账号密码时,验证码永远不会刷新,且这时候的验证码一直有效,这开发神奇的脑洞很巧妙的导致验证码能复用,不说了,看下图:
1.在密码正确前未对验证码的一次性做验证
2.只有当同一http请求内所有触发因子都为正确时,验证码的一次性效验才生效,且下一次验证码销毁
验证码失效
这里说到底还是开发的逻辑思维有问题,首先,验证码正常情况下,是只能使用一次的,但是,由于数据提交到服务端时,验证码的优先级为低,这导致同一个http请求到服务端以后验证码不是最先验证的,从而导致了验证码具有复用性,而这时候攻击者就可以根据这一逻辑漏洞,针对登录认证这方面做攻击了,面对开发的这种脑洞,我也是很无奈,好好的一个验证码硬是给搞崩了
2.验证码易识别
分享一个我之前实战的一个案例;这个站点的图片验证码易识别,验证码杂点太少或者没有杂点导致可以用程序识别出验证码的内容,这可导致攻击者可根据越权得到的账号信息,针对指定用户进行密码爆破,然后可利用越权漏洞更改指定用户密码
1.验证码为纯数字,且验证码易识别
2.审查源码发现加密方式为前端base64加密
3.密码传输使用Base64加密,根据其特性,写个py脚本对密码字典进行Base64加密后针对性的进行爆破破解
4.直接使用Pkav HTTP Fuzzer 进行爆破
由于验证码使用不规范,导致攻击者可进行对站点登录认证漏洞的利用
安全的认证机制建设
一、图片验证码
1.验证码必须要在服务端生成添加杂点干扰项并足够扭曲以图片格式返回前端且服务端应第一优先级先验证验证码的存在性、正确性、一次性,其次可对参数进行正则格式验证、之后对不能验证参数进行过滤编码、验证用户名和认证因子的匹配性、最后再触发相关功能
二、登录数据传输
1.采取HTTPS加密通道进行数据传输
2.采取有效的加密算法对敏感数据传输进行加密
三、手机和邮箱验证码
1.验证码要有一定的复杂度,至少6位,验证码不能返回前端
2.基于客户端session进行次数限制,制定合适的锁定策略
3.进行敏感数据操作时对比账号和绑定的手机邮箱是否匹配,做多次验证
除此之外,一个安全的认证机制的建设还应包含以下规则:
1.用户提交敏感数据时,应把验证码和注册/登录信息在同一http请求中提交,且服务端应优先验证验证码是否正确,最后再触发相关功能
2.永远不要相信用户在数据交互点的输入数据,面对用户数据输入,应做好相对应的参数过滤,针对sql注入,可采取参数绑定或预编译查询数据库避免产生注入,而对于xss,可利用正则判断部分字段,对用户输入的恶意代码进行过滤,在不影响业务进行的情况下,可对参数进行过滤转码,使之不能作为正常的脚本运行
转自:csdn