口令安全是攻击防护中一个重要的环节。可能大家平常都做为攻方,有没有想过安全产品是如何来防护的?我就先抛砖引玉,各位大佬有更好的方法或思路,可以一起探讨下。
WEB口令防护按某服,划分成了三种:
1、弱口令
2、口令爆破
3、明文传输
这三种方式貌似很简单的样子,收集下字典不就完事了么,其实不然,真正实现起来你才会发现有好多要考虑的东西。
0x1 弱口令
既然是针对口令的防护,那么无论是哪一种分类,首要目标就是从请求包里把口令字段识别出来。
常见的登录验证方式,这里先列出以下两种:
第一种就是最常见的表单方式,以POST形式传参,content-type限定为x-www-form-urlencoded或application/json,当然还有xml等其它不常见的接口类型就先不管了。
满足上述条件,下一步就是解决用户和密码匹配问题了,那么如何来判定一个传参是用户或密码呢?这需要收集通常做为用户和密码的常用字段名,这些字段靠百度或谷歌得到的结果除了是用户密码字典,还是用户密码字典,并非我们预期。其实这个字段很像sql注入中猜用户字段名和密码字段名的过程,于是把目标锁定在了sql注入工具上,拿了几款SQL注入工具,譬如:啊D注入工具,成功的白嫖到了大量的用户字段和密码字段命名。然后去真实环境测试,你会发现这远远不够,程序员在建立登录表单时,往往会加入前缀或后缀之类的字母,这样的话就得使用到强大的正则了。
直接上干货
用户字段匹配
\b(?:\w{1,12}_|admin|adminuser)?(?:usr|user[s]?|name|username|account|administrators?)(?:_\w{1,12})?")
密码字段匹配
(?:\w{1,12}_|admin|adminuser|user)?(?:password|passwd|pwd|pass)1?
上面正则中间部分可以自行加更多你认为或新发现的用户字段或密码字段。
匹配到了键名,下面就顺利了,按匹配的键名拿到对应键值,再增加限定的弱口令规则(如:纯数字,纯字母,长度小于多位之类的),也可以使用内置字典或用户自定义的密码字典。到此,弱口令防护过程就理清了,编码实现就是水到渠成的事儿。
第二种登录方式就是常见的401基础认证了(一般路由器都使用这种方式),这种类型和POST表单认证完全不一样,用户名和密码是在header头中,形如:
Authorization: Basic YWRtaW46MTIzNDU2
basic后面是base64编码,解码后以:分隔,前面为用户名,后面为密码。这种方式比第一种要简单,只不过多了一个解码过程,就不多说了,有兴趣了自己研究。
0x2 口令爆破
有了上面的铺垫,口令爆破就简单了,匹配上面的正则,再配合用户设定的url,都满足即可判定是一次登录。当然,爆破防护的核心部分就是阈值的限定,这里面涉及到一些简单的算法,就不在本文讨论范围了。
0x3 明文传输
讲真这个真让人头疼,玩burp的人应该都知道,它就能扫出密码明文传输漏洞,那么问题来了,这喵的怎么实现?没那能力去逆向burp,百度谷歌也是徒劳,只能自己研究了,。
上文中已经解决了密码抓取的问题,最难缠的就是如何判定这密码为明文了?这得有好多密码加密判定依据通常登录加密最典型的就是md5,sha1,256之类的加密验证了,这可以设定第一种依据,如果密码只由[a-fA-F0-9]组成,且长度大于等于16位,则可以判定为有加密(当然不排除有人密码是16位仅由数字或a-f组成,这没办法,只能漏报了)
然后就是常见的对称及非对称的加密方式了,如aes,rc4,des,3des,rsa,sm2之类了,一般来说,这种加密后的密文ascii会在0-255之间传输不便,所以通常会使用base64或hex编码,这里就有些头疼了,有的加密如果使用了非填充方式,密文会很短,即便匹配上了base64或hex编码规则,你也无法判定到底是密码还是明文,比如dg9ebGMx,是rc4加密后使用base64编码的密文,但它却像极了明文。很尴尬了,只好硬着头皮来假定一个长度了。
当然还有更头疼的就是base64这个常见的编码了,它并不算是一种加密,但也有人拿它来简单加密密码,如果匹配上了这种base64,得尝试解码,如果解码后是常见的密码字符集,也应当判定为明文传输。最后没办法,硬是写了个长长的正则加上一些逻辑来判定明文传输,这里就不献丑了!!!
写到最后这里,又是一把汗,不知道当初写的防护WAF插件会有多少误报,多少漏报!!