漏洞介绍
众所周知,现在大大小小各种网站,在使用时很多都会让用户进行身份认证。目前主流的认证方式包括账号密码,手机/邮箱验证码,微信/app扫码等,这种认证实际上就是在检查“你是否是你”,以对用户在站内的资源进行保护。但如果网站存在身份认证漏洞,那么这种保护机制就会失效。
P.S. 还有比较复杂的多因子认证,就是将秘密信息因子(密码/个人身份识别码/安全问题验证)、物品因子(软件令牌如验证码/硬件令牌如ukey)、生物特征因子(指纹/语音/面部特征)、位置因子(IP)、时间因子(特定的时间段)等组合起来使用。此篇文章只涉及单因子认证的相关漏洞。
身份认证漏洞一般是指系统在对用户进行身份认证的过程中存在纰漏,使攻击者可能绕过或欺骗系统对用户身份的检查,获取其他用户的身份权限。这种漏洞可能导致攻击者完全取得目标用户的权限。如果是用户系统,就会对该目标用户的资源造成损失,如果是管理系统,则危害更大,可能会对系统整体造成不可预估的损失。同时,这种漏洞也会对组织和企业的声誉带来负面影响,甚至可能导致经济损失和法律责任。
漏洞成因
身份认证漏洞的成因,主要是开发者制定的身份验证机制存在编码不完善,逻辑缺陷,或过于相信用户的安全意识,导致攻击者可以冒用其他用户的身份。(这里不讨论钓鱼、肩窥等社工行为导致的密码泄露,和存在sql注入导致的万能密码登录等情况)。
身份认证漏洞根据使用的秘密信息因子,主要包括以下常见的类型:
账号密码:
账号密码认证是最常见的身份认证方式。对于使用这种方式的网站,可以先判断一下目标网站的类型,如果是管理系统,且使用了开源的web框架,则可能存在默认的登陆账密,如wordpress的admin:password,zabbix的admin:zabbix等等,可以尝试搜集一下目标网站框架的默认账密。当然,现在那些新版的大型框架中已经很少使用固定的默认账密了┑( ̄Д  ̄)┍。
如果需要进行登录,那么用户名也是必不可少的。对于用户系统,攻击者通常需要自行获取目标用户的用户名,而对于管理系统,如果开发者分别对用户名和密码进行判断,攻击者就可以通过构造一些常用的用户名来对存在的用户名进行暴破。
举例说明🌰🌰,开发者使用以下判断逻辑,先判断了用户名,用户名匹配后再判断密码
user = {"admin":"123456", "guest":"guest"}
if username not in user:
return "用户名不存在"
else:
...
虽然这样一来或许判断效率会高一些(十分有限),但攻击者就可以通过观察后端返回错误的内容判断当前尝试的用户名是否存在。
当获取用户名后,就可以尝试对密码的进行获取或绕过。最常见的方式就是密码暴破。
举例说明🌰🌰,系统存在
POST /api/login
Host: example.com
username=*&password=*
这样一个身份验证接口,如果开发者没有对这个接口的请求做限制,那么攻击者就可以通过在burp或脚本中构造常用密码字典的方式进行暴破。同时也可以根据目标用户的个人信息(姓名/生日/公司等),构造更加针对性的密码字典。
在有的情况下,开发者过于依赖前端的校验,从而在后端的身份验证处,可能会有逻辑漏洞。笔者之前遇到一个漏洞,网站前端存在密码非空的限制,但抓包将密码字段置空后,即可成功登录。因此在挖掘此类漏洞时,可以多对请求进行多种修改尝试。
验证码:
有的网站会使用验证码来限制攻击者的暴破行为,比如直接使用短信验证码登录,或者在输入密码后再次要求输入验证码。但如果没有对其设计完整的安全逻辑,这种方式依旧会存在风险。
在短信验证码的场景下,验证码其实可以简单的看作是服务端只对某次登陆行为生成的临时密码,那么既然是“临时”密码,就会涉及强度和有效时间的问题。如果开发者在设计验证码功能时,使用了4位数字这种低强度组合作为验证码,那么一旦没有对用户的尝试错误次数做限制,就会导致验证码本身也会有被暴破的风险。而如果开发者没有限制验证码的过期时间,就可能会导致同一验证码可以被多次使用,甚至在同一个域下不同应用上可以复用。
如果是要求同时输入密码和验证码的场景,可以多注意下生成验证码时的返回包。有的不太注意的开发者会从后端直接将验证码返回至前端,再由前端将验证码图片化。
举例说明🌰🌰,系统存在
GET /api/GetVerificationCode
Host: example.com
这种接口,用于从后端获取验证码,而后端直接将验证码返回至前端
HTTP/2 200 OK
VerificationCode=******
此时的验证码就会形同虚设,可以通过脚本将获取验证码和登录的行为连起来进行密码暴破。(甚至遇到过直接将手机验证码回显到前端的操作,不知道开发者怎么设计的…)
最后还可以尝试一下万能验证码,就是开发者遗留的测试验证码,没有及时删除掉,比如000000,999999这类。
二维码:
二维码扫码登录这块主要可能存在Oauth2漏洞,此处不再赘述,可参考以下大佬内容。
搞懂玩爆OAuth 2.0—OAuth2.0身份验证漏洞 作者:Eason_LYC
其他漏洞:
在身份认证这块,还有可能存在一些设计逻辑上的漏洞,比如将认证结果(true or false)返回前端,再由前端判断是否显示认证后内容;直接burp抓包将认证包丢弃,可以跳过认证界面;在忘记密码处进行暴破或者其他操作等等,主要还是思路要打开,多多尝试。
处理方式
身份认证漏洞这块,从开发者的角度来讲,可以主要关注以下几点:
- 在注册时进行密码强度限制,如:8位以上,必须包括数字字母符号,不能包含常用弱密码等等;
- 限制同一账号的登陆尝试次数;
- 限制验证码的强度、有效时间和作用范围;
- 遵循最佳实践,正确配置OAuth2认证;
- 完善身份认证逻辑;
- …
ps:如果还有其他想法,欢迎评论区交流👀