Windows 安全认证机制探究

0x00 简介

Windows 身份认证有 NTLM 和 Kerberos 两种协议,前者主要应用于 Windows NT 和 Windows 2000 Server 及之后的工作组环境,而后者则主要应用于 Windows 2000 Server 及之后的域环境。NTLM 是 Windows 早期版本的标准安全协议,认证过程相对简单;而 Kerberos 较之 NTLM 更高效、更安全,同时认证过程也相对复杂。本文将围绕这两种协议,对 Windows 安全认证机制中涉及到的内容进行初步探究。

0x01 Windows Hash 类型

Windows 系统使用两种方法对用户的密码进行哈希处理,它们分别是 LAN Manager 哈希(LM Hash)和 NT LAN Manager 哈希(NTLM Hash)。

LM 型哈希

LM Hash 是 Windows 系统所用的第一种密码哈希算法,它只有一个版本且一直用到了 NTLM 哈希的出现,在 Windows Vista 和 Windows Server 2008 以前的系统中使用。

LM 型哈希对一个密码的处理过程如下:

  1. 将用户的明文口令全部转换成大写形式(用户口令被限制为最多14个字符);
  2. 将口令转换为16进制字符串,不足14个字节要求在后面用0补全;
  3. 将新得到的用户口令从中间一分为二,每一半分别包含7个字节;
  4. 将每部分转换成56 bit 的比特流,长度不足56 bit 要求使用0在左边补齐长度,再分7 bit 为一组末尾加0,组成新的64 bit编码;
  5. 将上述得到的两组8字节编码,分别作为 DES 密钥加密字符串 **KGS!@#$%**,得到两个8字节的16进制密文;
  6. 将两组8字节的密文拼接,最终得到 LMHash 值。

NTLM 型哈希

NTLM 型哈希也被称为 NTHash,由于 IBM 设计的 LM Hash 算法存在几个弱点,因此在 Windows Vista 和 Windows Server 2008 及之后的 Windows 系统中 LM Hash 被弃用,微软在保持向后兼容性的同时提出了自己的挑战响应机制,NTLM Hash 便应运而生。NTLM Hash 以 MD4 散列算法为基础,在实现起来实际上更为简单。

NTLM 型哈希对一个密码的处理过程如下:

  1. 将密码字符串转化为 ASCII 字符串(123456 -> 49 50 51 52 53 54);
  2. 将 ASCII 字符串转换为十六进制字符串(49 50 51 52 53 54 -> 31 32 33 34 35 36);
  3. 将十六进制字符串转化为 Unicode 字符串(31 32 33 34 35 36 -> 310032003300340035003600);
  4. 对 Unicode 字符串使用 MD4 散列算法,得到16字节的 NTLM Hash 值(310032003300340035003600 -> 32ed87bdb5fdc5e9cba88547376818d4)。

与 LM Hash 算法相比,NTLM Hash 对明文口令大小写敏感,且无法根据 NTLM Hash 判断原始明文口令是否小于8字节,摆脱了魔术字符串 KGS!@#$%。另外相较于 DES 加密,MD4 哈希算法被认为要强壮得多,因为它允许使用更长的密码,允许有大小写的不同,而且也无须把密码分割成更小、更易于被破解的块。

NTLM Hash 与 Net-NTLM Hash 的区别

NTLM Hash 通常是指 Windows 系统下 Security Account Manager 中保存的用户密码 hash,Net-NTLM Hash 通常是指网络环境下用于网络身份认证(例如 NTLM 认证)中的 hash,如 Net-NTLMv1 和 Net-NTLMv2。

Windows Hash 密码格式

格式为:用户名称:RID:LMHash:NTHash

例如:
Administrator:500:C8825DB10F2590EAAAD3B435B51404EE:683020925C5D8569C23AA724774CE6CC:::

表示:
用户名称为:Administrator
RID 为:500
LM Hash 值为:C8825DB10F2590EAAAD3B435B51404EE
NTLM Hash 值为:683020925C5D8569C23AA724774CE6CC

如果你知道某个用户的 NTLM Hash 密码了,可以使用 hashcat 进行破解,或者到 这个网站 进行在线破解。

Windows 下各类 HASH 比较

