摘要
2020年08月12日,Windows官方
发布了 NetLogon 特权提升漏洞
的风险通告,该漏洞编号为 CVE-2020-1472
,漏洞等级:严重
,漏洞评分:10分
。
攻击者通过NetLogon(MS-NRPC),建立与域控间易受攻击的安全通道时,可利用此漏洞获取域管访问权限。成功利用此漏洞的攻击者可以在该网络中的设备上运行经特殊设计的应用程序
影响版本
- 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)
本文主要包含原理说明与复习两部分,翻译原文如下:https://www.secura.com/pathtoimg.php?id=2055
特别感谢伍默师傅在复现过程中给出的指导性建议,复现图均来自伍默师傅。
翻译:
这份白皮书描述了CVE-2020-1472的一些技术细节(我们称之为“Zerologon”),这是WindowsServer中 的一个关键漏洞,它从微软获得了10.0的CVSS评分。为了缓解这一问题,强烈建议在所有ActiveDirectory域控制器上安装微软2020年8月的安全补丁。离开一个DC未补丁将允许攻击者妥协,并给自己域管理特权。攻击者唯一需要的就是能够与易受攻击 的DC建立TCP连接。他们需要在网络上站稳脚跟,但不需要任何域凭据。针对Zerologon的补丁还实现了一些额外的深入防御措施,迫使域连接的机器使用Netlogon协议先前 可选的安全特性。在2021年2月的更新将进一步收紧这些限制,这可能会打破一些第三方设备或软 件。请注意,在所有域控制器(也包括备份和只读)上安装2020年8月补丁足以阻止这里描述的高影 响开发。有关更多信息,请参阅微软关于这些更改的指南。如果您想确保您不受伤害,您可以使用我们发布的测试工具,并可以从我们的GitHub回购下载。我们 不会发布一个完整的工作概念证明漏洞,但我们的评估是,这种漏洞可以由恶意行为者构建,并付出一 定的努力,基于补丁的CVE单独。https://github.com/SecuraBV/CVE-2020-1472 这里描述的攻击利用了密码认证协议中的缺陷,该协议证明了域连接计算机与DC的真实性和身份。由于AES操作模式的不正确使用,有可能欺骗任何计算机帐户的身份(包括DC本身的身份),并在域中为 该帐户设置一个空密码。
脆弱性细节 的Netlogon协议
Netlogon Remote Protocol是一个在Windows域控制器 上可用的RPC接口。它用于与用户和机器身份验证相关 的各种任务,最常见的是方便用户使用NTLM协议登录到 服务器。其他功能包括身份验证 NTP响应,特别是:允许计算机在域内更新其密码。通 过TCP分配的动态端口购买域控制器的“portmapper”服 务,或者通过端口445上的SMB管道,RPC接口可以在TCP 上使用。
这个协议有趣的是它不使用与其他RPC服务相同的身份 验证方案。相反,它使用定制的密码协议来让客户端 (域连接计算机)和服务器(域 控制器)向对方证明他们都知道一个共同的秘密。此共 享秘密是客户端计算机帐户密码的散列。其原因是,在 Windows NT时代,计算机帐户没有使用一流的原则,因 此它们无法使用标准用户身份验证方案,如NTLM或 Kerberos。
客户端启动Netlogon会话,客户端和服务器通过该会话 相互交换随机的8字节非ces(称为客户端和服务器挑战。它们都通过使用密钥派生函数将两个挑战与共享秘密混 合来计算会话密钥。然后客户端使用此会话密钥计算客 户端凭据。服务器重新计算这个相同的凭据值,如果它 匹配,则得出结论,客户端必须知道会话密钥,因此客 户端也必须知道计算机密码。
在认证握手期间,双方可以协商是否要对后续消息进行 密封和签名(加密和加密认证),这对于防止网络级攻 击者是必不可少的。当加密被禁用时,执行重要操作的 所有Netlogon调用仍然必须包含一个身份验证器值,该 值也是使用会话密钥计算的。
实现密码协议是很棘手的:一个小的监督可能导致各种 方法绕过该方案的预期功能(在这种情况下:计算机身 份验证和传输安全)。由于我不知道对该协议的任何已 发表的安全审计,我决定亲自深入研究它。
最初,我主 要是寻找中间人攻击,假设攻击者可以看到和修改合法 客户端和服务器之间的流量。结果,可能 CVE-2019- 1424 (https://www.secura.com/blog-cve-2019-1424)用于获得对客户端系统的本地管理访问,攻击者可以看 到和修改流量。然而,后来,当更仔细地检查用于初 始身份验证握手的密码学时,我发现了一个更严重的一 般身份验证旁路,它可以由任何能够与域控制器建立TCP 连接的攻击者进行。
核心漏洞:不安全地使用AES-CFB8客户端和服务器用 于生成凭据值的加密原语是在一个名为 ComputeNetlogon凭据的函数中实现的,如定义的那 样。协议 规格 (https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-NRPC/[MS-NRPC].pdf)此函数接受8字节输入,并在其上执行 秘密会话的转换 产生等长输出的键。其背后的基本假设是,不知道会 话密钥的攻击者将无法计算或猜测匹配某一输入的正确 输出,从而允许它被用来证明会话密钥的知识。这个函数有两个版本:一个基于2DES,一个基于AES的 更新版本。
使用哪一个取决于客户端在身份验证期间 设置的标志。然而,现代版本的WindowsServer的默认配置将拒绝使用 2DES方案进行身份验证的任何尝试。
因此,在大多数领 域,只能使用AES方案。有趣的是,正是这种更新我发现漏洞的计划。旧版本不受这种特定攻击的影响 (尽管由于其他原因,2DES仍然被认为是不安全的)。基本的AES分组密码操作需要16个字节的输入,并将其 置换为大小相等的输出。为了加密较大或较小的输入, 必须选择操作模式。计算Netlogon凭据函数只需要转换 8个字节,它使用了相当模糊的函数。cfb8 (8位 密码 反馈) (https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CFB)模式 这种模式比AES使用的任何更常见的操作模 式慢大约16倍,这可能解释了为什么它没有被广泛使用。
AES-CFB8通过将一个16字节的“初始化向量”预先写 入明文来加密明文的每个字节,然后将AES应用于IV 明 文的前16个字节,取AES输出的第一个字节,并将其与 下一个明文使用XOR。如图2所示。
为了能够加密消息的初始字节,必须指定一个初始 化向量(IV)来引导加密过程。此IV值必须是唯一 的,并为每个使用相同密钥加密的单独明文随机生 成。然而,计算Netlogon凭据函数定义了这个IV 是固定的,并且应该始终由16个组成 零字节。这违反了安全使用AESCFB8的要求:它的安全属 性只有在IVs是随机的时才成立。
所以,这真的是个问题吗?全零IV会出什么问题?因 为CFB8的默默无闻,我可以 没有找到任何关于这个主题的文献。因此,我试图自 己想出一些选择的明文攻击,并找到了一些有趣的东 西:对于每256个密钥中的1个,将AESCFB8加密应用于 全零明文将导致全零密文。图3显示了为什么会出现这 种情况。
事实上,这个属性更一般一点:当IV只由零组成时, 将有一个整数0≤X≤255,它认为以值X的n字节开始的 明文将有一个以值0的n字节开始的密文。X依赖于加 密密钥并随机分布。
为了攻击Netlogon,我们不需要更一般的属性:足以知 道全零输入可以导致全零输出。所以让我们看看我们如 何利用这一点。
利用步骤1:欺骗客户端凭据后,与NetrServer Req挑 战调用交换挑战,然后客户端通过执行 NetrServerAuthenticate3调用来验证自己。
此调用有 一个名为Client Credential的参数,它是通过将 Compute Netlogon Credential应用于上一次调用中发送 的客户端挑战来计算的。
由于这个挑战实际上可以由我 们任意选择,没有什么可以阻止我们将这个挑战设置为8 个零。这意味着1英寸 256个会话密钥,正确的客户端证书也将由8个零组成!那么,我们如何知道会话使用这些键之一呢?嗯, 我们没有。
但是每次我们尝试这样进行身份验证 时,服务器仍然会产生一个唯一的服务器挑战,这个 挑战也是会话密钥的一个参数 派生。这意味着会话密钥对于每次身份验证尝试都是不 同的(并且是均匀分布的。由于计算机帐户在无效登录 尝试后没有锁定,我们可以简单地尝试很多次,直到我 们击中这样的密钥并验证成功。
预期需要的平均尝试次 数为256次,实际上只需要大约3秒。使用这种方法,我们可以作为域中的任何计算机登录。这包括备份域控制器,甚至目标域控制器本身!
利用步骤2:禁用签名和密封,而步骤1允许我们绕过身 份验证调用,但我们仍然不知道会话密钥的值是多少。
这变得有问题,因为Netlogon的传输加密机制(“RPC签 名和密封”)使用了这一点 关键但与弱势群体完全不同的方案 计算Netlogon凭据函数。幸运的是,对我们来说,签名和密封是可选 的,并且可以通过简单地不在其中设置标志来禁 用 Netr Server Authenticate3调用。
默认情况下,当 服务器没有设置此标志时,现代客户端将拒绝连接(可 能是防止降级攻击的措施),但服务器不会拒绝不请求 加密的客户端。我认为这可能是维护遗留兼容性的设计选择。由于我们在这次攻击中充当客户端,我们可以简单地省 略标志并继续。
利用步骤3:欺骗电话 即使调用加密被禁用,每一个做一些有趣的事情的 调用都必须包含一个所谓的认证器值。此值是通过 将计算Netlogon凭据(带会话密钥)应用于客户端存 储凭据 时间戳的值来计算的。
客户存储凭据是客户维护的增量值。在执行握手时, 它被初始化为与我们提供的客户端凭据相同的值。此 客户端凭据仅由零组成,因此在身份验证后执行的第一 次调用的客户端存储凭据将为0。时间戳应该包含当前的Posix时间,并包含在客 户端的调用中 认证者。
然而,事实证明,服务器实际上并没有对这个 值进行许多限制(这很有意义,否则时钟倾斜会变得非常 麻烦),所以我们可以简单地假装它是1月1日 圣 1970 年,并将此值设置为0。如果我们通过步骤1,我们也知道计算Netlogon凭据 (0)=0。因此,我们可以通过简单地提供全零认证器和 全零时间戳来验证我们的第一次调用。
利用步骤4:更改计算机的AD密码 因此,现在我们可以像任何计算机一样发送Netlogon电 话,我们该怎么办?有许多与帐户数据库复制相关的调 用,但自从引入ActiveDirectory以来,这些调用已经被 禁用,因此不幸的是,我们不能使用它们来提取凭据。
另一个有趣的调用是Netr Server Password Get,它允许获得计算机密码的NTLM散列。不幸的是,这个散列是 用会话密钥加密的,使用了另一种机制,所以这对我们 不有用。然而,我们可以利用的是Netr服务器密码Set2调用。用于为客户端设置新的计算机密码。此密码没有散列, 但它是用会话密钥加密的。怎么做?再次使用CFB8与 全零IV!
Netlogon协议中的明文密码结构由516字节组成。最后 四个字节表示以字节为单位的密码长度。结构中不属于 密码函数的所有字节都被视为填充,并且可以具有任意 值。如果我们只是在这里提供516个零,这将被解密为516 个零,即。零长度密码。事实证明,为计算机设置空 密码是完全不被禁止的,所以这意味着我们可以为域中 的任何计算机设置空密码!(见图4。)
能够对域进行身份验证,并且只能通过手动操作重新同 步。因此,在这一点上,我们已经有了一个相当危险的 拒绝服务的漏洞,允许我们从域中锁定任何设备。此 外,当计算机帐户在域内拥有特殊权限时,这些权限现在 可以被滥用。
开发步骤5:从密码更改到域管理 我们可以更改密码的计算机之一是域控制器本身的计算 机,即使这是 我们连接到Netlogon上的同一个域控制器。这样做会产 生一种有趣的情况,其中存储在AD中的DC密码与存储在其 本地注册表中的密码不同(在 HKLMSECURITYPolicySecret$机器上。acc)。这似 乎导致DC以各种不可预测的方式行为不端(例如,在我的 实验室设置中,它的DNS解析器停止工作)。作为攻击者,我们希望使用它使用自己的密码登录到 DC,这样我们就可以折衷它。
然而,只有当DC使用存储在AD中的密码来验证我们的 登录尝试,而不是本地存储的密码时,这才有效。经 过一些实验,我发现简单地使用新的DC密码运行 Impacket的“秘密转储”脚本是有效的。这个脚本将 成功 通过域复制服务(DRS)协议从域中提取所有用户散列。这包括域管理员散列(包括“krbtgt”键,它可以用来创 建金票),然后可以用来登录到DC(使用标准的通行攻 击) 并更新存储在DC本地注册表中的计算机密码。现在 DC再次正常工作,攻击者已成为域管理员。
结论
通过简单地发送一些Netlogon消息,其中各种字段都填充了零,攻击者可以更改存储在AD中的域控制器的计算机密 码。然后,这可以用于获得域管理凭据,然后恢复原始DC 密码。
这种攻击产生了巨大的影响:它基本上允许本地网络上 的任何攻击者(例如恶意内部人员或仅仅将设备插入到 预先设置的网络端口的人)完全破坏Windows域。攻击 完全没有身份验证:攻击者不需要任何用户凭据。
在2020年8月星期二的补丁上发布的补丁通过执行安全 NRPC来解决这个问题(即。域中所有Windows服务器和客 户端的Netlogon签名和密封),打破了第2步的漏洞。
此外,我的实验表明,步骤1也被阻塞,即使不掉标志/印章标志。我不知道这到底是如何实现的:可能是通过阻塞身 份验证尝试,其中客户端凭据字段以太多的零开始。我 没有成功地绕过这张支票。无论哪种方式,Zerologon 攻击,如这里所描述的,如果安装了补丁,将不再工作。
如果存在绕过步骤1保护的实际方法(可能涉及大量额外 的强制执行),这可能会使未强制执行Secure NRPC的遗 留或第三方设备面临风险。然后,攻击者仍然可以重置 存储在AD中的这些设备的计算机密码,这将通过有效地断 开这些设备与域的连接来拒绝服务。这也可能允许类似 中间人攻击,攻击者可以通过这种攻击获得对这些特定设 备的本地管理访问。CVE-2019-1424 (https://www.secura.com/blog-cve-2019-1424)
为了解决这个剩余的风险,Windows将记录在域中存在 此类设备时的警告事件。还存在打开“强制执行模 式”的选项,该模式将授权安全NRPC对所有设备,即使 这将导致它们中断。在2021年2月,默认情况下将打开 这种执行模式,要求管理员事先更新、退役或白名单设 备,这些设备不支持SecureNRPC。
复现:
直接使用github上的exp进行攻击,exp地址如下:https://github.com/SecuraBV/CVE-2020-1472
直接使用exp攻击,效果图如下:
然后使用wmi获取shell权限
注:一定要恢复原来的密码,不然会导致DC脱域!!!!!
恢复方法,可以使用某些exp自带的方法,或者使用下面微软给出的方法
修复建议:
通过如下链接自行寻找符合操作系统版本的漏洞补丁,并进行补丁下载安装。
CVE-2020-1472 | NetLogon 特权提升漏洞
https://portal.msrc.microsoft.com/zh-CN/security-guidance/advisory/CVE-2020-1472