导语:PowerView可能是我写过的我最喜欢的一个程序,也绝对是我最经常使用的程序(最近的文章就是证明)。我的团队也大量使用了这个工具包,在过去的几年里我们已经提出了一些很酷的用法。很长一段时间内,我一直想分享PowerView一些真正的“强
PowerView可能是我写过的我最喜欢的一个程序,也绝对是我最经常使用的程序(最近的文章就是证明)。我的团队也大量使用了这个工具包,在过去的几年里我们已经提出了一些很酷的用法。很长一段时间内,我一直想分享PowerView一些真正的“强大”用途,比如这篇文章里写到的PowerView使用“技巧” 。
这个系列文章的目的是为了演示如何使用PowerView来解决有趣的问题以及我们在每个解决方案背后的思考过程。PowerView不是一个固有的“攻击性”或“防御性”的工具集,它是一个帮助解决Active Directory安全问题的工具,无论是黑是白。
本系列中的所有内容都将基于真实的渗透测试场景,每篇文章将至少介绍一个PowerView功能。由于这些场景是基于实际情况中的问题,所以解决方案可能并不总是通用的,但是它们应该是非常有用的。我确信很多人只是使用了PowerView功能的一小部分,我希望向所有人展示它的全部功能。
这个系列的文章将符合下面这个半标准的格式:
· 场景:重点描述在实际渗透测试中遇到的操作问题
· 解决方案:提供完整的PowerView解决方案
· 解释:一步一步地将解决方案分解,逐步解释我们的思维过程
随后的文章中将更新如下内容:
· PowerView PowerUsage系列#1 – 批量用户配置文件枚举
· PowerView PowerUsage系列#2 – 使用全局编录映射计算机短名称
· PowerView PowerUsage系列#3 – 枚举外部域中的GPO编辑权限
· PowerView PowerUsage系列#4 – 寻找交叉信任的ACE
场景一:多用户配置文件枚举
假设你正在准备提升域权限,并且想要映射你已经拿到权限的系统3389(或以其他方式交互式登录)。你也知道这个域可能早已经被入侵过了,所以你想尽可能地限制凭证的暴露。如果我们有一个可过滤的CSV文件来将数据传送给客户端,那么也是很好的,如果可能的话,这会将任何“噪音” 最小化。
解决方案
Get-DomainComputer -LDAPFilter '(dnshostname=*)' -Properties dnshostname -UACFilter NOT_TRUSTED_FOR_DELEGATION -Ping | % { try { $ComputerName = $_.dnshostname Get-WmiObject -Class Win32_UserProfile -Filter "NOT SID = 'S-1-5-18' AND NOT SID = 'S-1-5-19' AND NOT SID = 'S-1-5-20'" -ComputerName $_.dnshostname -ErrorAction SilentlyContinue | % { if ($_.SID -match 'S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[0-9]+$') { $LocalPath, $Time = '', '' if ($_.LastUseTime) { $Time = ([WMI]'').ConvertToDateTime($_.LastUseTime) } if ($_.LocalPath) { $LocalPath = $_.LocalPath.Split('')[-1] } New-Object PSObject -Property @{'ComputerName'=$ComputerName ; 'SID'=$_.SID; 'LocalPath'=$LocalPath; 'LastUseTime'=$Time} } } } catch {} } | Export-Csv -NoTypeInformation user_profiles.csv
解释说明
首先,我们使用Get-DomainComputer 来检索了当前域的活动目录的计算机对象。为了减少“噪音”,我们实现了一个自定义的LDAPFilter,并且让这个函数只返回活动目录中有dnsHostName属性的计算机。
由于我们很在意机器返回的dnshostname信息,所以可以设置-Properties只要求相关的域控制器返回我们需要的信息。这有助于减少我们和DC之间的网络流量。
由于我们知道该域可能已经被入侵了,因此,在进行远程网络连接时,我们希望尽可能谨慎地使用提升后的登陆凭据。肖恩·梅特卡夫(Sean Metcalf)在“不受约束授权的危险”这一方面有很几篇很不错的文章,我没有太多的时间在这方面进行深入研究,但是我们至少可以返回没有设置过TRUSTED_FOR_DELEGATION标志的机器。返回的系统是应该可以通过像WMI这样的东西来进行进一步渗透。最后,我们也只想从当前的网络连接到的机器,-Ping参数只能返回机器的标准ICMP ping的响应。
现在有一组我们感兴趣的由管道返回的主机名。对于这个特定的场景,我们希望看到谁曾经登录过一台机器,我们决定通过Get-WmiObject枚举Win32_UserProfile类来查看交互式用户在机器上生成的配置文件。为了减少一些噪音,我们可以“向左优化”,并筛选出一些我们不关心的常见SID。
最后,我们只关心域SID,因此,我们使用'S-1-5-21- [0-9] + – [0-9] + – [0-9] + – [0-9] +'作为过滤器。然后,我们将配置文件的LastUseTime转换为可读的格式,然后拆分返回的配置文件路径,以便了解配置文件的用户名。我们通过使用New-Object PSObject在包含我们关心的最终输出元素的管道中间创建一个新的自定义对象,将所有内容都输出到Export-Csv以便于分析。
场景二:计算机短名称与全局编录映射
在参与多域林环境的渗透测试过程中,你最终可能会在文件computers.txt中记录一些计算机的“短名称”(如WINDOWS1),以便利用该文件来解析DNS主机名。
解决方案
解释说明
这个其实很简单。我们使用gc (Get-Content)输出计算机短名称列表,通过管道符和Sort-Object -Unique将其进行排序,作为对列表进行唯一化的一种方式。然后这个唯一的列表通过管道符和%(ForEach-Object)以执行脚本块({…}中的代码)的方式传送到Get-DomainComputer ,以便我们可以适当地过滤名称。
-SearchBase X 指定了通过对象搜索的LDAP源。在这种情况下,我们会使用全局编录(点击这里查看更多信息),它是Active Directory林中所有对象的部分拷贝。如果我们在当前域(从$ENV:USERDNSDOMAIN拉出)之前指定GC:// ,那么我们所在域的全局编录副本将被搜索,而不是在我们当前的域进行搜索。由于计算机对象的“name”和“dnshostname”属性被复制到了全局编录中,因此我们可以使用这种方法将短名称(名称)快速映射到完全限定名称,本例中为dnshostname 。
我们通过为从文本文件列表返回的名称添加了一个自定义的-LDAPFilter 过滤器来完成映射,并且–Properties dnshostname将再次“向左优化”,只返回我们关心的属性。