17370845950

NTLM协议详解

目录

SSP和SSPI的概念

  1. SSPI

  2. SSP

LM Hash加密算法

NTLM Hash加密算法

  1. NTLM Hash加密流程

  2. Windows系统存储的NTLM Hash

NTLM协议认证

  1. 工作组环境下的NTLM认证

    (1) 工作组环境下NTLM认证抓包

    1)协商。

    2)Negotiate协商数据包。

    3)Challenge质询包。

    4)Authenticate认证包。

    5)返回成功与否。

    6)签名。

    (2) Net-NTLM v2 Hash计算

  2. 域环境下的NTLM认证

    (1) 域环境下NTLM认证抓包

  3. NTLM v1和NTLM v2的区别

  4. LmCompatibilityLevel

NTLM协议的安全问题

  1. Pass The Hash

  2. NTLM Relay

  3. Net-NTLM v1 Hash破解

本文节选自《域渗透攻防指南》

NTLM(New Technology LAN Manager)身份验证协议是微软用于Windows身份验证的主要协议之一。早期的SMB协议以明文口令的形式在网络上传输,因此产生了安全性问题。后来出现了LM(LAN Manager)身份验证协议,它简单到很容易被破解。随后,微软提出了NTLM身份验证协议,以及更新的NTLM V2版本。NTLM协议既可以为工作组中的机器提供身份验证,也可以用于域环境身份验证。NTLM协议可以为SMB、HTTP、LDAP、SMTP等上层微软应用提供身份认证。

01

SSP和SSPI的概念

在学习NTLM协议之前,我们先了解两个基本概念:SSPI和SSP。

1

SSPI

SSPI(Security Service Provider Interface 或 Security Support Provider Interface,安全服务提供接口)是Windows定义的一套接口,该接口定义了与安全有关的功能函数,包含但不限于:

·身份验证机制。

·为其他协议提供的Session Security机制。Session Security指的是会话安全,即为通讯提供数据完整性校验以及数据的加、解密功能。

SSPI接口定义了与安全有关的功能函数,用于获取验证、信息完整性、信息隐私等安全功能,该接口只是定义了一套接口函数,但并未实现具体内容。

2

SSP

SSP(Security Service Provider,安全服务提供者)是SSPI的实现者,微软自己实现了如下的SSP,用于提供安全功能,包含但不限于:

·NTLM SSP:在Windows NT 3.51中引入(msv1_0.dll),为Windows 2000之前的客户端-服务器域和非域身份验证(SMB/CIFS)提供NTLM质询/响应身份验证。

·Kerberos SSP:在Windows 2000中引入,Windows Vista中更新为支持AES(kerberos.dll),Windows 2000及更高版本中首选的客户端-服务器域相互身份验证。

·Digest SSP:在Windows XP中引入(wdigest.dll),在Windows与Kerberos不可用的非Windows系统间提供基于HTTP和SASL身份验证的质询/响应。

·Negotiate SSP:在Windows 2000中引入(secur32.dll),默认选择Kerberos,如果不可用则选择NTLM协议。Negotiate SSP提供单点登录能力,有时称为集成Windows身份验证(尤其是用于IIS时)。在Windows 7及更高版本中,NEGOExts引入了协商使用客户端和服务器上支持的已安装定制SSP进行身份验证。

·Cred SSP:在Windows Vista中引入,Windows XP SP3上也可用(credssp.dll),为远程桌面连接提供单点登录(SSO)和网络级身份验证。

·Schannel SSP:在Windows 2000中引入(Schannel.dll),Windows Vista中更新为支持更强的AES加密和ECC,该提供者使用SSL/TLS记录来加密数据有效载荷。

·PKU2U SSP:在Windows 7中引入(pku2u.dll),在不隶属域的系统之间提供使用数字证书的对等身份验证。

