1.背景知识
1.1 与Active Directory交互的方法
-
内置封装各种Win32 API调用的net命令
-
手动实现各种Win32 API调用
-
LDAP接口(比如dsquery和adfind)
-
PowerShell
- 微软官方RSAT-AD-PowerShell Active Directory cmdlets
- 与封装各种RPC接口的各种 .NET 类交互
- 使用 .NET DirectorySearcher 或 DirectoryEntry 对象与 LDAP 交互
DirectoryEntry
[System.DirectoryServices.DirectoryEntry]表示一个封装在Active Directory中的节点或对象
- $Entry = New-Object DirectoryServices.DirectoryEntry('LDAP://CN=harmj0y,CN=Users,DC=testlab,DC=local')
- $Entry.objectclass
[adsi]加速器是一个简单的DirectoryEntry别名
- ([adsi]"LDAP://CN=harmj0y,CN=Users,DC=testlab,DC=local”).objectclass
DirectorySearcher
[System.DirectoryServices.DirectorySearcher] 类允许针对 Active Directory 实例进行搜索
• $Searcher = New-Object DirectoryServices.DirectorySearcher('(samaccountname=harmj0y)')
• $Searcher.FindAll() : 查找所有结果
• $Searcher.FindOne() : 查找一个结果
[adsisearcher] 加速器是一个简单的 DirectorySearcher 别名:
• ([adsisearcher]'(samaccountname=harmj0y)').FindAll()
1.2 ADSI概述
ADSI是一个允许IT管理员查看和管理AD中的对象和属性的工具。它是Remote Server Administration (RSAT)工具包的一部分,默认安装在System32文件夹下。
1.3 LDAP属性
活动目录有对象和属性。每个对象都包含不同的属性,属性可以是姓名、电子邮件、电话号码等等。
如下图,我们可以看到不同的LDAP属性,这些属性对每个认证的用户都是可读的。
因为它对每个认证的用户都是可读的。在没有任何额外权限的情况下,也有可能枚举出这些信息。
1.4 查询时间戳的LDAP属性
我们将查询一个存在于Domain Naming Context (DNC)上的LDAP属性。DNC包含所有存储在域中的对象。
这里我们可以看到minPwdLength,它规定了密码必须包含的最小字符数。
对应的命令行查询语句:
[adsi]"LDAP://DC=contoso,DC=com" | Format-List minPwdLength
2.基本信息收集
所有user对象
([adsisearcher]'(&(objectCategory=person)(objectClass=user))').FindAll()
所有计算机对象
([adsisearcher]'(objectCategory=computer)').FindAll()
所有group对象
([adsisearcher]'(objectCategory=group)').FindAll()
所有OU
([adsisearcher]'(objectCategory=organizationalUnit)').FindAll()
所有容器
([adsisearcher]'(objectCategory=container)').FindAll()
所有domain对象
([adsisearcher]'(objectCategory=domain)').FindAll()
cn以'Jon'开头的用户
([adsisearcher]'(&(objectCategory=person)(objectClass=user)(cn=Jon*))').FindAll()
以Test或Admin开头的组
([adsisearcher]'(&(objectCategory=group)(|(cn=Test*)(cn=Admin*)))').FindAll()
以svc或adm开头的帐号
([adsisearcher]'(&(objectCategory=user)(|(cn=svc*)(cn=Adm*)))').FindAll()
定义了登录脚本字段的所有用户
([adsisearcher]'(&(objectCategory=person)(objectClass=user)(scriptPath=*))').FindAll()
配置了"Password Never Expires"的用户
([adsisearcher]'(&(objectCategory=person)(objectClass=user)(userAccountControl :1.2.840.113556.1.4.803:=66048))').FindAll()
不需要有密码的用户
([adsisearcher]'(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=544))').FindAll()
所有启用了"Do not require kerberos preauthentication"的用户
([adsisearcher]'(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))').FindAll()
受信任的无约束委派的账户
([adsisearcher]'(&(!(primaryGroupID=516)(userAccountControl:1.2.840.113556.1.4.803:=524288)))').FindAll()
受信任的无约束委派的计算机
([adsisearcher]'(&(objectCategory=computer)(!(primaryGroupID=516)(userAccountControl:1.2.840.113556.1.4.803:=524288)))').FindAll()
受信任的无约束委派的用户
([adsisearcher]'(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=524288))').FindAll()
所有distribution组
([adsisearcher]'(&(objectCategory=group)(!(groupType:1.2.840.113556.1.4.803:=2147483648)))').FindAll()
所有security组
([adsisearcher]'(groupType:1.2.840.113556.1.4.803:=2147483648)').FindAll()
所有内置组
([adsisearcher]'(groupType:1.2.840.113556.1.4.803:=1)').FindAll()
所有具有SPN的用户账户,同时不包括KRBTGT账户
([adsisearcher]'(&(objectCategory=user)(!(samAccountName=krbtgt)(servicePrincipalName=*)))').FindAll()
所有DC域控
([adsisearcher]'(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))').FindAll()
指定组的所有直接成员(例如,域管理员)
([adsisearcher]'(memberOf=cn=DomainAdmins,cn=Users,dc=contoso,dc=com)').FindAll()
指定组的所有成员
([adsisearcher]'(memberOf:1.2.840.113556.1.4.1941:=cn=DomainAdmins,CN=Users,dc=contoso,dc=com)').FindAll()
受AdminSDHolder保护的所有对象
([adsisearcher]'(adminCount=1)').FindAll()
所有组策略(Group Policy)对象
([adsisearcher]'(objectCategory=groupPolicyContainer)').FindAll()
所有Exchange服务器
([adsisearcher]'(objectCategory=msExchExchangeServer)').FindAll()
所有只读DC
([adsisearcher]'(userAccountControl:1.2.840.113556.1.4.803:=67108864)').FindAll()
列出所有DNS记录
([adsisearcher]'(objectClass=dnsnode)').FindAll()
查找有LAPS密码的计算机
([adsisearcher]'(&(objectCategory=computer)(ms-MCSAdmPwd=*))').FindAll().properties
所有属于受AdminSDHolder保护的内置组的服务账户(例如,Domain Admins, Enterprise Admins, Administrators)
([adsisearcher]'(&(objectClass=user)(!(samAccountName=krbtgt)(servicePrincipalName=*)(
adminCount=1)))').FindAll()
所有在描述中带有"password"的用户对象
([adsisearcher]'(&(objectCategory=person)(objectClass=user)(description=password*))').FindAll()
3.域侦察示例
3.1 枚举具有adminCount=1值的帐户
所有受AdminSDHolder保护的用户都是Domain Admins, Enterprise Admins, Administrators, Backup Operators, Account Operators, Server Operators, Print Operators等组的成员。
LDAP查询:
([adsisearcher]'(&(objectClass=user)(adminCount=1))').FindAll()
3.2 枚举DNS zone
DNS zone位于活动目录中的容器RootDNSServers下。
$ADSI = ([ADSI]"LDAP://DC=RootDNSServers,CN=MicrosoftDNS,CN=System,DC=contoso,DC=com") $ADSI.psbase.Children | Format-Table name
3.3 枚举活动目录子站点
子网是与特定的AD站点相关的IP范围,为了获得AD中的所有子网。我们必须查看所有在子网容器中的子对象。CN=Subnet是CN=Sites的一个子容器。
$ADSI = ([ADSI]"LDAP://CN=Subnets,CN=Sites,CN=Configuration,DC=contoso,DC=com") $ADSI.psbase.Children | Format-Table name
3.4 枚举属于Domain Admin和Enterprise Admin的用户
([adsisearcher]'(memberOf=cn=Domain Admins,CN=Users,dc=contoso,dc=com)').FindAll()
3.5 枚举MicrosoDNS容器上的ACL
除了DNSAdmins之外,错误的委托权限可能导致权限的提升。
$ADSI=[ADSI]"LDAP://CN=MicrosoftDNS,CN=System,DC=contoso,DC=com" $ADSI.psbase.get_ObjectSecurity().getAccessRules($true, $true,[system.security.principal.NtAccount])
对象具有GenericWrite及以上权限(如GenericAll)可能导致提权。
$ADSI=[ADSI]"LDAP://CN=MicrosoftDNS,CN=System,DC=contoso,DC=com" $ADSI.psbase.get_ObjectSecurity().getAccessRules($true, $true,[system.security.principal.NtAccount]) |? ActiveDirectoryRights - Match "GenericWrite"
3.6 枚举AdminSDHolder容器上的ACL
AdminSDHolder是活动目录中的一个容器,它维护一个对象的权限列表,这些对象是活动目录中特权组的成员。这些组可以通过adminCount=1属性来识别。
$ADSI=[ADSI]"LDAP://CN=AdminSDHolder,CN=System,DC=contoso,DC=com" $ADSI.psbase.get_ObjectSecurity().getAccessRules($true, $true,[system.security.principal.NtAccount])
假设我们想找出哪些用户对AdminSDHolder容器拥有 "GenericAll"权限。
$ADSI=[ADSI]"LDAP://CN=AdminSDHolder,CN=System,DC=contoso,DC=com" $ADSI.psbase.get_ObjectSecurity().getAccessRules($true, $true,[system.security.principal.NtAccount]) |? ActiveDirectoryRights - Match "GenericAll"
参考资料:
Adversary Tactics:PowerShell(https://github.com/specterops/at-ps)
往期精选
围观
热文
热文
本文始发于微信公众号(天御攻防实验室):红队攻防揭秘 - 无感知域渗透(AD侦察)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论