NTLM与kerberos认证体系详解


本地认证

本地认证是今天讲的这些认证方式之中最简单的一个。

当我们开机登录输入密码的时候,系统会将我们输入的明文密码加密成NTLM hash,此时再同sam文件里的值进行对比,如果相同,则登录成功。NTLM hash的前身是LM hash

SAM文件中所储存的是密码的hash值

我们上面说的sam文件是指:

C:\Windows\System32\config\SAM

总结一下,就是用户注销、重启后,操作系统会显示输入框,接收输入后,首先判断输入的用户名是否存在,如果存在将密码交给lsass进程,这个进程中可能会存一份明文密码,将明文密码加密成NTLM Hash,对比SAM数据库中的hash进行验证。

NTLM hash 的产生:

明文->hex编码->Unicode编码->MD4

python实现:

import hashlib,binascii
hash = hashlib.new('md4', "password".encode('utf-16le')).digest()
print binascii.hexlify(hash)

或者也可以直接用ntlm库

windows 网络认证

  • 在内网渗透中,经常会遇到工作组环境,而工作组环境是一个逻辑上的网络环境(局域网工作区),因为在工作组中并不存在一个信托机构,所以隶属于工作组的机器之间是无法建立一个完美的信任机制的,只能点对点进行认证
  • 假如在一个工作组中有a,b两个机器,a想远程访问b上的文件,那么这个时候a机器的操纵者则需要将一个存在于b机器上的账户凭证发送给b机器,经过认证后才能访问。
  • 最常见的服务:445端口的smb服务
  • smb协议:一个用于进行共享文件资源的一个协议

NTLM(NT LAN Manager)协议

  • 早期smb协议在网络上传输明文口令,后来出现LAN Manager Challenge/Response 验证机制,简称LM,由于他的不安全性,微软在后面的更新中提出了windowsNT挑战/响应验证机制,称之为NTLM。发展到现在已经有了更新的NTLM V2以及Kerberos验证体系。
  • smb协议本身只提供了资源相关的共享服务,在认证方面,采用的是NTLM协议,可以类比我们远程访问windows的共享文件夹时,在认证我们身份的方面,也是采用的NTLM协议,在windows的好多服务的”认证层”上,使用的都是我们的NTLM协议。当然如果是在域内,认证方面会采用kerberos协议进行认证

挑战(challenge)/响应(response)机制

主要分为质询->协商->验证三个阶段

第一步协商

简单来说就是客户端主要在这一步向服务端确认协议的版本,是NTLM v1还是NTLM v2还是其他的比如LM协议。

第二步质询

第二步质询完整过程:

  1. 客户端向服务端发送用户信息(包含用户名)请求
  2. 服务器接受到请求,生成一个16位的随机数,被称之为”challenge”,并在本机sam文件上查找登录名对应的密码的NTLM Hash,并用这个NTLM Hash 加密challenge,生成challenge1后,将challenge发送回客户端(这里的challenge1呢其实就叫做Net NTLM Hash,这个在ntlm中继攻击中提到过,可以去看下那篇文章)
  3. 客户端接受到challenge后,会将用户输入的密码进行NTLM hash,并使用NTLM hash加密 challenge, 生成Response,然后将Response发送至服务端。(这里的Response,本质上也可以说是Net NTLM Hash)
  4. 服务器端收到客户端的Response后,对比challenge与Response是否相等,若相等,则认证通过

第三步验证

这一步其实就是上面质询过程中的第4点,为了更方便理解,所以没有拆分

总结

这里有一个总结的图示:

NTLM v1与NTLM v2的差别

  • NTLM v1与NTLM v2最大的差别就是challenge与加密算法不同
  • challenge:NTLM v1的challenge有8位,NTLM v2的challenge有16位
  • Net-NTLM hash:NTLM v1的主要加密算法是DES,NTLM v2的主要加密算法是HMAC-MD5

域认证体系-kerberos认证

(注:下面所有流程图中的ticket代表ST)

  • kerbroes是一种网络认证协议,其目标设计是通过密钥系统为客户机/服务器应用程序提供强大的认证服务。该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包,可以被任意的读取修改。在以上情况下,kerberos作为一种可信任的第三方服务,是通过传统的密码技术(如共享密钥),执行认证服务的

域认证所参与的三个角色

  • client(客户端)
  • server(服务端)
  • KDC(域控上的一个服务)

域认证所参与的角色(KDC上又细分的一些服务)

  • AD(account database):储存所有client的白名单,只有存在于白名单的client才能顺利申请到TGT
  • AS(Authentication Service):为client生成TGT的服务
  • TGS(Ticket Granting Service):为client生成某个服务的ticket。生成ST的地方

域认证流程——粗略流程

  1. client向kerberos服务(就是我们的域控上的一个服务)请求,希望获得访问server的权限。kerberos服务得到了这个消息,首先判断client是否是可信赖的(就是判断是否是此域内的机器),也就是白名单黑名单的说法。这就是AS服务完成的工作,通过在AD中存储黑名单和白名单来区分client。成功后AS返回TGT给客户端。(AS_REQ与AS_REP)
  2. client得到TGT后,继续向kerberos服务请求,希望获得访问server的权限。kerberos服务得到了这个消息,这时通过client消息中的TGT,判断出了client拥有这个权限,于是给了client访问服务端的权限并返回了ST。(TGS_REQ与TGS_REP)
  3. client得到ST后,终于可以访问server。这个ST只是针对这个server,其他server需要向TGS申请。(AP_REQ与AP_REP)