0x02 Windows 域和工作组

局域网上的资源需要管理,域(Domain)工作组(Work Group)就是两种不同的网络资源管理模式,两者之间的基本区别在于资源的共享方式和管理用户的方法不同,主要根据 LAN 的规模来区别使用,Windows 计算机不能同时属于域与工作组。

工作组

工作组是一群计算机的集合,它仅仅是一个逻辑的集合,组中每台计算机还是单独管理的,如果要访问其中的计算机,则需要到被访问计算机上进行用户验证,这增加了访问的复杂程度。例如想要通过工作组控制用户访问共享文件,当一台计算机设定了密码后,其他计算机每次在访问这台电脑中的共享文件时都必须输入密码。

加入工作组的方法很简单,如果在 LAN 上的计算机设置了相同的工作组名称,网络 中就会将这些计算机将显示在同一个工作组中。你可以随便加入同一网络上的任何工作组,也可以随时退出某个工作组,只要将工作组名称改动即可。工作组就像一个可以自由加入和退出的俱乐部一样,它本身的作用仅仅是提供一个“房间”,以便同一 LAN 下的计算机可以共享资源。

与工作组的松散的“会员制”有所不同,域是一个相对严格的组织,是一个有 安全边界 的计算机集合。在同一个域中的计算机彼此之间已经建立了信任关系,在域内访问其他机器时,不需要在访问的计算机上再次进行身份验证。

在“域”模式下,至少有一台服务器负责每一台联入网络的计算机和用户的验证工作,相当于一个单位的门卫一样,这个服务器被称为 域控制器(Domain Controller,DC)。域控制器中包含了由这个域的账户、密码、属于这个域的计算机等信息。当计算机联入网络时,域控制器首先要鉴别这台计算机是否是属于这个域的,用户使用的账号/口令是否正确,认证成功后,再访问这个域中的共享文件时就无须每次输入密码了。

关于林根域的概念具体见这篇文章:图解域域树域林根域的含义

工作组和域的区别

域用户的帐号和密码是不在本机的,全部保存在域控制器上,而工作组中帐号和密码都保存在本地。

域和工作组适用的环境不同,域一般是用在比较大的网络里,工作组则较小。

在一个域中需要有一台域控服务器,对其他计算机的互相访问进行管理;而在工作组中所有的计算机都是对等的,也就没有了服务器和客户机之分,但是和域一样,工作组中也存在一台组控服务器(以选举的方式产生,不固定),用于存储和这个组相关的信息。如果一台计算机想访问组中其他的计算机时,首先也要找到这个组中的组控服务器,得到工作组的信息,然后继续访问。

0x03 NTLM 身份认证

NTLM 是 Windows NT 早期版本的标准安全协议,为用户提供认证、完整性和机密性保障,因向后兼容而被保留下来,有 NTLMv1,NTLMv2,NTLMv2 session 三种版本。

NTML 认证过程

NTLM 是一种挑战/响应(Challenge/Response)形式的验证机制,主要包括三类消息类型:

  • Type1 message:协商(negotiation)

    客户端在发起认证时,首先向服务器发送协商消息。协商需要认证的主体、用户、机器以及需要使用的安全服务等信息,并通知服务器自己支持的协议内容、加密等级等。

  • Type2 message:挑战(challenge)

    服务器在收到客户端的协商消息之后,会读取其中的内容,从中选择出自己所能接受的服务内容,比如加密等级,安全服务等,并生成一个随机数 challenge,然后生成挑战消息返回给客户端。

  • Type3 message:认证(authentication)

    客户端在收到服务器返回的 challenge 消息后,读取服务器所支持的内容和随机数 challenge,决定服务器所支持的内容是否满足自己的要求。如果满足,则使用自己的 password hash 加密 challenge, 并最终生成一个认证消息发送给服务器。