因为SSPI中定义了与Session Security有关的API。所以上层应用利用任何SSP与远程的服务进行了身份验证后,此SSP都会为本次连接生成一个随机Key。这个随机Key被称为Session Key。上层应用在经过身份验证后,可以选择性地使用这个Key对之后发往服务端或接收自服务端的数据进行签名或加密。在系统层面,SSP就是一个dll,用来实现身份验证等安全功能。不同的SSP,实现的身份验证机制是不一样的。比如NTLM SSP实现的就是一种基于质询/响应身份验证机制。而Kerberos SSP实现的就是基于Ticket票据的身份验证机制。我们可以编写自己的SSP,然后注册到操作系统中,让操作系统支持我们自定义的身份验证方法。SSP、SSPI和各种应用的关系如图所示。

相关:

SSPI

(https://www./link/1fe37085233f04789c85afa0a8b3f7b3)

Microsoft 提供的SSP包(https://www./link/352decc1e8f3d97fcdb53af60cbe1f53)

02

LM Hash加密算法

LM(LAN Manager)身份认证是微软推出的一个身份认证协议,其使用的加密算法是LM Hash加密算法。LM Hash本质上是DES加密,尽管LM Hash较容易被破解,但为了保证系统的兼容性,Windows只是将LM Hash禁用了(从Windows Vista和Windows Server 2008开始,Windows默认禁用了LM Hash)。LM Hash明文密码被限定在14位以内,也就是说,如果要停止使用LM Hash,将用户的密码设置为14位以上即可。

如果LM Hash的值为:aad3b435b51404eeaad3b435b51404ee,说明LM Hash为空值或者被禁用了。

LM Hash的加密流程如下,我们以口令P@ss1234为例演示:

1)将用户的明文口令转换为大写,并转换为16进制字符串。

P@ss1234 -> 大写 = P@SS1234 -> 转为十六进制 = 5040535331323334

2)如果转换后的16进制字符串的长度不足14字节(长度28),用0来补全。

5040535331323334 -> 用0补全为14字节(长度28) = 5040535331323334000000000000

3)将14字节分为两组,每组7字节转换为二进制数据,每组二进制数据长度为56比特位。如图所示。

4)将每组二进制数据按7比特位为一组,分为8组,每组末尾加0,再转换成16进制,这样每组也就成了8字节长度的16进制数据了。如图所示。

5)将上面生成的两组16进制数据,分别作为DES加密密钥对字符串“KGS!@#%”进行加密。然后将DES加密后的两组密文进行拼接,得到最终的LM HASH值。如图所示。KGS!@#%转为16进制为:4B47532140232425

LM Hash加密代码运行效果如图所示

03

NTLM Hash加密算法

为了解决LM Hash加密和身份验证方案中固有的安全弱点,微软于1993年在Windows NT 3.1中首次引入了NTLM (New TechnologyLAN Manager) Hash。

下图是各个Windows版本对LM Hash和NTLM Hash的支持。也就是说,微软从Windows Vista和Windows Server 2008开始,默认禁用了LM Hash,只存储NTLM Hash,而LM Hash的位置则为空:aad3b435b51404eeaad3b435b51404ee。

不同Windows系统版本对LM和NTLM的支持如图所示。

NTLM Hash算法是微软为了在提高安全性的同时保证兼容性而设计的散列加密算法。

NTLM Hash是基于MD4加密算法进行加密的。

下面我们来看看NTLM Hash的加密流程。

1

NTLM Hash加密流程

NTLM Hash的加密方程如下,可以看到NTLM Hash是由明文密码经过三步加密而成:

NTLM Hash = md4(unicode(hex(password)))

1)先将用户密码转换为16进制格式。

2)再将16进制格式的字符串进行ASCII转Unicode编码。

3)最后对Unicode编码的16进制字符串进行标准MD4单向哈希加密。

如下可以看到P@ss1234通过NTLM Hash的加密流程一步步加密成为NTLM Hash:74520a4ec2626e3638066146a0d5ceae。

P@ss1234 -> 转为十六进制 = 50407373313233345040737331323334 -> ASCII转Unicode编码 = 5000400073007300310032003300340050004000730073003100320033003400 -> MD4加密 = 74520a4ec2626e3638066146a0d5ceae

NTLM Hash加密代码运行效果如图所示

