0x00背景

其实在很早之前我就想学习下NTLM的机制,当时也是随便看了下然后写了点笔记,这篇文章算是对当初的浮躁的一个静下心来的基础学习。

0x01前置知识

在理解windows认证前必须要掌握的是域的基本概念、域环境、工作组环境的区别。

域渗透是基于Windows域的渗透,而域渗透涉及到的技术,例如哈希传递(PTH)、票据传递(PTT)、委派攻击等常用的域渗透手段,都是基于域环境下的认证机制来啊实现的。

因而理解清楚Windows的认证机制对于域渗透的学习是必不可少的。

0x02正式开始

开局一张图,其余全靠扯。

image-20201126205344663

本地认证

本地认证十分简单:其实就是我们平常登陆系统的认证手段,我们输入密码,系统收到密码后将我们输入的密码计算成NTLM Hash,然后与sam数据库(%SystemRoot%\system32\config\sam)中该用户的哈希比对,匹配则登陆成功,不匹配则登陆失败。

由于采用了哈希算法,是单向的加密,因而只要设置的较为负责就不会被碰撞出结果。

而NTLM大致的运算流程为:用户密码->HEX编码->Unicode编码->MD4

NTLM Hash前身是LM Hash在一些较老的操作系统中前半段依然可以看到这个东西。

目前已经被淘汰了,这里我也不多延申了。

在本地认证中用来处理用户输入密码的进程也就是lsass.exe,密码会在这个进程中明文保存。

供该进程将密码计算成NTLM Hash与sam进行比对。

但早在2012R2就已经默认不再明文保存了(内存禁止保存明文密码)。我们看一下自己的win10是否有这个进程:

image-20201126210722368

所以这个windows认证的进程还是存在的,只是像刚刚说的一样不再支持明文保存密码了。

所以这个时候mimikatz的原理就清楚了,就是从这个进程lsass.exe中获取到的明文密码。

在2012R2之后的win7、win10就不行了,在这之前的都可以(部分win7也可以)。

网络认证Net NTLM

网络认证也就是在工作组环境下远程登陆另一台电脑所采用的认证机制。

NTLM协议的认证过程分为三步,也叫挑战响应机制:

1.协商(双方确定使用的协议版本,NTLM分为V1和V2两个版本,区别就是使用不同的加密方式)

2.质询(挑战(Chalenge)/响应(Response)认证机制的核心)

首先客户端向服务器端发送用户信息请求(输入用户名)

服务器接收到请求后,判断本地用户列表是否存在客户端输入的用户名,如果没有则返回认证失败,如果有,会生成一个16位的随机数,被称为”Challenge”,然后使用登陆用户名对应的NTLM Hash加密Challenge(16位随机字符),生成Challenge1保存在内存中,之后将Challenge(16位随机字符)发送给客户端。

而客户端接收到Challenge后,使用自己提供的账户的密码转换成对应的NTLM Hash,然后使用这个NTLM Hash加密Challenge生产Response,然后将Respense发送到服务器端。

3.验证(质询完成后,验证结果,认证的最后一步)

服务端收到客户端发送的Response后与之前保存在内存中的Channelge1比较,如果相等认证通过。

其中,经过NTLM Hash机密Challenge的结果在网络协议中成为Net NTLM Hash(不能直接用来进行哈希传递攻击,但可以通过暴力破解来获取明文密码)。

总结:

客户端向服务器请求使用某个用户进行验证,服务端判断该用户是否存在,存在的话使用这个用户密码的哈希值来加密一个随机字符串,并且将这个随机字符串返回给客户端,客户端再把自己提供的密码进行哈希处理后也来加密这串随机字符串,然后再把结果发送给服务器,服务器把从客户端发送的加密结果与自己本地的加密结果进行比较,相同的话便通过认证

其中的关键点在于:第二步中客户端发送的是NTLM哈希值与随机字符串加密的结果,而这个NTLM哈希是由用户输入的密码本地计算得出的,所以在这个步骤中,只要能提供正确的NTLM哈希即使不知道正确的密码也可通过认证。

于是乎便有了这样的例子:

当我们通过sql注入拿到某某数据库中管理员密码后,却发现是MD5加密的。

这个时候抓破了头也没有解出来,但这个时候发现校验密码的规则(采用前端)竟然会将输入的密码进行md5加密后对比是否相同来校验,那我们直接(绕过前端md5加密部分),然后输入md5密码就能登陆了,就不用解开了。

域认证(Kerberos)

累了累了,下次再单独写一篇关于这个的学习文章。

参考资料:parrotsec-Windows认证机制