域认证流程深入剖析—第一步:TGT的获取 (AS_REQ与AS_REP)

  1. 首先我们的客户端会向域控上的kdc服务的AS发送我们客户端的一些信息,比如用户名,主机名等。
  2. 下一步我们的kdc服务上的AS就会进行判断这个主机、用户名等是否在我们的域里面,如果存在,那么我们kdc上的AS就会生成一个session key,这个session key是一串随机字符。
  3. 域用户的密码的NTLM hash是可以域控上查到的,然后就会使用这个客户端用户对应的NTLM hash来加密我们的session key,并将加密后的值返回发送给客户端。
  4. 然后域控这里下一步会使用KDC服务对应的用户的NTLM hash,对session key和一些客户端的信息再进行加密,最后加密出的结果也就是我们常说的TGT,并将他连同3中加密出的值一同返回发送给客户端

我们再来用两张图详细的剖析下上面所说的”客户端发送”与”KDC返回”这样的两个过程:

发送:

返回:

大家可以看到这里的TGT的有效性是有时间限制的

域认证流程深入剖析—第二步:获取ST (TGS_REQ与TGS_REP)

  1. 我们的客户端接收到了一个密文和一个TGT
  2. 第一个密文是KDC用我们客户端的用户的密码的NTLM hash加密session key产生的,因为这个客户端的用户的密码的NTLM hash不仅在域控上存在,在我们客户端本机也是存在的,所以的客户端就会使用这个客户端的用户的密码的NTLM hash来对密文进行解密,从而得到session key。
  3. 下一步我们的客户端就会向KDC上的TGS服务发送TGT,以及用session key加密的当前客户端的一些信息和时间戳,然后还有一些客户端的信息和要访问的服务端的信息这三块内容
  4. 当我们客户端向KDC发送以后,KDC的TGS服务就会开始进行认证,它首先会使用KDC服务对应的用户的NTLM hash去解密TGT得到session key,再通过session key去解密客户端包装加密的信息,得到客户端的一些信息和时间戳,然后会比较这个时间戳和当前的时间戳是不是间隔的太久了,如果间隔超过一定时间则需要他重新从头开始验证,然后他还会通过接收到的这个客户端的信息和服务端的信息来判断当前客户端是否有权限去访问这个服务端
  5. 当KDC上的TGS认证通过以后呢,他又会随机生成一串字符,叫做server session key,这个server session key其实就是用于客户端和服务端进行通信时的密钥。然后TGS会使用session key来加密这个server session key并将这个密文返回给客户端。
  6. TGS还会提取客户端的所在的域的域名,客户端的用户信息,server session key,到期时间等,来做成ST
  7. 此时TGS还会提取接收到的要访问的服务端的一些信息,并使用服务器端对应的计算机名对应的NTLM hash来加密ST,并将这个密文也返回给客户端

流程图:

ST的组成:

域认证流程深入剖析—第三步:client通过ST访问server (AP_REQ与AP_REP)

  1. 客户端通过session key解密得到server session key,并使用server session key来加密客户端的信息和时间戳,并连同ST一同发给服务端
  2. 因为服务端这台机器上是存着自己的用户hash的,所以我们可以使用Server hash解密得到ST,并得到ST里的end time,用他来判断得到ST是否已经过期,还会得到ST里的server session key,然后会使用这个server session key来解密1步骤的密文,得到客户端的信息和时间戳,然后他会去校验这个客户端信息和ticket里的客户端信息是否相等,还会验证这个时间戳是否大于某个时间。

简易流程图:

PAC

在黄金/白银票据的构造分析中,说了开启PAC可以防止白银票据的攻击。

那么PAC是什么呢?

我们都知道黄金票价的构造原理就是:掌握KRBTGT用户密码之后可以通过签发一张高权限用户的TGT票据,再利用这个TGT向KDC获取域内服务的ticket来实现对域的控制。那么这里的“高权限用户”是通过什么来判断的呢,答案就是PAC。

PAC在我们域认证中出现的节点是在哪的呢?

主要是两个节点

  1. 当我们的客户端第一次向KDC去请求TGT的时候,我们返回的TGT票据中就包含了PAC。(AS_REP)
  2. 就是最后我们的客户端拿着ST去与服务端通信的时候,如果一切验证顺利,那么最后我们的服务端就会将解密出来的PAC发送给KDC去进行认证,KDC解密PAC。获取Client的sid,以及所在的组,再根据该服务的ACL,判断Client是否有访问服务的权限。防止白银票据其实主要也是这一步。 (AP_REP)

总结
kerberos认证流程的本质上就是不停交换密钥,然后采用对称加密算法验证时间戳和身份,来完成的一个安全认证


文章作者: wa1ki0g
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 wa1ki0g !
  目录