前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >内网协议NTLM之NTLM基础

内网协议NTLM之NTLM基础

作者头像
黑白天安全
发布2021-04-07 12:27:59
1.3K0
发布2021-04-07 12:27:59
举报

Windows Hash简述

我们知道windows系统自身是不会保存明文密码的,也就是说SAM中保存的不是明文而是Hash。在本地登陆的情况下,操作系统会使用用户输入的密码作为凭据去与系统中的密码进行校验,如果成功的话表明验证通过。操作系统的密码存储在C盘的目录下:

%SystemRoot%\system32\config\sam

SAM用于储存本地所有用户的凭证信息,但是这并不代表着你可以随意去查看系统密码。我们登陆系统的时候系统会自动读取SAM文件中的密码与我们输入的密码进行比对,如果认证相同则可以使用该机器。

本地认证的流程

winlogon.exe -> 接收用户输入 -> lsass.exe -> (认证)

Windows Logon Process(即 winlogon.exe),是Windows NT 用户登 陆程序,用于管理用户登录和退出。

LSASS用于微软Windows系统的安全机 制。它用于本地安全和登陆策略。

由于是本地验证,那么用户列表和Hash密码都是在本地磁盘保存的,解密它们所需的所有信息也都在注册表中(SAM和SYSTEM),我们可以从注册表把这两个文件备份出来,然后在使用secretsdump.py或Mimikatz进行解密。首先把这两个文件获取下来。

reg.exe save hklm\sam save.save
reg.exe save hklm\system system.save

然后,我们可以使用secretsdump.py提取这些哈希

secretsdump.py -sam sam.save -system system.save LOCAL

NTLM的认证过程是怎样什么?

NTLM Hash是怎么样生成的呢?当用户注销、重启、锁屏后,操作系统会让winlogon显示登陆界面,当winlogon.exe接收到账号密码输入之后,会将密码交给lsass进程,这个进程会存一份明文密码,将明文密码加密成NTLM Hash,对SAM数据库比较认证。(winlogon.exe即Windows Logon Process,是Windows NT用户登陆程序,用于管理用户登录和退出。LSASS用于微软Windows系统的安全机制。它用于本地安全和登陆策略。) 比如当用户输入密码admin的时候,操作系统会将admin转换为16进制,经过Unicode转换后,再调用MD4加密算法加密,这个加密结果的十六进制就是NTLM Hash

admin -> hex(16进制编码) = 61646d696e
61646d696e -> Unicode = 610064006d0069006e00
610064006d0069006e00 -> MD4 = 209c6174da490caeb422f3fa5a7ae634

例如我们使用一些工具导出目标系统的hash值,通常都是如下格式:

Administrator:500:AAD3B435B51404EEAAD3B435B51404EE:31D6CFE0D16AE931B73C59D7E0C089C0:::

Administrator:500 这个就不用多说了,那么第一个

AAD3B435B51404EEAAD3B435B51404EE

就是LM hash了,31D6CFE0D16AE931B73C59D7E0C089C0是NTLM Hash

而且LM Hash已经被弃用了。LM Hash的加密算法存在一些固有的漏洞

首先,密码长度最大只能为14个字符

密码不区分大小写。在生成哈希值之前,所有密码都将转换为大写

查看我们的加密过程,就可以看到使用的是分组的DES,如果密码强度是小于7位,那么第二个分组加密后的结果肯定是aad3b435b51404ee,如果我们看到lm hash的结尾是aad3b435b51404ee,就可以很轻易的发现密码强度少于7位

