导语:Active Directory访问控制是我和我的同事们在过去一年以来一直非常感兴趣的事情。到目前为止,我们发布了BloodHound的 ACL攻击路径更新的功能,以及@ _wald0和我发现了Active Directory DACL 后门(白皮书在这里)。这篇文章将涵盖
Active Directory访问控制是我和我的同事们在过去一年以来一直非常感兴趣的事情。到目前为止,我们发布了BloodHound的 ACL攻击路径更新的功能,以及@ _wald0和我发现了Active Directory DACL 后门(白皮书在这里)。这篇文章将涵盖在外部域中的GPO DACL枚举。
为什么要关心这个问题呢?因为,如果你有了编辑GPO的权限,那么你就可以控制应用了该GPO的任何用户或计算机。如果你的目标是明确的找出GPO所应用的对象,那么请 参阅“PowerView-3.0-tricks”中的这一行代码。
情景三:在一个外部域中枚举GPO编辑权限
假设你正在进行渗透测试,并且你想知道哪些安全主体是可以在外部域(在本例中为dev.testlab.local)中编辑GPO 。
解决方案
解释说明
首先,我们使用PowerView的Get-DomainObjectACL 枚举外部域中所有组策略对象的ACE。-Domain “dev.testlab.local” 参数指明了要查询的外部域,并且LDAP过滤器-LDAPFilter ‘(objectCategory=groupPolicyContainer)’表明仅返回组策略对象。-ResolveGUIDs参数表示了,在ACE中的任何目标的GUID都应该解析为人类可读的名字。
然后,我们实现一个自定义过滤器? {…} (Where-Object),只返回与正则表达式‘^S-1-5-.*-[1-9]d{3,}$’匹配的主体(具有权限的对象)的SecurityIdentifier。这只会返回受信主体的安全标识符的相对标识符(RID)大于-1000及其以上的内容,也就是不是类似于“域管理员”内置的那些对象。这个过滤器的目的是为了减少噪声,试图列举非标准域用户的更多“有趣”的错误配置。过滤器的第二部分与ACE中的权限相匹配,表示某种类型的控制关系(通用的所有权限,更改所有者权限等),即某种类型的“对象接管”原语,允许入侵目标对象。有关这种类型的关系或攻击的更多信息,请查看@ wald0's和我的一起发布的白皮书——An ACE Up the Sleeve。
从这里开始,为了给操作人员添加更多的上下文信息,我们通过% {…} (ForEach-Object)处理管道上的每个ACE结果,并通过使用ACE 将SecurityIdentifier 解析为可分辨的名称,解析名称使用的是PowerView的Convert-ADName ,并设置 -OutputType 为DN(专有名称)。我们通过使用New-Object PSObject在管道中间创建一个新的自定义对象,其中包含了我们关心的信息,并将所有内容都传递给fl (Format-List)便于输出显示。
现在你就可以知道哪些帐户可以编辑这些有趣的GPO,你可以对这些帐户执行有针对性的攻击,并且可以使用这些账户来推送恶意的GPO。
下面的内容是 “ PowerView PowerUsage 使用方法 ”系列文章中的第四个场景的介绍。
在信任关系域环境中进行渗透测试的一种思路我已经在前面做了简要的介绍,就是在域对象上枚举DACL/ACE,主体(即拥有用户或组的指定对象的权限)与目标对象位于不同的域中。如上所述,Active Directory对象的大多数ntSecurityDescriptor 属性是:(1)任何域认证用户都可访问,(2)在全局编录中复制。这意味着你可以从当前的受信任域的上下文中查询信任域中的所有对象的DACL,并过滤外部安全主体在你列举的对象上具有给定权限的任何ACE条目。
情景四:查找交叉域的ACE
你想知道特定域中的DACL/ACE条目包含不在这些特定域中的主体。也就是说,你想要查找目标域的入站跨域安全描述符关系。在这个例子中,我们假设,我们目前在testlab.local 域中,并且目标域是dev.testlab.local 。
解决方案
$Domain = "dev.testlab.local" $DomainSid = Get-DomainSid $Domain Get-DomainObjectAcl -Domain $Domain -ResolveGUIDs -LDAPFilter '(|(objectclass=groupPolicyContainer)(objectclass=group)(objectclass=user)(objectclass=domain))' | ? { ($_.AceType -match 'AccessAllowed') -and ` ($_.SecurityIdentifier -match '^S-1-5-.*-[1-9]d{3,}$') -and ` ($_.SecurityIdentifier -notmatch $DomainSid) -and ` ($_.ActiveDirectoryRights -match 'WriteProperty|GenericAll|GenericWrite|WriteDacl|WriteOwner') } | % { $_ | Add-Member Noteproperty 'PrincipalDN' $(Convert-ADName $_.SecurityIdentifier -OutputType DN) $_ }
解释说明
上述代码片段看起来非常简单。在我们做其他事情之前,我们用PowerView的Get-DomainSid获取外部域的SID(安全标识符)。这样我们可以过滤出ACE信息,其中受信主体(具有权限的对象)的SecurityIdentifier与枚举对象位于同一个域中。这样我们稍后就可以过滤这些交叉信任的ACE关系。
为了清楚一些,我们使用PowerView的Get-DomainObjectAcl 枚举外部域中的某些对象的ACE,可以使用-Domain'dev.testlab.local' 指定。在我的“攻击域信任指南”后面的 “PowerView中的数据枚举”一节中介绍了更多有关的内容。不过要注意,-LDAPFilter与前面的过滤器有所不同。在当前这种情况中·,我们正在搜索组策略,组,用户,计算机和域对象,即我们目前拥有接管原语的对象。由于计算机对象在其对象类中也包含“用户”,因此我们不需要明确指定“计算机”。-ResolveGUIDs 参数标志表示了ACE中的任何目标GUID都应该被解析为人类可读的名称。
接下来,我们实现一个自定义过滤器?{…} (Where-Object),该过滤器有以下要求:
· 首先,我们需要确保AceType指定了一个为ALLOW的条目。
· 其次,我们再次使用SecurityIdentifier中的 ‘^S-1-5-.*-[1-9]d{3,}$’正则表达式返回只有受信主体的安全标识符的相对标识符(RID)大于等于 -1000 的结果 。
· 第三,通过对先前枚举的外部域SID执行条件为假的正则表达式匹配,这样我们就可以从与对象相同的域中过滤出主体。
· 最后,最后一个规则与ACE中的权限相匹配,这些权限指示某种类型的控制关系(通用所有权限,更改所有者的权限或其他“对象接管”原语),从而使目标对象可以被攻击。有关这种关系或攻击类型的更多信息,请查看 @ _wald0和我在Black Hat 2017 上发布的 “ ACE 套装 ”白皮书。
现在,我们通过%{…} (ForEach-Object) 处理每个ACE结果。与前面提到的提取出特定的属性并创建新的对象相反,现在我们使用PowerView 的 Convert-ADName并将输出类型-OutputType 设置为DN(专有名称)来解析ACE的SecurityIdentifier 为一个专有名称并添加为在管道符上返回的ACE对象的新属性。
在跨越某种类型的信任边界的外部域中枚举ACE
注意:这可能需要一段时间才能运行,因为这个过程会枚举和解析大量对象的安全描述符信息。