WMI 攻击手法研究 - Active Directory 枚举 (第五部分)
本篇文章翻译自:Offensive WMI - Active Directory Enumeration (Part 5) :: 0xInfection's Blog — Random ramblings of an Infected Geek本篇文章是 WMI 攻击手法研究系列中的第五篇,着重于 Active Directory 枚举。
Active Directory (AD) 是 Microsoft 为 Windows 域网络实施的目录和 IAM 服务 —— 管理员能够通过它来管理权限和对资源的访问。任何用于管理多个资源的东西对管理员来说都很方便,但是,对于不法分子收集信息和横向移动也很有用。
需要注意的是,有多种方式可以与任何 AD 环境进行交互,但在本篇文章中,我们将坚持使用纯 WMI。
一、AD 和 WMI
WMI 有一个名为 root\directory\ldap 的 provider,可用于与 AD 环境进行交互。如果尝试列出该 provider 下的类,可以看到有很多类带有这些前缀中的任何一个,即 ads_ 或 ds, 以 ads_ 开头的类是抽象类,以 ds_ 开头的类是动态类 (唯一对我们有用的类,因为它们允许检索实例)。
使用以下命令可快速列出可用的类:
Get-WmiObject -Namespace root\directory\ldap -Class ds_* -List
让我们正式开始吧!
二、寻找域名
在获得域上的一个访问权限后,侦察的第一步是尝试找出所在的域名:
Get-WmiObject -Namespace root\directory\ldap -Class ds_domain | select ds_dc,
ds_distinguishedname, pscomputername
在上面的命令中,我们获取了域、FQDN 和当前所在计算机的名称。
三、获取域策略
现在,尝试查看当前的域策略。同样 ds_domain 可以提供一些额外的策略信息:
Get-WmiObject -Namespace root\directory\ldap -Class ds_domain | select ds_lockoutduration,
ds_lockoutobservationwindow, ds_lockoutthreshold, ds_maxpwdage,
ds_minpwdage, ds_minpwdlength, ds_pwdhistorylength, ds_pwdproperties
注意:您可能已经注意到,上述命令的输出中包含许多负值。上述输出中的所有时间戳都存储为负 "文件时间",即表示为 100 纳秒时间片的负整数。例如,20 分钟的时间段将表示为 -12000000000。
我们可以公平地推导出锁定持续时间和锁定观察窗口都设置为 30 分钟,而密码过期持续时间是无限的,即永不过期。密码最小长度为 7,历史长度为 24。
四、查找域控制器
Cool,让我们试着找出域控制器。在此之前,应该记住,在 WMI 中,不同的 UAC (用户帐户控制) 值是通过常量定义的。下表显示了 UAC 值到用户类型的映射:
User TypeHex ValueConstants
Normal User0x200512
Workstation/Server0x10004096
Domain Controller0x82000532480
现在知道了这些值,那么可以使用以下命令轻松查询 ds_computer 类。请注意使用 where Powershell 实用程序通过管道变量查找域控制器。
Get-WmiObject -Namespace root\directory\ldap -Class ds_computer | where {
$_.ds_useraccountcontrol -match 532480
} | select ds_cn, ds_dnshostname, ds_operatingsystem, ds_lastlogon, ds_pwdlastset
输出提供了大量有关域控制器 (domain controller,DC) 的数据,包括其名称、DNS 主机名、操作系统、上次登录时间戳甚至 DC 的上次密码更新时间戳。输出中所有基于时间的属性都是文件时间。可以使用这个简洁的转换器将文件时间转换为人可以阅读的日期时间格式。
我们可以用一个没有管理员权限的普通域用户帐户来枚举很多信息!
五、搜索用户帐户
此域中的用户帐户怎样,和信任关系中的其他域一样吗?它就像使用 Win32_UserAccount 类查询用户一样简单:
Get-WmiObject -Class win32_useraccount | select name, domain, accounttype
您可能已经猜到了,AccountType 属性是一个描述用户类型的常量值。下表定义了具有常量值的帐户类型:
Account TypeIdentifierConstant
Temporary Duplicate AccountUF_TEMP_DUPLICATE_ACCOUNT256
Normal AccountUF_NORMAL_ACCOUNT512
Interdomain Trust AccountUF_INTERDOMAIN_TRUST_ACCOUNT2048
Workstation Trust AccountUF_WORKSTATION_TRUST_ACCOUNT4096
Server Trust AccountUF_SERVER_TRUST_ACCOUNT8192
如果只想过滤单个域的用户帐户,可以像这样使用 cmdlet 的 -Filter 参数:
Get-WmiObject -Class win32_useraccount -Filter 'domain="infected"' | select caption
六、枚举当前登录的用户
Win32_LoggedOnUser 类提供有关该系统以及域中登录用户的信息。要仅过滤域的用户,可以使用以下命令:
Get-WmiObject -Class win32_loggedonuser | where {
$_ -match 'infected'
} | foreach {$_.antecedent}
七、获取组
获取域的组就像查询 Win32_GroupInDomain 类一样简单。我们将使用一些 Powershell 魔法来为我们提供更清晰的输出。
Get-WmiObject -Class win32_groupindomain | foreach {$_.partcomponent}
对 Win32_Group 类也可以这样做,但输出也将包括本地组。
八、弄清楚组成员身份
组成员资格数据由 Win32_GroupUser 类提供。获得的输出包括当前域、受信任域以及具有双向信任的受信任的所有成员信息。对于此示例,假设要获取域管理员帐户:
Get-WmiObject -Class win32_groupuser | where {
$_.groupcomponent -match 'domain admins'
} | foreach {$_.partcomponent}
这同样适用于相反的用例。如果想枚举特定用户所在的组 (在本例中为管理员),那么可以执行以下操作:
Get-WmiObject -Class win32_groupuser | where {
$_.partcomponent -match 'Administrator'
} | foreach {$_.groupcomponent}
注意:由于使用的是 Powershell 的 Where-Object cmdlet,我们可以有效地使用 -match 参数来查找属性中的任何子字符串。这有助于探索根据特定标准创造性地过滤事物的许多可能性。
九、在域中查找机器
要获取 AD 环境中所有唯一机器的列表,可以执行以下操作:
Get-WmiObject -Namespace root\directory\ldap -Class ds_computer | select ds_cn
十、跨机器枚举管理员权限
需要记住的重要一点是,默认情况下,WMI 仅向本地管理员提供远程访问。已经注意到那里的捕获了吗? 如果可以对远程计算机运行 WMI 命令,则意味着在该计算机上具有本地管理员访问权限。我们可以使用这些信息编写一个非常简单的脚本,该脚本可以枚举远程计算机上的本地管理员权限。
我们可以将最后一个命令的输出与一些 Powershell 链接起来以实现上述目的:
$pcs = Get-WmiObject -Namespace root\directory\ldap -Class ds_computer | select -ExpandProperty ds_cn
foreach ($pc in $pcs) {
(Get-WmiObject -Class win32_computersystem -ComputerName $pc -ErrorAction silentlycontinue).name
}
十一、结论
在本篇文章中,我们使用几个 WMI 类和一些 Powershell 魔法可以轻松地从 Active Directory 环境中枚举大量内容。再一次说明一下这篇文章并不全面,在侦察方面有很多可能性。在下一篇文章中,将重点介绍 通过 WMI 的横向移动。
我希望你喜欢阅读本篇文章,干杯!
页:
[1]