下面来详细解析 NTLM 验证过程,一共分为七步:

  1. 用户访问客户端计算机并提供域名(domain name)、用户名(user name)和口令(password)。在客户端计算口令的Hash值并保存在本地;
  2. 客户端(Client)将用户名发送给服务器(以明文形式);
  3. 服务器(Server)生成一个16字节的随机数,称为challenge或nonce,并将其发送给客户端;
  4. 客户端收到challenge后,复制一份拷贝,然后将其中一个challenge使用用户口令的单向散列(password hash)加密,之后作为response发送给服务器。这叫做响应。
  5. 服务器在收到客户端传送过来response后,将user name,challenge以及response这三份内容发送给域控制器DC。
  6. DC在收到user name,challenge,response后,根据user name在SAM数据库(Security Account Manager database)中找到其对应的password hash,然后用这个password hash加密challenge,得到challenge-hash;
  7. DC将它计算出的challenge-hash(步骤6)与客户端计算出的response(步骤4)进行比较。如果他们相同,则验证成功。之后DC会将验证结果发给Server,并最终返回给Client。(如果是使用本地用户身份进行认证,则由Server本身完成认证过程。)

注:在 Microsoft NTLM 中提到让我们不要直接使用 NTLM,而是使用 negotiate。由于 Kerberos 的安全性要比 NTLM 更高,在 negotiate 情况下 Windows 会判断 Kerberos 是否可用,如果可用就优先使用 Kerberos,否则才会使用 NTLM。

SSPI & SSP

SSPI(Security Support Provider Interface )是 Windows 定义的一套接口,此接口定义了与安全有关的功能函数;SSP(Security Support Provider)是 SSPI 的实现者,用于提供安全功能,比如 NTLMSSP(NTLM Security Support Provider)就为 NTLM 认证的实现提供了基本功能,类似的还有 Negotiate、Kerberos、CredSSP、DigestSSP、NegotiateSSP 等。

注:由于 NTLMSSP 只是实现了 NTLM 认证,它并没有规定使用什么协议来进行传输。实际上 SMB、HTTP、LDAP、MSSQL 等协议都可以携带 NTLM 认证的三类消息,也就是说我们可以通过这些协议来进行攻击。

NTLM-Relay & PTH

NTLM-Relay 和 Pass the Hash(PTH)在某些部分有些相似,但实际上是完全不同的两个东西。NTLM-Relay 针对的是用于网络认证的 Net-NTLM Hash,而 LMHash 或者 NTHash 从严格意义上讲,可以用来进行 pass the hash attack,但并不能进行 relay attack。

通常我们使用 Responder 等工具获取到的就是 Net-NTLM Hash,这类 hash 并不能直接用来 PTH,但可以通过暴力破解来获取明文密码。

Pass the Hash 在内网渗透中是一种很经典的攻击方式,原理就是攻击者可以直接通过传递 LM Hash 和 NTLM Hash 访问远程主机或服务,而不用提供明文密码。如果内网主机的本地管理员账户密码相同,即可通过 Pass the Hash 远程登录到任意一台主机。

利用 Pass the Hash 的渗透方式如下:

  1. 获取某一台域主机管理员权限;
  2. Dump(抓取)内存获取用户 hash;
  3. 通过 Pass the Hash 尝试登录其他主机;
  4. 继续搜集 hash 并尝试远程登录;
  5. 直到获得域管理员账户 hash,登录域控,最终成功控制整个域。

这类攻击适用于:

  • 域/工作组环境
  • 可以获得 hash,但条件不允许对 hash 进行爆破
  • 内网中存在和当前机器相同的密码

PTK

随着大家对 Pass the Hash 的认识越来越高,防御方法也越来越多,微软在2014年发布了更新补丁 kb2871997 禁止本地管理员账户用于远程连接,这样就无法以本地管理员用户的权限执行 WMI、psexec、schtasks、at 和访问文件共享。同样,禁用 NTLM 也使得 psexec 无法利用获得的 NTLM Hash 进行远程连接。

然而,安全研究人员在测试中发现,打了补丁之后,常规的 Pass The Hash 已经无法成功,唯独默认的 Administrator(SID 500)账号例外,利用这个账号仍可以进行 Pass The Hash 远程连接(2014)。

所以对于防御方来说,即使打了补丁也要记得禁用 SID=500 的管理员账户。

由于 mimikatz 的出现, 再次改变了格局。国外安全研究人员开发的 mimikatz 实现了在禁用 NTLM 的环境下仍然可以远程连接,并且可以通过用户账户的 aes Key 进行远程连接,即利用 Pass the Key(PTK)

