2019年6月,Microsoft发布了一条安全更新。该更新针对CVE-2019-1040漏洞进行修复。此次漏洞,攻击者可以通过中间人攻击,绕过NTLM MIC(消息完整性检查)保护,将身份验证流量中继到目标服务器。

通过这种攻击使得攻击者在仅有一个普通域账号的情况下可以远程控制 Windows 域内的任何机器,包括域控服务器。

0x01 漏洞利用


攻击方式一:Exchange

验证环境:

角色 系统版本 计算机名 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

验证过程:

① 环境搭建

  • 安装配置域控制器
  • 安装配置Exchange Server,参考[1]
  • 在域中新建一个用于测试的账户test

②执行ntlmrelayx.py脚本进行NTLM中继攻击,设置SMB服务器并将认证凭据中继到LDAP协议。其中–remove-mic选项用于清除MIC标志,–escalate-user用于提升指定用户权限。

umDaAU.png

③ 执行printerbug.py脚本,触发SpoolService的bug。

umDdNF.png

④ SpoolService的bug导致Exchange服务器回连到ntlmrelayx.py,即将认证信息发送到ntlmrelayx.py。可以在下图中看到认证用户是TEST\TOPSEC$。

umDwh4.png

接着ntlmrelayx.py开始执行LDAP攻击,加上-debug选项后可以看到更详细的信息。

首先,通过遍历验证中继帐户所在用户组及权限,发现当前账户可以创建用户、可以修改test.local域的ACL,因为域中的Exchange Windows Permissions用户组被允许修改ACL,如下图所示:

umDB9J.png

该用户组下的成员正是中继的计算机账户TOPSEC

umDD39.png

因此脚本会首选修改ACL来提权,因为这相比创建用户的方式更隐秘一些。具体方式是通过LDAP修改域的安全描述符(Security Descriptor),可以在下面的数据包中看到ACL中每一条具体的访问控制条目(ACE,Access Control Entries):

umDrcR.png

⑤ 完成ACL的修改后,test就可以通过secretsdump.py的DCSync功能dump出所有密码哈希值:

umDsj1.png

攻击方式二:Kerberos委派

验证环境:

角色 系统版本 计算机名 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

验证过程:

① 环境搭建

  • 安装配置域控制器,同时开启LDAPS支持,因为该攻击方式需要添加新的计算机账户,必须在LDAPS进行。开启方法参考[2]
  • 安装配置辅助域控制器,参考[3]
  • 在域中新建一个用于测试的账户topsec,一个域管理员admin

② 和攻击方式一相同,执行ntlmrelayx.py本,使用–delegate-access选项,delegate-access选项将中继计算机帐户(这里即辅助域控制器)的访问权限委托给attacker。

umD6nx.png

③ attacker对辅助域控制器(SDC)执行printerbug.py脚本

umDcB6.png

printerbug.py脚本执行成功后,将触发辅助域控制器(SDC)回连Attacker主机,回连使用的认证用户是辅助域控制器(SDC)本地计算机账户TEST/TOPSEC$。

ntlmrelayx.py通过ldaps将该用户账户中继到域控服务器(DC),因为这种攻击方式下所冒用的身份TEST/TOPSEC$并不在Exchange Windows Permissions组内,不具有修改ACL权限,但是可以通过此身份在DC上添加一个新计算机账户(下图中EJETBTTB$), 并修改其约束委派授权,授予它对受害计算机(辅助域控制器)的委派权限。

umDgHK.png

umDWND.png

④使用getSP.py脚本,通过-impersonate参数模拟用户admin请求其票证,保存为ccache,admin用户为Domain Admins组的成员,具有对辅助域控制器(SDC)的管理与访问权限。

umDf4e.png

⑤ 使用上一步骤中保存的Kerberos服务票证,我们可以在目标主机(SDC)上模拟admin身份,从而执行任何操作,例如使用secretsdump转储哈希值。通过secretsdump dump出所有密码哈希值:

umD49H.png

0x02 漏洞细节


此次的攻击流程有如下两个方式:

1、Exchange攻击流程:使用任何AD帐户,通过SMB连接到目标Exchange服务器,并触发SpoolService错误。目标服务器将通过SMB回连至攻击者主机,使用ntlmrelayx将SMB身份验证中继到LDAP。使用中继的LDAP身份验证,为攻击者帐户授予DCSync权限。攻击者帐户使用DCSync转储AD中的所有密码哈希值。

2、Kerberos委派攻击流程:使用任何AD帐户,通过SMB连接到目标服务器,并触发SpoolService错误。目标服务器将通过SMB回连至攻击者主机,使用ntlmrelayx将SMB身份验证中继到LDAP。使用中继的LDAP身份验证,将目标服务器的基于资源的约束委派权限授予攻击者控制下的计算机帐户。攻击者作为受害者服务器上的任何用户进行身份验证。

Exchange攻击流程

下文出现的攻击流量图中,个角色与ip对应关系同上文验证环境搭建:

角色 系统版本 计算机名 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通信一节内容

attacker使用普通AD账户登陆Exchange

在攻击的开始阶段,attacker需要确保拥有一个可使用的AD账号,这是满足触发SpoolService错误的必要条件。

首先attacker利用已拥有的AD账号,连接到远程服务器的打印服务(spoolsv.exe)。

umDIgA.png

Attacker通过SMB2协议登陆Exchange流程

umDojI.png

Attacker通过SMB2协议登陆Exchange流量

成功的通过该阶段,就可以请求对一个新的打印作业进行更新,令其将该通知发送给指定目标。

触发SpoolService错误

attacker通过Printerbug脚本,触发Exchange服务器SpoolService错误,强制Exchange服务器通过MS-RPRN RPC接口向attacker进行身份验证。具体细节见技术点分析一章中的SpoolService/printerbug

umD7ut.png

Attacker发送SpoolService错误payload流程

umDHDP.png

Attacker通过printerbug向Exchange发送带有payload的流量

Exchange主机向Attacker发送Negotiate Protocol Request

在触发SpoolService错误后,Exchange服务器向Attacker进行身份验证

Exchange服务器向Attacker发送NegotiateProtocol Request,这是客户端向服务器发送第一个SMB请求,可参考技术点分析-客户端与服务器端的SMB通信

umDbHf.png

Exchange向Attacker发送SMB协商请求流程

umDLE8.png

Exchange向Attacker发送SMB协商请求流量

在正常的业务场景中,用户想登陆并使用Exchange,往往需要向Exchange服务器发送SMB协商请求流量,以便验证身份并登陆。但由于SpoolService错误,在这里,Exchange向Attacker发送SMB协商请求流量,以便验证身份。这便造成了Attacker可以作为中间人身份中继此身份认证以冒充Exchange欺骗DC的机会。

Attacker将协商请求通过ldap中继到DC服务器

umDOUS.png

Attacker向DC中继Exchange的协商请求流程

umDX4g.png

Attacker向DC中继Exchange的协商请求流量

Attacker作为中间人,将Negotiate ProtocolRequest通过ldap请求中继到ad服务器

在此步骤以及以下攻击流程中,有需要将SMB身份验证通过LDAP中继至DC的环节。由于NTLM协议的工作方式,无法将SMB流量直接通过LDAP中继,因此需要对流量进行修改,而需改流量,势必需要绕过MIC验证,此处便是本次漏洞的重点,详情见 技术点分析-MIC校验绕过部分

attacker向Exchange发送Negotiate Protocol Response

umDvCQ.png

Attacker向Exchange发送Negotiate Protocol Response流程

umDx3j.png

Attacker向Exchange发送Negotiate Protocol Response流量

Exchange向attacker发送Session Setup Request

umDzgs.png

Exchange向attacker发送Session Setup Request流程

umDx3j.png

Exchange向attacker发送Session Setup Request流量

Attacker向DC中继Session Setup Request

umrSvn.png

Attacker向DC中继Session Setup Request流程

umr9uq.png

Attacker向DC中继Session Setup Request流量

Attacker将Exchange发送来的Session Setup Request 中继给DC, DC将包含 CHALLENGE的Response发送给Attacker

Attacker 向exchange发送Session Setup Response(CHALLENGE)

umrCD0.png

Attacker 向exchange发送Session Setup Response流程

umrPbV.png

Attacker 向exchange发送Session Setup Response流量

Attacker 将DC发出的包含challenge的Session Setup Response发送给exchange

exchange向Attacker发送包含了身份验证请求的Session Setup

umrFET.png

exchange向Attacker发送包含了身份验证请求的Session Setup Request流程

umrPbV.png

exchange向Attacker发送包含了身份验证请求的Session Setup流量

我们可以看到上图中的认证用户为TEST\TOPSEC$,而不是运行Exchange的SYSTEM账户,这是因为SYSTEM账户具有太高权限,如果用此帐户对网络资源进行身份验证,则会出现安全问题。所以当访问网络资源时,使用本地计算机的网络帐户对网络进行身份验,(形式为domain\computername$,即TEST\TOPSEC$)

Exchange收到challenge后,向attacker发送包含了身份验证请求的Session Setup流量

Attacker向 DC中继含有Exchange的身份认证的Session Setup Request

umyB9g.png

Attacker向 DC中继Session Setup Request流程

umrkUU.png

Attacker向 DC中继Session Setup Request流量

DC认证通过Exchange身份,并向Attcker发送认证通过的Response。

此时,DC对Attacker的身份验证结束,Attacker成功冒用Exchange身份。由于安装Exchange后,Exchange在Active Directory域中具有高权限,Exchange的本地计算机账户TOPSEC$会被加入用户组Exchange Trusted Subsystem,该用户组又隶属于Exchange Windows Permissions。ExchangeWindows Permissions组可以通过WriteDacl方式访问Active Directory中的Domain对象,该对象允许该组的任何成员修改域权限,从而可以修改当前域ACL达到提权目的。

使用提权后的用户或计算机可以执行域控制器通常用于复制的同步操作,这允许攻击者同步ActiveDirectory中用户的所有哈希密码。

umre29.png

同步Active Directory中用户的所有哈希密码

Kerberos委派攻击流程

下文出现的攻击流量图中,个角色与ip对应关系同上文验证环境搭建:

角色 系统版本 计算机名 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实现并设置账户与密码,如下图

um5ZGt.png

Ntlmrelayx工具成功创建计算机账户

um46KS.png

DC上可见computers列表中新创建的名为EJETBTTB的计算机

在域中新的计算机账户EJETBTTB(下图中的service A)建立成功后,后续攻击如下图攻击步骤

umrmvR.png

攻击步骤

攻击者为Service A配置了基于资源的约束委派

由于通过S4U2Self请求到的TGSforwardable标志位为 Non-forwardable,这意味着该TGS服务票据是不可转发的,不可以在接下来的S4U2Proxy中进行转发。但是不可转发的TGS竟然可以用于基于资源的约束委派,S4U2Proxy会接收这张不可转发的TGS。由于我们拥有Service A的计算机账号以及密码,所以在这里可以为Service A到SDC配置了基于资源的约束委派,将默认的约束委派更改为基于资源的约束委派,以便后续攻击。

Service A 调用S4U2Self向认证服务器(SDC)为admin请求访问自身的服务票据.

umIVw4.png

通过国外安全研究员Elad Shami的研究可知,无论服务账号的UserAccountControl属性是否被设为TrustedToAuthForDelegation, 服务自身都可以调用S4U2Self为任意用户请求访问自己的服务票据,也就是说,这里Service A 可以调用S4U2Self向SDC为admin用户申请可访问自身的服务票据.

SDC将为admin用户申请的访问ServiceA的TGS发送给Service A

umsnJg.png

Service A通过S4U2Proxy 转发TGS,并为admin申请访问SDC票据

umsuWQ.png

SDC将为admin用户申请的访问SDC的TGS发送给Service A

在这里,Service A为Attacker创建并控制,Attacker获得TGS票据,利用该票据以admin身份访问SDC,完成提权

umslyn.png

0x03技术点分析


在理清利用流程后,接下来详解利用流程中的技术点

客户端与服务器端的SMB通信

补充介绍一些关于SMB通信协议相关内容,通过这部分内容,可以加深对的漏洞流程的理解。对SMB通信协议熟悉的读者,可以跳过此部分

umD53d.png

客户端与服务器端的SMB通信流程

SMB2 / Negotiate Protocol

Negotiate Protocol是在SMB2的任何新TCP会话上发出的第一个SMB2命令,它用于协商要使用的协议版本。

Negotiate Protocol命令分为如下两部分:

  1. Negotiate Protocol Request:客户端向服务器发送第一个SMB请求:“Negotiate ProtocolRequest”。这个请求包含了客户端所支持的各种 SMB Dialect。
  2. Negotiate Protocol Response: 服务器收到该请求后,选择一个它支持的最新版本(比如NTLM 0.12),再通过“Negotiate Protocol Response”回复给客户端。

SMB2 / Session Setup

SMB2 / Session Setup命令用于对用户进行身份验证并获取分配的UserID。此命令通常是SMB2 / Negotiate Protocol阶段完成后从客户端发出的第一个命令。

Session Setup分为如下两部分:

1.Session SetupRequest: Negotiate Protocol阶段结束之后,,客户端请求和服务器建立一个session,在客户端发送的Session Setup Request里,包含了身份验证请求。

\2. Session SetupResponse: 服务器回复是否通过验证。

SpoolService/printer bug

在攻击利用流程中,需要使用到一个名为printerbug.py的工具,此工具触发SpoolService/printer bug,强制Windows主机通过MS-RPRN RPC接口向攻击者进行身份验证。

Windows的MS-RPRN协议用于打印客户机和打印服务器之间的通信,默认情况下是启用的。协议定义的RpcRemoteFindFirstPrinterChangeNotificationEx()调用创建一个远程更改通知对象,该对象监视对打印机对象的更改,并将更改通知发送到打印客户端。

任何经过身份验证的域成员都可以连接到远程服务器的打印服务(spoolsv.exe),并请求对一个新的打印作业进行更新,令其将该通知发送给指定目标。之后它会将立即测试该连接,即向指定目标进行身份验证(攻击者可以选择通过Kerberos或NTLM进行验证)。另外微软表示这个bug是系统设计特点,无需修复。

umsKzj.png

在本次漏洞的利用过程中,我们通过printerbug.py脚本触发了上述bug,强制Exchange服务器对攻击者(192.168.123.69)发起身份验证,而Exchange默认是以SYSTEM身份执行的。

umDifH.png

下图是printerbug.py执行后的数据包:

umDkpd.png

1、第一次身份验证由攻击者向exchange服务器发起,以便可以远程连接到Spoolsv服务,可以看到使用的账号是一个普通的域成员账号test;

2、接着,printerbug.py脚本中调用RpcRemoteFindFirstPrinterChangeNotificationEx(),请求对一个新的打印作业进行更新,并令其将该通知发送给我们指定的attackerhost(192.168.123.69)。这部分数据就是上图中Encrypted SMB3中的一部分。

umsbtS.png

3、第二次身份验证便是使Exchange向attackerhost(192.168.123.69)发起的身份验证,用户为TEST\TOPSEC$,(不是SYSTEM的原因是:如果本地服务使用SYSTEM帐户访问网络资源,则使用本地计算机的网络帐户domain\computername$对网络进行身份验证)

SMB中继LDAP思路以及难点

在攻击利用流程中,需要将SMB身份验证通过LDAP中继至DC,由于NTLM协议的工作方式,无法将SMB流量直接通过LDAP中继,将SMB流量通过LDAP中继难点以及绕过思路如下:

1、默认情况下,SMB中的NTLM身份验证:NEGOTIATE_SIGN为set状态

umDE6I.png

2、将此SMB流量中继到LDAP时,由于此时的NegotiateSign设置为set,该标志会触发LDAP签名,而此SMB流量为Attacker从Exchange服务器上中继而来,无法通过LDAP的签名校验,从而被LDAP忽略,导致攻击失败

3、为了防止攻击失败,需要将NEGOTIATE_SIGN设置为Not set

4、MIC保护不被篡改,如果简单的改包,将NEGOTIATE_SIGN设置Not set,将会导致MIC校验不通过

5、需要寻找一种可以绕过MIC校验的方式,以便更改包中的值

6、在绕过MIC校验之后,更改NEGOTIATE_SIGN值为Not set,使得在不触发LDAP签名校验的情况下,将SMB中继LDAP

MIC校验

NTLM身份验证由3种消息类型组成:

NTLM_NEGOTIATE,NTLM_CHALLENGE,NTLM_AUTHENTICATE。

NTLM_NEGOTIATE,NTLM_CHALLENGE,NTLM_AUTHENTICATE对应位于SMB协议中的SessionSetup阶段

umDVXt.png

Clinet与Server交互流程图

umDenP.png

Clinet与Server交互流量

umDm0f.png

SMB认证协议流程

为了确保恶意行为者不在传输过程中处理消息,在NTLM_AUTHENTICATE消息中添加了一个额外的MIC(消息完整性代码)字段。

umDn78.png

存放于NTLM_AUTH中的MIC

MIC是使用会话密钥应用于所有3个NTLM消息的串联的HMAC_MD5,该会话密钥仅对启动认证的帐户和目标服务器是已知的。

因此,试图篡改其中一条消息的攻击者(例如,修改签名协商)将无法生成相应的MIC,这将导致攻击失败。

MIC校验绕过

Microsoft服务器允许无MIC 的NTLM_AUTHENTICATE消息。

如果想要将SMB身份验证中继到LDAP,并完成中继攻击,可以通过如下步骤:

取消MIC校验以确保可以修改数据包中的内容:

(1)从NTLM_AUTHENTICATE消息中删除MIC

(2)从NTLM_AUTHENTICATE消息中删除版本字段(删除MIC字段而不删除版本字段将导致错误)。

LDAP签名绕过

在绕过MIC校验之后,可以修改NEGOTIATE_SIGN值以便将SMB流量顺利通过LDAP签名校验

将NEGOTIATE_SIGN设置为notset以绕过LDAP验证

(1) 取消设置NTLM_NEGOTIATE消息中的签名标志(NTLMSSP_NEGOTIATE_ALWAYS_SIGN,NTLMSSP_NEGOTIATE_SIGN

(2) 取消设置NTLM_AUTHENTICATE消息中的以下标志:NTLMSSP_NEGOTIATE_ALWAYS_SIGN,NTLMSSP_NEGOTIATE_SIGN,NEGOTIATE_KEY_EXCHANGE,NEGOTIATE_VERSION。

smb中继LDAP流程

为了实现SMB中继LDAP流程,这里使用ntlmrelayx.py工具作为中继

umDKAS.jpg

Ntlmrelayx中继流程如下:

1、取消设置NTLM_NEGOTIATE消息中的签名标志(NTLMSSP_NEGOTIATE_ALWAYS_SIGN,NTLMSSP_NEGOTIATE_SIGN)

umDMtg.png

Exchange-Attacker-DC交互流量

umDQhQ.png

Exchange向Attacker发送NTLMSSP_NEGOTIATE包内容

umD1pj.png

Attacker将NTLMSSP_NEGOTIATE通过LDAP中继到DC包内容

可见,在通过LDAP中继时,已经取消设置NTLM_NEGOTIATE消息中的签名标志(NTLMSSP_NEGOTIATE_ALWAYS_SIGN,NTLMSSP_NEGOTIATE_SIGN)

2、从NTLM_AUTHENTICATE消息中删除MIC以及版本字段

umD31s.png

Exchange-Attacker-DC交互流量

umD8cn.png

Exchange向Attacker发送NTLMSSP_AUTH

umDYn0.png

Attacker将NTLMSSP_AUTH通过LDAP中继到DC

在通过LDAP中继时,NTLM_AUTHENTICATE消息中MIC以及版本字段已被删除

3、取消设置NTLM_AUTHENTICATE消息中的以下标志:NTLMSSP_NEGOTIATE_ALWAYS_SIGN,NTLMSSP_NEGOTIATE_SIGN,NEGOTIATE_KEY_EXCHANGE,NEGOTIATE_VERSION

um4w4I.png

Exchange-Attacker-DC交互流量

umDtBV.png

Exchange向Attacker发送NTLMSSP_AUTH包内容

umDN7T.png

Attacker将NTLMSSP_AUTH通过LDAP中继到DC包内容

在通过LDAP中继时,NTLM_AUTHENTICATE消息中的以下标志:NTLMSSP_NEGOTIATE_ALWAYS_SIGN,NTLMSSP_NEGOTIATE_SIGN,NEGOTIATE_KEY_EXCHANGE,NEGOTIATE_VERSION已经被设置为’NOT set’

0x04参考链接


[1] Exchange Server 2013 一步步安装图解

[2] EnableLDAP over SSL (LDAPS) for Microsoft Active Directory servers

[3] Windows Server 2012 R2 辅助域控制器搭建

[4] 滥用基于资源约束委派来攻击Active Directory

[5] AbusingS4U2Self: Another Sneaky Active Directory Persistence

[6]利用CVE-2019-1040 - 结合RCE和Domain Admin的中继漏洞

[7] 滥用Exchange:远离域管理员的一个API调用

[8] The SYSTEM Account

[9]Waggingthe Dog: Abusing Resource-Based Constrained Delegation to Attack ActiveDirectory