脆弱点就在于DES的Key(KGS!@#$%)是固定的,也就是说,有了Key就能够解出原文。

Des密码强度不高等等

如下是LM Hash的加密过程:

将所有小写字母转换为大写字母
• >123ABC // 未达到7个字符
• 将密码转化为16进制,分两组,填充为14个字符,空余位使用0x00字符填补
• >31323341424300000000000000
• 将密码分割为两组7个字节的块
• >31323341424300 00000000000000 // 16进制
• 将每组转化为比特流,不足56Bit则在左边加0
• >31323341424300 ->(转换为二进制) 110001001100100011001101000001010000100100001100000000-> (补 足56Bit) 00110001001100100011001101000001010000100100001100000000
• 将比特流按照7比特一组,分出8组,末尾加0


由于后者都为0,结果可想而知,那就都是0;
• 将每组比特流转换为16进制作为被加密的值,使用DES加密,字符串 “KGS!@#$%”为Key(0x4B47532140232425),得到8个结果 ,每个 结果转换为16进制。
• -> 00110000100110001000110001101000000101000001001000001100 00000000
• ->30988C6814120C00 -> DES(30988C6814120C00) -> 48-D7-EB-91- 2F-5E-69-7C
• 由于我们的密码不超过7字节,所以后面的一半是固定的:
• AA-D3-B4-35-B5-14-04-EE
• 连接两个DES加密字符串。这是LM哈希。
• 48-D7-EB-91-2F-5E-69-7C-AA-D3-B4-35-B5-14-04-EE

到现在为止,Windows已经弃用了LM Hash了,可以参考下图查看版本。

一般我们导出来的LM Hahs都是空密码的,如果遇到XP或者2003的系统就要留意LM Hahs了哦!

SSP & SSPI

SSPI(Security Support Provider Interface) 这是 Windows 定义的一套接口,此接口定义了与安全有关的功能函数, 用来获得验证、信息完整性、信息隐私等安全功能,就是定义了一套接口函数用来身份验证,签名等,但是没有具体的实现。

SSP(Security Support Provider) SSPI 的实现者,对SSPI相关功能函数的具体实现。微软自己实现了如下的 SSP,用于提供安全功能:

1.NTLM SSP

2.Kerberos

3.Cred SSP

4.Digest SSP

5.Negotiate SSP

6.Schannel SSP

7.Negotiate Extensions SSP

8.PKU2U SSP

在系统层面,SSP就是一个dll,来实现身份验证等安全功能,实现的身份验证机制是不一样的。比如 NTLM SSP 实现的就是一种 Challenge/Response 验证机制。而 Kerberos 实现的就是基于 ticket 的身份验证机制。我们可以编写自己的 SSP,然后注册到操作系统中,让操作系统支持更多的自定义的身份验证方法

NTLM认证过程

在开始学习NTLM的时候要注意一点就是,目前的windows加密密码叫做NTLM Hash了,它容易与NTLM混淆,NTLM是一种网络协议,与NTLM Hash的关系就是:NTLM网络认证协议是以NTLM Hash作为根本凭证进行认证的协议。

身份验证分为3个步骤:

首先,客户端告诉服务器它想要认证。

然后,服务器以质询作为响应,质询只是随机的字符序列。

客户端使用其秘密对该挑战进行加密,然后将结果发送回服务器。这是它的回应。

此过程称为challenge/response.

下面是我用在本地工作组来进行验证时候抓取的数据包,可以看到在NTLM Server Challenge就是服务器返回的Challenge。并且下面还有一些服务器的信息(也就是我请求的对方)。

1.客户端访问服务器的某个服务(需要知道服务器用户和密码),并且需要身份认证。接着客户端输入服务器的用户名和密码来进行验证,输入之后客户端会缓存服务器密码的NTLM-Hash值。客户端发送TYPE 1 Negotiate 协商消息去协商需要认证的主体,用户(服务器端的用户名),机器以及需要使用的安全服务等等信息。

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

3.客户端收到服务端返回的 TYPE 2 消息, 读取出服务端所支持的内容,并取出其中的随机值Challenge,用缓存的服务器端密码的NTLM-Hash对其进行加密,并与用户名、Challenge等一起组合得到 Net-NTLMHash,最后将Net NTLM-Hash封装到 NTLM_AUTH 消息中(被称为 TYPE 3 消息, Authenticate认证消息),发往服务端

4.服务器在收到 Type3的消息之后,用自己的密码的 NTLM-Hash 对 Challenge 进行加密,并比较自己计算出的 Net NTLM-Hash 认证消息和客户端发送的认证消息是否匹配。如果匹配,则证明客户端掌握了正确的密码,认证成功,否则认证失败。

NTLM v1响应和NTLMv2响应的区别

v2是16位的Challenge,而v1是8位的Challenge

v1是将 16字节的NTLM hash空填充为21个字节,然后分成三组,每组7比特,作为3DES加密算法的三组密钥,加密Server发来的Challenge。将这三个密文值连接起来得到response。

v2是的加密算法是。

1.将Unicode后的大写用户名与Unicode后的身份验证目标(在Type 3消息的"TargetName"字段中指定的域或服务器名称)拼在一起。请注意,用户名将转换为大写,而身份验证目标区分大小写,并且必须与“TargetName”字段中显示的大小写匹配。使用16字节NTLM哈希作为密钥,得到一个值。

2.构建一个blob信息

3.使用16字节NTLMv2哈希作为密钥,将HMAC-MD5消息认证代码算法加密一个值(来自type 2的Challenge与Blob拼接在一起)。得到一个16字节的NTProofStr。 将NTProofStr与Blob拼接起来形成得到response。至于选择哪个版本的响应由LmCompatibilityLevel决定。

4.下面这个是我在工作组中抓取的数据包,这里我的客户端是192.168.8.1,服务器为192.168.8.145,请求的用户名为administrator。红框选中的四个SMB流量的数据包就是NTLM认证的数据包了。

下面这个是我在工作组中抓取的数据包,这里我的客户端是192.168.8.1,服务器为192.168.8.145,请求的用户名为administrator。红框选中的四个SMB流量的数据包就是NTLM认证的数据包了。

协商阶段

先看一下type 1 协商的数据包,消息的主要结构如下:

这个数据包含了客户端支持和服务器请求的功能列表。里面有包含很多协商信息,都在Negotiate Flag里面,例如有机器信息,认证主体和安全服务信息等。和请求的名字意思一样嘛就是和服务器协商认证。

质询阶段

接着就是服务器用type2消息进行对客户端的响应了,包含服务器支持和同意的功能列表,并且此时服务器或生成一个Challenge返回给客户端。消息的主要结构如下:

第二个包就是服务器收到了客户端的type1协商之后读取里面的内容。这个数据包最总要的东西就是服务器生成的随机的 Challenge 值了,在数据包 NTLM Server Challenge里面,值为f1d2047ca04f3cc6

身份验证阶段

接着客户端收到了服务器发过来的type2消息并且读取里面的内容取其Challenge,并且用缓存的NTLM-Hash对这个Challenge,也就是使用将要登陆到账户对应的NTLM Hash加密Challenge,将response,username,challenge发给服务器。这里最重要的就是response部分了。

可以查看到数据包,下面有一个请求的Host也就是我,请求对方服务器用户administrator。上面有一个NTLMv2的Response数据,底下有包含有NTLMv2 Client Challenge,也就是客户端加密生成的Challenge值为3f8439f98404ba3c

在type3中的响应,有六种类型的响应

LM(LAN Manager)响应 - 由大多数较早的客户端发送,这是“原始”响应类型。

NTLM v1响应 - 这是由基于NT的客户端发送的,包括Windows 2000和XP。

NTLMv2响应 - 在Windows NT Service Pack 4中引入的一种较新的响应类型。它替换启用了 NTLM版本2的系统上的NTLM响应。

LMv2响应 - 替代NTLM版本2系统上的LM响应。

NTLM2会话响应 - 用于在没有NTLMv2身份验证的情况下协商NTLM2会话安全性时,此方案会更改LM NTLM响应的语义。

匿名响应 - 当匿名上下文正在建立时使用; 没有提供实际的证书,也没有真正的身份验证。“存 根”字段显示在类型3消息中。

这六种使用的加密流程一样,都是前面我们说的Challenge/Response 验证机制,区别在Challenge和加密算法不同。

Challenge/Response验证机制里面type3 response里面包含Net-ntlm hash,NTLM v1响应和NTLMv2响应对应的就是Net-ntlm hash分为Net-ntlm hash v1和Net-ntlm hash v2。

Net-ntlm hash v1的格式为:

username::hostname:LM response:NTLM response:challenge

爆破Net-ntlm hash v1

hashcat -m 5500 username::hostname:LM response:NTLM response:challenge /tmp/password.list -o found.txt --force

说明:

-m:hash-type,5500对应NetNTLMv1,详细参数可查表:https://hashcat.net/wiki/doku.php?

-o:输出文件,字典文件为/tmp/password.list

–force代表强制执行,测试系统不支持Intel OpenCL

这里提取出NTLMv2的Response数据:Net-NTLM Hash格式为 username::domain:challenge:HMAC-MD5:blob

username:需要访问的服务器用户名,我这里就是User name:administrator

domain:访问者的主机名或者IP,这里就是Host Name:WIN-KBG0AISIT8K

challenge:服务端加密生成的Challenge值为f1d2047ca04f3cc6

HMAC-MD5:这个值就是数据包中的NTProofStr值为:6f8b51a619084f85dc6931b19b7fc7bb

blob:数据包中Response去掉NTProofStr的后半部分值为:01010000000000009f63092823f2d601b772ccdbbf7aeabf00000000020006004f004e0045000100060044004500560004000e006f006e0065002e0063006f006d00030016006400650076002e006f006e0065002e0063006f006d0005000e006f006e0065002e0063006f006d00070008009f63092823f2d6010600040002000000080030003000000000000000000000000030000034735f9e07f7051a8aa580472e67889dfe7353f39803a7c365a039cdcf1487100a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0038002e00310037003100000000000000000000000000

接着下面这个就是完全拼接好了的Net-NTLM Hash了。需要注意的是这里的challenge是type2 服务器返回的challenge不是type3 流量包里面的client Challenge

hashcat.exe -m  5600 administrator::WIN-KBG0AISIT8K:f1d2047ca04f3cc6:6f8b51a619084f85dc6931b19b7
fc7bb:01010000000000009f63092823f2d601b772ccdbbf7aeabf00000000020006004f004
e0045000100060044004500560004000e006f006e0065002e0063006f006d00030016006400
650076002e006f006e0065002e0063006f006d0005000e006f006e0065002e0063006f006d0
0070008009f63092823f2d60106000400020000000800300030000000000000000000000000
30000034735f9e07f7051a8aa580472e67889dfe7353f39803a7c365a039cdcf1487100a001
000000000000000000000000000000000000900240063006900660073002f00310039003200
2e003100360038002e0038002e00310037003100000000000000000000000000 pass.txt –force

说明:

-m:hash-type,5600对应NetNTLMv2,详细参数可查表https://hashcat.net/wiki/

–force代表强制执行,测试系统不支持Intel OpenCL

在域环境在中可以使用Kerberos和NTLM认证方式来对用户认证,域内一般情况下都是使用Kerberos认证作为默认方式。但是在域内使用NTLM 认证的话由于用于的 NTLM Hahs不存储在服务器上面而是存储在域控制器上,如果用户想要通过NTLM 认证来访问到服务器的话,需要把验证身份这个工作委托给域控制器,因为所有的Hash都存储在域控制器的NTDS.DIT的文件中,该文件是所有域用户的数据库。

所以当到了用户发送Challenge过去给服务器的时候,服务器会Netlogon服务,该服务能够与域控制器建立安全连接。此安全连接称为安全通道。之所以可以建立这种安全连接,是因为服务器知道自己的密码,而域控制器也知道服务器密码的哈希值。他们可以安全地交换会话密钥并安全地进行通信。通过这个通道来完成之后的身份验证任务。

这一步只是在普通工作组环境中多出了后面的几个步骤:

用户登录客户端电脑

(type 1)客户端向服务器发送type 1(协商)消息,它主要包含客户端支持和服务器请求的功能列表。

(type 2)服务器用type 2消息(质询)进行响应,这包含服务器支持和同意的功能列表。但是,最重要的是,它包含服务器产生的Challenge。

(type 3)客户端用type 3消息(身份验证)回复质询。用户接收到步骤3中的challenge之后,使用用户hash与challenge进行加密运算得到response,将response,username,challeng发给服务器。消息中的response是最关键的部分,因为它们向服务器证明客户端用户已经知道帐户密码。

服务器拿到type 3之后,使用challenge和用户hash进行加密得到response2与type 3发来的response进行比较。如果用户hash是存储在域控里面的话,那么没有用户hash,也就没办法计算response2。也就没法验证。这个时候用户服务器就会通过netlogon协议联系域控,建立一个安全通道,然后将type 1,type 2,type3 全部发给域控(这个过程也叫作Pass Through Authentication认证流程)

域控使用challenge和用户hash进行加密得到response2,与type 3的response进行比较

NTLM安全问题之:PTH

由于在NTLM认证的时候使用的就是Hash来进行计算,而不是明文密码来进行加密,所以我们可以在模拟登录的时候就使用Hash来进行验证而可以不使用明文密码来进行登录。在进行PTH的时候有很多工具可以给我们进行使用。最经典的就是使用mimikatz来进行PTH了。下图就是利用mimikatz来进行PTH攻击。

除了mimikatz之外,还有一个自动化可以批量PTH的工具crackmapexec,这里的命令如下:

crackmapexec smb 192.168.8.0/24 -u USERNAME -H HASH -x COMMAND

KB2871997 补丁

但是PTH攻击其实是很早以前的技术了,并且微软2014年5月13日发布了针对Pass The Hash的更新补丁kb2871997来防御这个攻击,我这里的实验操作系统是Windows 2016 Server,早已经打了这个补丁,但是就想上图显示我成功的达到了PTH攻击。因为这个补丁kb2871997对于本地Administrator(rid为500,操作系统只认rid不认用户名,接下来我们统称RID 500帐户)和本地管理员组的域用户是没有影响的。如下如所示,administrator的SID是500

如下图所示,这里PTH失败了。是因为user0x2这个用户的RID不是500的值,即使你这个用户是管理员组又如何,所以RID不是500的用户都被这个补丁的拦截了。

所有这些问题的真正罪魁祸首是远程访问上下文中的用户帐户控制(UAC)令牌筛选。 对于远程连接到Windows Vista +计算机的任何非RID 500本地管理员帐户,无论是通过WMI,PSEXEC还是其他方法(有个例外,那就是通过RDP远程),即使用户是本地管理员,返回的令牌都是已过滤的管理员令牌。当用户试图远程访问一个特权资源(例如 admin$)时,他们会收到一条"Access is Denied"消息。

但是如果把注册表项HKLMSOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystemLocalAccountTokenFilterPolicy 键存在的话(默认情况下不存在)并设置为了1,那么在协商期间,管理员用户组的所有本地成员的远程连接都被授予完全高完整性的令牌。这样非 rid 500帐户连接不会被过滤,并且可以成功地传递哈希!

reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\system /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f

在 Windows Vista 时代,微软就通过将LocalAccountTokenFilterPolicy 值默认设置为 0 来禁止非administrator账号的远程连接(包括哈希传递攻击),在打了KB2871997 补丁的机器上,通过将LocalAccountTokenFilterPolicy设置为1,也是可以通过非RID为500的账户PTH的。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 黑白天实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
多因子身份认证
多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档