弱口令扫描是比较常见的场景,实现思路也是五花八门,本次重点讲系统账户弱口令的实现。
Windows系统账户
现在的做法都是基于mimikatz实现的,其原理如下:
Windows系统账户密码早期是明文保存咋lsass进程里面的,mimikatz可以直接读取到明文密码。据说当时mimikatz作者给微软提了这个问题,但是微软不想改,我估计是因为微软觉得攻击者都能登陆上去开始读取lsass进程内存了,相当于完全接管了操作系统,那密码要不要加密已经无所谓了。但是明文密码总归是一个比较low的做法,后面微软改进了一下,不再保存明文密码,而是保存密码的hash。lsass进程也开始加固了,普通进程无法读取内存。
微软是怎么hash明文密码的呢,有一个论文https://acad.ro/sectii2002/proceedings/doc2013-3s/05-OPREA.pdf
具体过程在论文中都有提及。
mimikatz可以根据注册表表里面的信息,得到ntlm hash值,ntlm hash是很好计算的。
所以说,要想实现系统账户弱口令的话,其流程如下:
- mimikatz获取所有账户的ntlm hash
- 读取弱口令字典里面的明文,计算ntlm hash并碰撞
这里要注意的是,mimikatz是很多AV防护的目标,所以要做免杀,要不然文件还没落盘就被干掉了。
域账户弱口令
Windows域控机器有一个功能叫做DCsync,用来给不同域控主机同步密码的。mimikatz会模拟这个过程,假装自己是一个域控主机同步所有账户的密码信息。
剩下的逻辑和系统账户弱口令一样了,也是做hash碰撞。
Linux系统账户弱口令
Linux原理比较简单,因为Linux的密码hash保存在/etc/shadow文件中,具体这个文件的格式可以查阅Linux手册。里面讲的很详细。
然后我们调用系统函数crypt,传入弱密码字典中的明文密码和每个账户的盐。
比如说:
user:$y$j9T$021yGaPjogcLgSTSsGbHs/$N5c1nDhuHVLrWDy/Bc0WS4XSEbWwY45Jmk71nw0/NQA:20432:0:99999:7::: lxd:!:20319::::::
其中
$y$j9T$021yGaPjogcLgSTSsGbHs/$N5c1nDhuHVLrWDy/Bc0WS4XSEbWwY45Jmk71nw0/NQA
可以按照$拆分成3个部分,第一个部分表示加密算法,y表示yescrypt,j9T表示yescrypt的加密参数,具体查阅yescrypt算法,最后一个是计算出来的密码hash,也就是我们要碰撞的密文。
具体落地要注意下面几个地方:
- Linux加密算法不同版本系统是不同的
- crypt函数计算比较慢,这是故意的,就是为了防止通过暴力破解方式
弱口令库的选择:
下载https://github.com/berzerk0/Probable-Wordlists/blob/master/Real-Passwords/Real-Password-Rev-2-Torrents/ProbWL-v2-Real-Passwords-7z.torrent
里面有很多弱口令库,而且是基于出现频率排好序的。
密码策略和弱口令其实是2个不同事情,有一定的交叉性,但不完全相同。
强密码肯定不好记,好记的密码多半是弱密码。大部分用户还是会选择好记的密码。 因此仅仅基于密码复杂度和密码特征来定义密码的话,其实是不够的。
比如说P@ssw0rd123456,还是一个弱密码,但是符合等保三的密码策略。
如果真的想让用户设置一个强密码,就不仅仅是满足长度,字符等要求,还要对组合有一定要求。比如说要求单词用特殊字符分割P@ssw0rd#123456。
但是这样做的话,对预先验证密码是不是弱密码又有要求。
密码安全永无止境,只能在好用和安全之间做个妥协。