作者:天融信阿尔法实验室一、漏洞概述2019年6月,Microsoft发布了一条安全更新。该更新针对CVE-2019-1040漏洞进行修复。此次漏洞,攻击者可以通过中间人攻击,绕过NTLM MIC(消息完整性检查)保护,将身份验证流量中继到目标服务器。通过这种攻击使得攻击者在仅有一个普通域账号的情况下可以远程控制 Windows 域内的任何机器,包括域控服
2019年6月,Microsoft发布了一条安全更新。该更新针对CVE-2019-1040漏洞进行修复。此次漏洞,攻击者可以通过中间人攻击,绕过NTLM MIC(消息完整性检查)保护,将身份验证流量中继到目标服务器。 通过这种攻击使得攻击者在仅有一个普通域账号的情况下可以远程控制 Windows 域内的任何机器,包括域控服务器。
验证环境:
角色 | 系统版本 | 计算机名 | 地址 | 域 |
---|---|---|---|---|
Attacker | Ubuntu Server 18.04 | ubuntu | 192.168.123.69 | |
DC | Windows Server 2012 R2 | topsec-dc | 192.168.123.150 | test.local |
Exchange | Windows Server 2012 R2 | topsec | 192.168.123.143 | test.local |
验证过程: ① 环境搭建
②执行ntlmrelayx.py脚本进行NTLM中继攻击,设置SMB服务器并将认证凭据中继到LDAP协议。其中--remove-mic选项用于清除MIC标志,--escalate-user用于提升指定用户权限。
③ 执行printerbug.py脚本,触发SpoolService的bug。
④ SpoolService的bug导致Exchange服务器回连到ntlmrelayx.py,即将认证信息发送到ntlmrelayx.py。可以在下图中看到认证用户是TEST\TOPSEC$。
接着ntlmrelayx.py开始执行LDAP攻击,加上-debug选项后可以看到更详细的信息。 首先,通过遍历验证中继帐户所在用户组及权限,发现当前账户可以创建用户、可以修改test.local域的ACL,因为域中的Exchange Windows Permissions用户组被允许修改ACL,如下图所示:
该用户组下的成员正是中继的计算机账户TOPSEC:
因此脚本会首选修改ACL来提权,因为这相比创建用户的方式更隐秘一些。具体方式是通过LDAP修改域的安全描述符(Security Descriptor),可以在下面的数据包中看到ACL中每一条具体的访问控制条目(ACE,Access Control Entries):
⑤ 完成ACL的修改后,test就可以通过secretsdump.py的DCSync功能dump出所有密码哈希值:
验证环境:
角色 | 系统版本 | 计算机名 | 地址 | 域 |
---|---|---|---|---|
Attacker | Ubuntu Server 18.04 | ubuntu | 192.168.123.69 | |
DC | Windows Server 2012 R2 | topsec-dc | 192.168.123.212 | test.local |
SDC | Windows Server 2012 R2 | topsec | 192.168.123.62 | test.local |
验证过程: ① 环境搭建
② 和攻击方式一相同,执行ntlmrelayx.py本,使用--delegate-access选项,delegate-access选项将中继计算机帐户(这里即辅助域控制器)的访问权限委托给attacker。
③ attacker对辅助域控制器(SDC)执行printerbug.py脚本
③ printerbug.py脚本执行成功后,将触发辅助域控制器(SDC)回连Attacker主机,回连使用的认证用户是辅助域控制器(SDC)本地计算机账户TEST/TOPSEC。ntlmrelayx.py通过ldaps将该用户账户中继到域控服务器(DC),因为这种攻击方式下所冒用的身份TEST/TOPSEC并不在Exchange Windows Permissions组内,不具有修改ACL权限,但是可以通过此身份在DC上添加一个新计算机账户(下图中EJETBTTB
④使用getSP.py脚本,通过-impersonate参数模拟用户admin请求其票证,保存为ccache,admin用户为Domain Admins组的成员,具有对辅助域控制器(SDC)的管理与访问权限。
⑤ 使用上一步骤中保存的Kerberos服务票证,我们可以在目标主机(SDC)上模拟admin身份,从而执行任何操作,例如使用secretsdump转储哈希值。通过secretsdump dump出所有密码哈希值:
此次的攻击流程有如下两个方式:
下文出现的攻击流量图中,个角色与ip对应关系同上文验证环境搭建:
角色 | 系统版本 | 计算机名 | 地址 | 域 |
---|---|---|---|---|
Attacker | Ubuntu Server 18.04 | ubuntu | 192.168.123.69 | |
DC | Windows Server 2012 R2 | topsec-dc | 192.168.123.150 | test.local |
Exchange | Windows Server 2012 R2 | topsec | 192.168.123.143 | test.local |
下文标题内容,即为攻击流程,对应流程图中红框所示的流程 如果对SMB协议不是很清楚的读者,可以先参考技术点分析-客户端与服务器端的SMB通信一节内容 1. attacker使用普通AD账户登陆Exchange 在攻击的开始阶段,attacker需要确保拥有一个可使用的AD账号,这是满足触发SpoolService错误的必要条件。 首先attacker利用已拥有的AD账号,连接到远程服务器的打印服务(spoolsv.exe),下图是Attacker通过SMB2协议登陆Exchange流程和流量:
成功的通过该阶段,就可以请求对一个新的打印作业进行更新,令其将该通知发送给指定目标。
2. 触发SpoolService错误 attacker通过Printerbug脚本,触发Exchange服务器SpoolService错误,强制Exchange服务器通过MS-RPRN RPC接口向attacker进行身份验证。具体细节见技术点分析一章中的SpoolService/printer bug。下图是Attacker触发SpoolService错误payload流程和流量:
3. Exchange主机向Attacker发送Negotiate Protocol Request 在触发SpoolService错误后,Exchange服务器向Attacker进行身份验证,即发送Negotiate Protocol Request,这是客户端向服务器发送第一个SMB请求,可参考技术点分析-客户端与服务器端的SMB通信。下图是Exchange向Attacker发送SMB协商请求流程和流量:
在正常的业务场景中,用户想登陆并使用Exchange,往往需要向Exchange服务器发送SMB协商请求流量,以便验证身份并登陆。但由于SpoolService错误,在这里,Exchange向Attacker发送SMB协商请求流量,以便验证身份。这便造成了Attacker可以作为中间人身份中继此身份认证以冒充Exchange欺骗DC的机会。
4. Attacker将协商请求通过ldap中继到DC服务器 Attacker作为中间人,将Negotiate Protocol Request通过ldap请求中继到ad服务器 在此步骤以及以下攻击流程中,有需要将SMB身份验证通过LDAP中继至DC的环节。由于NTLM协议的工作方式,无法将SMB流量直接通过LDAP中继,因此需要对流量进行修改,而需改流量,势必需要绕过MIC验证,此处便是本次漏洞的重点,详情见技术点分析-MIC校验绕过部分
5. attacker向Exchange发送Negotiate Protocol Response
6. Exchange向attacker发送Session Setup Request
7. Attacker向DC中继Session Setup Request Attacker将Exchange发送来的Session Setup Request 中继给DC, DC将包含 CHALLENGE的Response发送给Attacker
8. Attacker 向exchange发送Session Setup Response(CHALLENGE) Attacker 将DC发出的包含challenge的Session Setup Response发送给exchange
9. exchange向Attacker发送包含了身份验证请求的Session Setup
我们可以看到上图中的认证用户为TEST\TOPSEC,而不是运行Exchange的SYSTEM账户,这是因为SYSTEM账户具有太高权限,如果用此帐户对网络资源进行身份验证,则会出现安全问题。所以当访问网络资源时,使用本地计算机的网络帐户对网络进行身份验(形式为domain\computername,即TEST\TOPSEC
10. Attacker向 DC中继含有Exchange的身份认证的Session Setup Request Attacker将身份认证请求中继到DC,并使用Exchange的身份认证通过DC认证
DC认证通过Exchange身份,并向Attcker发送认证通过的Response,此时,DC对Attacker的身份验证结束,Attacker成功冒用Exchange身份。 由于安装Exchange后,Exchange在Active Directory域中具有高权限,Exchange的本地计算机账户TOPSEC$会被加入用户组Exchange Trusted Subsystem,该用户组又隶属于Exchange Windows Permissions。Exchange Windows Permissions组可以通过WriteDacl方式访问Active Directory中的Domain对象,该对象允许该组的任何成员修改域权限,从而可以修改当前域ACL达到提权目的。 使用提权后的用户或计算机可以执行域控制器通常用于复制的同步操作,这允许攻击者同步Active Directory中用户的所有哈希密码。
下文出现的攻击流量图中,个角色与ip对应关系同上文验证环境搭建:
角色 | 系统版本 | 计算机名 | 地址 | 域 |
---|---|---|---|---|
Attacker | Ubuntu Server 18.04 | ubuntu | 192.168.123.69 | |
DC | Windows Server 2012 R2 | topsec-dc | 192.168.123.212 | test.local |
SDC | Windows Server 2012 R2 | topsec | 192.168.123.62 | test.local |
Kerberos委派攻击流程与Exchange攻击利用,在DC对Attacker的身份验证结束之前的阶段是类似的。区别在于后续提权过程,下面介绍下Kerberos委派攻击后续攻击流程。 在Attacker冒用SDC身份后,由于SDC计算机身份没有修改访问控制列表(ACL)的权限,无法直接提权。而后续提权利用中的S4U2Self不适用于没有SPN的帐户。在域环境中,任何域用户都可以通过MachineAccountQuota创建新的计算机帐户,并为其设置SPN。Attacker通过此方式新建一个域中的计算机账号。这一过程通过LDAP实现并设置账户与密码 ,如下图
DC上可见computers列表中新创建的名为EJETBTTB的计算机:
在域中新的计算机账户EJETBTTB(下图中的service A)建立成功后,后续攻击如下图攻击步骤
1. 攻击者为Service A配置了基于资源的约束委派 由于通过S4U2Self请求到的TGS forwardable标志位为 Non-forwardable,这意味着该TGS服务票据是不可转发的,不可以在接下来的S4U2Proxy中进行转发。但是不可转发的TGS竟然可以用于基于资源的约束委派,S4U2Proxy会接收这张不可转发的TGS。由于我们拥有Service A的计算机账号以及密码,所以在这里可以为Service A到SDC配置了基于资源的约束委派,将默认的约束委派更改为基于资源的约束委派,以便后续攻击。
2. Service A 调用S4U2Self向认证服务器(SDC)为admin请求访问自身的服务票据
通过国外安全研究员Elad Shami的研究可知,无论服务账号的UserAccountControl属性是否被设为TrustedToAuthForDelegation, 服务自身都可以调用S4U2Self为任意用户请求访问自己的服务票据,也就是说,这里Service A 可以调用S4U2Self向SDC为admin用户申请可访问自身的服务票据
4、 Service A通过S4U2Proxy 转发TGS,并为admin申请访问SDC票据
5、SDC将为admin用户申请的访问SDC的TGS发送给Service A 在这里,Service A为Attacker创建并控制,Attacker获得TGS票据,利用该票据以admin身份访问SDC,完成提权
在理清利用流程后,接下来详解利用流程中的技术点
补充介绍一些关于SMB通信协议相关内容,通过这部分内容,可以加深对的漏洞流程的理解。对SMB通信协议熟悉的读者,可以跳过此部分。 下图是客户端与服务器端的SMB通信流程:
SMB2 / Negotiate Protocol Negotiate Protocol是在SMB2的任何新TCP会话上发出的第一个SMB2命令,它用于协商要使用的协议版本。Negotiate Protocol命令分为Negotiate Protocol Request/ Negotiate Protocol Response两部分:
SMB2 / Session Setup SMB2 / Session Setup命令用于对用户进行身份验证并获取分配的UserID。此命令通常是SMB2 / Negotiate Protocol阶段完成后从客户端发出的第一个命令。Session Setup分为两部分:
在攻击利用流程中,需要使用到一个名为printerbug.py的工具,此工具触发SpoolService/printer bug,强制Windows主机通过MS-RPRN RPC接口向攻击者进行身份验证。 Windows的MS-RPRN协议用于打印客户机和打印服务器之间的通信,默认情况下是启用的。协议定义的RpcRemoteFindFirstPrinterChangeNotificationEx()调用创建一个远程更改通知对象,该对象监视对打印机对象的更改,并将更改通知发送到打印客户端。
任何经过身份验证的域成员都可以连接到远程服务器的打印服务(spoolsv.exe),并请求对一个新的打印作业进行更新,令其将该通知发送给指定目标。之后它会将立即测试该连接,即向指定目标进行身份验证(攻击者可以选择通过Kerberos或NTLM进行验证)。另外微软表示这个bug是系统设计特点,无需修复。
在本次漏洞的利用过程中,我们通过printerbug.py脚本触发了上述bug,强制Exchange服务器对攻击者(192.168.123.69)发起身份验证,而Exchange默认是以SYSTEM身份执行的。
下图是printerbug.py执行后的数据包:
在攻击利用流程中,需要将SMB身份验证通过LDAP中继至DC,由于NTLM协议的工作方式,无法将SMB流量直接通过LDAP中继,将SMB流量通过LDAP中继难点以及绕过思路如下:
NTLM身份验证由3种消息类型组成:
分别对应位于SMB协议中的SessionSetup阶段,下图就是Clinet与Server交互流程图和流量:
为了确保恶意行为者不在传输过程中处理消息,在NTLM_AUTHENTICATE消息中添加了一个额外的MIC(消息完整性代码)字段,如下图所示:
MIC是使用会话密钥应用于所有3个NTLM消息的串联的HMAC_MD5,该会话密钥仅对启动认证的帐户和目标服务器是已知的。因此,试图篡改其中一条消息的攻击者(例如,修改签名协商)将无法生成相应的MIC,这将导致攻击失败。
Microsoft服务器允许无MIC 的NTLM_AUTHENTICATE消息。 如果想要将SMB身份验证中继到LDAP,并完成中继攻击,可以通过如下步骤: 取消MIC校验以确保可以修改数据包中的内容:
在绕过MIC校验之后,可以修改NEGOTIATE_SIGN值以便将SMB流量顺利通过LDAP签名校验 将NEGOTIATE_SIGN设置为not set以绕过LDAP验证
为了实现SMB中继LDAP流程,这里使用ntlmrelayx.py工具作为中继
Ntlmrelayx中继流程如下: