攻击Active Directory组托管服务账户(GMSA)
在2020年5月,我在Trimarc网络研讨会“保护Active Directory:解决常见问题”中介绍了一些Active Directory安全主题,包括关于AD组托管服务账户(GMSA)安全性的信息。本文扩展了我在研讨会中涵盖的攻击和防御GMSA的内容。
组托管服务账户(GMSA)概述
创建为用户账户的服务账户很少更改密码。组托管服务账户(GMSA)提供了一种更好的方法(从Windows 2012开始)。密码由AD管理并自动更改。这意味着GMSA必须明确委派安全主体以访问明文密码。类似于其他委派控制访问的领域(如LAPS),确定谁应被委派访问权限需要仔细考虑。
GMSA的关键点:
- GMSA密码由AD管理。
- 托管GMSA服务账户的计算机从Active Directory请求当前密码以启动服务。
- 配置GMSA以允许计算机账户访问密码。
- 如果攻击者入侵使用GMSA的托管服务计算机,GMSA即被入侵。
- 如果攻击者入侵有权请求GMSA密码的账户,GMSA即被入侵。
GMSA具有对象类“msDS-GroupManagedServiceAccount”和特定于GMSA的属性,包括:
- msDS-GroupMSAMembership (PrincipalsAllowedToRetrieveManagedPassword) – 存储可访问GMSA密码的安全主体。
- msds-ManagedPassword – 此属性包含组托管服务账户的密码信息BLOB。
- msDS-ManagedPasswordId – 此构造属性包含组MSA当前托管密码数据的密钥标识符。
- msDS-ManagedPasswordInterval – 此属性用于检索组MSA自动更改托管密码前的天数。
运行AD PowerShell cmdlet Get-ADServiceAccount,我们可以检索GMSA的信息,包括特定GMSA属性。此GMSA是域管理员组的成员,具有对域的完全AD和DC管理员权限。屏幕截图显示密码最近更改,且几周内不会更改 – 于2020年5月11日更改,配置为每30天更改一次。这意味着如果我们能获取此账户的密码,我们几乎有一个月的时间使用账户凭据,然后才会更改。我们还可以识别一个可以检索密码数据的组。
获取运行GMSA服务的服务器访问权限
一旦我们进入在GMSA上下文中运行服务的服务器,我们有一些选项。我们识别LCNSQL01服务器在GMSA上注册为服务主体名称(SPN),并且此服务器在Servers OU中。如果我们能入侵有权访问Servers OU的账户,或通过GPO受限组或类似方式委派管理员权限,或能够修改链接到此OU的GPO,我们可以获取LCN服务器的管理员权限。
获取与GMSA关联的服务器的管理员权限后,我们可以看到有服务在GMSA上下文中运行(我在此作弊,配置了Windows许可证管理器服务以此账户启动)。由于有服务在账户上下文中运行,我们可以获取与服务账户关联的密码数据。这里我们使用Mimikatz通过sekurlsa::logonpasswords转储LSASS。有趣的是,密码看起来有点不寻常:“SA{262E99C9-6160-4871-ACEC-4E61736B6F21}”这不是标准密码(且实际上不是与账户关联的密码)。更重要的是,此密码哈希不正确。Microsoft将GMSA凭据加载到LSASS中,但似乎不使用它。
要获取正确的NT密码哈希,我们需要使用Mimikatz命令“Sekurlsa::ekeys”,用于获取Kerberos票证。运行此Mimikatz命令后,我们能够看到密码哈希。有了此密码哈希,我们可以传递哈希(PTH)以入侵AD。
入侵具有GMSA密码访问权限的账户
我们知道有一个组配置了获取GMSA密码的权限,让我们看看。msDS-GroupMSAMembership (PrincipalsAllowedToRetrieveManagedPassword)属性包含一个名为“SVC-LAB-GMSA1 Group”的组。此属性控制谁可以请求和接收明文密码。枚举组“SVC-LAB-GMSA1 Group”的成员时,有计算机、用户和另一个组(“Server Admins”),因此让我们检查该组的成员。
现在我们有了所有可以获取GMSA明文密码的账户列表。有11个用户账户具有此能力,其中9个看起来像常规用户账户(提示:它们确实是!)。这是一个大问题。入侵其中一个,GMSA账户即被入侵,并且由于它是域中管理员组的成员,我们控制了域。
一旦我们入侵了具有拉取明文密码能力的用户(或计算机!)账户(PrincipalsAllowedToRetriveManagedPassword),我们可以使用Microsoft PowerShell cmdlet Get-ADServiceAccount请求它。我们可以利用PowerShell cmdlet Get-ADServiceAccount获取GMSA的明文密码数据(属性msds-ManagedPassword)。使用DSInternals模块(ConvertTo-NTHash),我们可以将明文密码BLOB转换为NT哈希。
如果我们能入侵的账户是计算机账户,我们需要在计算机上以SYSTEM身份运行这些命令。如果我们能够在有权拉取GMSA密码的服务器上获取管理员/SYSTEM权限,但GMSA未在服务上下文中运行(因此运行Mimikatz无帮助,因为GMSA凭据不在内存中),则使用此方法。这里我使用PSEXEC生成一个在本地SYSTEM账户上下文中运行的命令shell。一旦以SYSTEM身份运行,我们可以执行与上述相同的操作。计算机账户有权拉取密码,但该计算机上的用户没有,因此我提升到SYSTEM,然后以关联的AD计算机账户与AD交互。现在我可以获取GMSA密码。
下一步我在实验室中执行以确认DSInternals提供的NT密码哈希与Active Directory中的匹配。我使用DSInternals命令Get-ADReplAccount获取AD密码哈希,并可以确认从GMSA拉取的密码哈希与从AD收集的相同。
缓解措施
确定实际所需的权限,并确保仅将所需的有限权限应用于GMSA。除非GMSA使用的服务器仅限于Tier 0(域控制器),否则不要添加到AD特权组。限制GMSA访问和位置(尤其是如果具有特权)。