0x04 Kerberos 身份认证

Kerberos 一词来源于希腊神话,是一种基于 票据(Ticket)的认证方式,其中三个主体分别是客户端、服务器和第三方认证服务器 KDC。客户端用户在访问服务器前,需要先从第三方认证服务器 KDC 处获取许可证,只有通过合法性认证的用户,才能依据票据去访问所需的服务和应用。

在 Windows 域环境中,KDC 的角色由 DC(Domain Controller)来担当。

Kerberos 认证过程

一次完整的 Kerberos 身份认证流程,如图所示:

1)账号 A 和 KDC 互相认证

账号 A 利用 hash 函数把密码转化成一把密钥,我们称它为 Kclt,用 Kclt 加密当前时间戳,生成一个字符串 {时间戳}Kclt。把上一步生成的字符串 {时间戳}Kclt、账号 A 的信息,以及一段随机字符串发给 KDC。这样就组成了 Kerberos 的身份认证请求 AS_REQ

KDC 收到 AS_REQ 之后,先读到账号 A 的信息,于是便调出 A 的密码,再用同样的 hash 函数转化为 Kclt。有了 Kclt 就可以解开{时间戳}Kclt,如果能成功解开,则说明该请求是由账号 A 生成的,即完成对账号 A 的身份认证。

接下来轮到 KDC 向账号 A 证明自己的身份,KDC 使用 Kclt 加密随机字符串,回复给账号 A,如果账户 A 拿到回复后能够解出随机字符串,则说明 KDC 为真。

同时,KDC 生成两把一样的密钥 Kclt-Kdc,用于以后账户 A 和 KDC 之间互相认证,这样就省去了每次都要调出账号 A 的密码和 hash 等工作。其中一把密钥发给账户 A 保管,另一把由 KDC 把自己的密码 hash 成 KKdc,然后用它加密另一把委托给 A 的密钥,把这个委托的密钥称为 TGT(Ticket Granting Ticket),TGT = {账户 A 的信息, Kclt-kdc},返回 AS_REP = TGT, {Kclt-kdc, 时间戳, 随机字符串}Kclt。

账号 A 收到 AS_REP 后利用 Kclt 解密信息,通过解开随机字符串和时间戳来确定 KDC 的真实性,然后把 Kclt-kdc 和 TGT 保存起来备用。

2)账号 A 请求 KDC 认证资源 B

首先 A 将 TGT 交还给 KDC,其次还有账号 A 的相关信息,当前时间戳,以及要访问的资源 B 的信息,生成 TGS-REQ

KDC 收到 TGS-REQ 后,先用 Kkdc 解密 TGT 得到 Kclt-kdc,再用 Kclt-kdc 解密出账号 A 的相关信息和时间戳来验证其身份。一旦确认账号A为真,就可以帮助 A 和 B 完成互相认证了。

KDC 生成两把同样的密钥 Kclt-srv 供 A 和 B 之间使用,其中一把密钥直接交给 A,另一把委托 A 交给 B。为了确保 A 不会受到假的资源 B 欺骗,Kerberos 把 B 的密码 hash 成 Ksrv,然后用它加密那把委托 A 交给 B 的 Kclt-srv ,成为一张只有真正的 B 能解开的 Ticket,Ticket = {账户 A 的信息, Kclt-srv}Ksrv,返回 TGS-REP = {Kclt-srv}Kclt-kdc, Ticket。

账号 A 收到 TGS-REP 后,先用 Kclt-kdc 解开 {Kclt-srv}Kclt-kdc,得到 Kclt-srv,再将 Ticket 保留着发给资源B。接下来如果需要多次访问资源 B,都可以使用同一个 Ticket,而不需要每次都向 KDC 申请

3)账号 A 和资源 B 互相认证

账号 A 给资源 B 发送 CS-REQ = {账号A的信息,时间戳}Kclt-srv, Ticket。如果资源 B 为真,则可以使用自己的 Ksrv 解开 Ticket,得到 Kclt-srv,从而可以解开 {账号A的信息,时间戳}Kclt-srv,这样资源 B 就可以确定账户 A 为真,然后回复 CS-REP = {时间戳}Kclt-srv,来证明自己也是真的。账号 A 解密 CS-REP,再通过时间戳来判断对方是否为真。