又或者直接一条python命令即可,如下。

python3 -c 'import hashlib,binascii; print("NTLM_Hash:"+binascii.hexlify(hashlib.new("md4", "P@ss1234".encode("utf-16le")).digest()).decode("utf-8"))'

如图所示,直接一条Python命令进行NTLM Hash加密:

2

Windows系统存储的NTLM Hash

用户的密码经过NTLM Hash加密后存储在 %SystemRoot%\system32\config\SAM 文件里,如图所示。

当用户输入密码进行本地认证的过程中,所有的操作都是在本地进行的。系统将用户输入的密码转换为NTLM Hash,然后与SAM文件中的NTLM Hash进行比较,相同说明密码正确,反之错误。当用户注销、重启、锁屏后,操作系统会让winlogon.exe显示登录界面,也就是输入框。当winlogon.exe接收输入后,将密码交给lsass.exe进程,lsass.exe进程中会存一份明文密码,将明文密码加密成NTLM Hash,与SAM数据库进行比较认证。我们使用mimikatz就是从lsass.exe进程中抓取明文密码或者密码哈希。使用mimikatz抓取lsass内存中的凭据如图所示。

使用MSF或者CobaltStrike通过转储哈希抓到的密码格式如下,第一部分是用户名,第二部分是用户的SID值,第三部分是LM Hash,第四部分是NTLM Hash,其余部分为空。

xxxxxxxxxx 用户名:用户SID值:LM Hash:NTLM Hash:::

从Windows Vista和Windows Server 2008开始,由于默认禁用了LM Hash,因此第三部分的LM Hash固定为空值,第四部分的NTLM-Hash才是用户密码加密后的凭据。

使用CobaltStrike的转储哈希功能转储目标机器内存中的凭据如图所示。

04

NTLM协议认证

NTLM身份认证协议是一种基于Challenge/Response质询响应验证机制,由三种类型消息组成:

·type 1(协商,Negotiate);

·type 2(质询,Challenge);

·type 3(认证,Auth)。

NTLM身份认证协议有NTLM v1和NTLM v2两个版本,目前使用最多的是NTLM v2版本。NTLM v1与NTLM v2最显著的区别就是Challenge质询值与加密算法不同,共同之处就是都是使用的NTLM Hash进行加密。

1

工作组环境下的NTLM认证

工作组环境下的NTLM认证流程图如图所示。

工作组环境下NTLM认证流程可以分为如下4步。

①:当客户端需要访问服务器的某个服务时,就需要进行身份认证。于是,当客户端输入服务器的用户名和密码进行验证的时候,客户端就会缓存服务器密码的NTLM Hash值。然后,客户端会向服务端发送一个请求,该请求利用NTLM SSP生成NTLMSSP_NEGOTIATE消息(被称为Type 1 NEGOTIATE协商消息)。

②:服务端接收到客户端发送过来的Type 1消息后,会读取其中的内容,并从中选择出自己所能接受的服务内容,加密等级,安全服务等。然后传入NTLM SSP,得到NTLMSSP_CHALLENGE消息(被称为Type 2 Challenge质询消息),并将此Type 2消息发回给客户端。此Type 2消息中包含了一个由服务端生成的16位随机值,此随机值被称为Challenge质询值,服务端会将该Challenge质询值缓存起来。

③:客户端收到服务端返回的Type 2消息后,读取出服务端所支持的内容,并取出其中的Challenge质询值,用缓存的服务器密码的NTLM Hash对其进行加密得到Response消息。最后将Response和一些其他信息封装到NTLMSSP_AUTH认证消息中(被称为Type 3 Authenticate认证消息),发往服务端。

④:服务端在收到Authenticate认证消息后,从中取出Net-NTLM Hash。然后用自己密码的NTLM Hash对Challenge质询值进行一系列加密运算,得到自己计算的Net-NTLM Hash。并比较自己计算出的Net-NTLM Hash和客户端发送的Net-NTLM Hash是否相等。如果相等,则证明客户端输入的密码正确,从而认证成功,反之则认证失败。