更详细的过程可参考《Wireshark网络分析就这么简单》中 Kerberos 的相关章节,作者的解释十分通俗易懂。

PTT

Pass the Ticket(PTT)是利用 Kerberos 协议进行的 Ticket 传递攻击,有三种常见的利用方法:MS14-068,Golden Ticket 和 Silver Ticket。

MS14-068

MS14-068 是 Windows 密钥分发中心(KDC)服务中的一个严重漏洞,其影响全部版本 Windows 版本的服务器,该漏洞允许攻击者提升任意普通域用户成为域管理员账户,攻击者可以利用这些提升的权限控制域中所有的计算机,包括域服务器。

漏洞的主要成因是由于 KDC 允许经过身份验证的用户在其 Kerberos 票证(TGT)中插入任意 PAC,当用户进行登录身份验证时,KDC 会验证 PAC 中的签名,并使用 PAC 中的数据为用户创建一个登录令牌,而 KDC 服务器端的 PAC signature 时没有严格控制使用 checksum 算法,导致客户端可以提交伪造的 PAC 欺骗 KDC 获取任意票证。

关于 MS14-068 漏洞的详细分析可以看这篇文章:深入解读 MS14-068 漏洞:微软精心策划的后门?

黄金票据(Golden Ticket)

该票据的利用条件是原先已成功取得 KDC(krbtgt 用户)的密码 hash(即 KKdc),并且还有一个普通域用户权限,在此条件下,我们可以利用 krbtgt 的 hash 值伪造生成任意用户的 TGT,绕过账号策略,让用户成为任意组的成员,还能利用该票据重新获得域管理员权限。

因为 krbtgt 只有域控制器上才有,使用黄金凭据意味着你之前拿到过域控制器的权限,所以可以理解为是一个后门。

白银票据(Silver Ticket)

通过分析 Kerberos 协议的认证过程不难发现,如果我们获取了 Server B 的秘钥 Ksrv,就可以跳过 KDC 的认证,直接伪造票据与 Server 通信。

Silver Ticket 和 Golden Ticket 不同的是,它不需要和域控制器进行通信,原理是伪造 TGS 服务器,使用计算机账户的 hash 进行加密,所以只能对单一的服务进行授权,访问指定的权限。而 Golden Ticket 的利用过程需要访问域控,原理是伪造 TGT,由 Kerberos 的 hash 进行加密,可以获取任何 Kerberos 服务权限。

Kerberoasting

2014年 SANS HackFest 大会上 Tim Medin 提出了一种新的攻击 Kerberos 的技术,他称之为 “Kerberoasting”。Tim 给出的利用方法是使用工具集的组合来请求票证,并从内存中提取票证,然后将它们转换为可破解的格式。更详细的技术细节,可以见 Tim 的 PPT 或 Cracking Kerberos TGS Tickets Using Kerberoast

0x05 相关利用工具

  • mimikatz:PTH、PTK、PTT 攻击,提取 Windows 明文密码、hash 值等凭据。
  • PowerView:PowerSploit 框架和 Empire 的一部分,用于内网信息搜集。
  • wmiexec:Windows WMIC 的强化版,可用于 PTH 攻击。
  • Kerberoast:Kerberoasting 利用工具包。
  • Responder:劫持 LLMNR 和 NBT-NS 请求,获取 Net-NTLM Hash。

参考文章:
腾讯安全玄武实验室 NTLM Relay Reloaded Attack methods you do not know.pdf
https://xz.aliyun.com/t/2445
http://www.tiejiang.org/23508.html
http://xnianq.cn/2018/10/16/%E5%9F%9F%E6%B8%97%E9%80%8F%E4%B9%8B%E6%A8%AA%E5%90%91%E7%A7%BB%E5%8A%A8/
https://www.cnblogs.com/bmjoker/p/10355979.html#autoid-0-0-0
https://www.4hou.com/technology/16263.html
https://3gstudent.github.io/3gstudent.github.io/%E5%9F%9F%E6%B8%97%E9%80%8F-Kerberoasting/