环境
Active Directory Enumeration – Enumeration Using Legacy Windows Tools – VM Group 1
IP:192.168.169.70-76
首先连接192.168.169.75 Windows11环境
xfreerdp /u:stephanie /d:corp.com /v:192.168.169.75
密码:LegmanTeamBenzoin!!
1. net命令
1.1. 显示域中用户
net user /domain
1.2. 针对特定用户运行net user
net user jeffadmin /domain
jeffadmin 是域管理员组的一部分,这是我们应该注意的。如果我们设法破坏此帐户,
我们基本上会将自己提升为域管理员。
1.3. 显示域中的组
net group /domain
1.4. 显示特定组中的成员
net group "Sale Department" /domain
在实际评估中,
我们可能会枚举每个组,对结果进行编目
2. LDAP、CN、DN
AD 枚举依赖于 LDAP。当域计算机搜索对象(如打印机)或查询用户或组对象时,LDAP 用作查询
的通信通道。换句话说,LDAP是用于与Active Directory通信的协议。
LDAP 并非 AD 所独有。其他目录服务也使用它。
我们需要一个特定的LDAP ADsPath才能与AD服务进行通信。LDAP 路径的
原型如下所示:
LDAP://主机名[:端口号][/专有名称]
我们正在使用 corp.com 域,因此我们可以简单地将其添加到我们的LDAP路径中并可能获取信息。请注意,一个域可能有多个 DC,因此设置域名可能会解析为域中任何 DC 的 IP 地址。
为了使我们的枚举尽可能准确,我们应该寻找保存最新信息的 DC。这称为主域控制器 (PDC)。
若要查找 PDC,我们需要找到保存 PdcRoleOwner 属性的 DC。
DistinguishedName (DN)(可分辨名称)是 LDAP 路径的一部分。DN 是唯一标识 AD 中对象(包括域本身)的名称。
为了使 LDAP 正常工作,必须根据特定的命名标准格式化 AD(或其他目录服务)中的对象。
stephanie 是 corp.com 域中的用户对象。有了这个,DN 可能看起来像这样:
CN=Stephanie,CN=Users,DC=corp,DC=com
CN 称为公用名,它指定域中对象的标识符。虽然我们通常将“DC”称为 AD 术语中的域控制器,但当我们引用DN时,“DC”表示域组件。域组件表示LDAP树的顶部,在这种情况下,我们将其称为域本身的DN。
读取 DN 时,我们从右侧的域组件对象开始,然后向左移动。在上面的示例中,我们有四个组件,从名为 DC=corp,DC=com 的两个组件开始。如上所述的域组件对象表示遵循所需命名标准的LDAP 树的顶部。
继续通过 DN,CN=Users 表示存储用户对象的容器(也称为父容器)的公用名。最后,一直到左边,CN=Stephanie 表示用户对象本身的公用名,这也是层次结构中最低的。
System.DirectoryServices.ActiveDirectory 命名空间。虽然这里有一些类可供选择,但我们将
重点介绍域类。它特别包含对属性中 PdcRoleOwner 的引用,这正是我们所需要的。通过检查方法,我们找到了一个名为 GetCurrentDomain() 的方法,它将返回当前用户的域对象,在本例中为 stephanie。
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
自动化获得PdcRoleOwner脚本
# Store the domain object in the $domainObj variable
$domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
# Print the variable
$domainObj
运行脚本之间一定要先
powershell -ep bypass
脚本运行情况
只要PDC
# Store the domain object in the $domainObj variable
$domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
# Store the PdcRoleOwner name to the $PDC variable
$PDC = $domainObj.PdcRoleOwner.Name
# Print the $PDC variable
$PDC
虽然我们也可以通过域对象获取域的 DN,但它不遵循 LDAP 要求的命名标准。
我们知道基本域是 corp.com,DN 实际上是 DC=corp,DC=com
我们可以直接在PowerShell中使用ADSI来检索DN。我们将使用两个单引号来指示搜索从 AD 层次
结构的顶部开始。
使用 ADSI 获取域的 DN
([adsi]'').distinguishedName
获取LDAP
$PDC =[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().PdcRoleOwner.Name
$DN = ([adsi]'').distinguishedName
$LDAP = "LDAP://$PDC/$DN"
$LDAP
3. 为脚本增加搜索功能
我们将使用位于 System.DirectoryServices 命名空间中的两个 .NET 类,更具体地说是DirectoryEntry和 DirectorySearcher两类
使用DirectoryEntry需要注意的一件事是,我们可以将其凭据传递给域以进行身份验证。但是,由于我们已经登录,因此无需在此处执行此操作。
DirectoryEntry类封装 AD 服务层次结构中的对象。
我们希望从AD层次结构的最顶部进行搜索,因此我们将提供获得的DirectoryEntry类的LDAP路径。
DirectorySearcher使用 LDAP 对 AD 执行查询。创建目录搜索器的实例时,我们必须以 SearchRoot属性的形式指定要查询的 AD 服务。根据 Microsoft 的文档,此属性指示搜索在 AD 层次结构中的开始位置。
由于 DirectoryEntry 类封装了指向层次结构顶部的 LDAP 路径,因此我们会将其作为变量传递给DirectorySearcher。
$PDC =[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().PdcRoleOwner.Name
$DN = ([adsi]'').distinguishedName
$LDAP = "LDAP://$PDC/$DN"
$direntry = New-Object System.DirectoryServices.DirectoryEntry($LDAP)
$dirsearcher = New-Object System.DirectoryServices.DirectorySearcher($direntry)
$dirsearcher.FindAll()
我 们 添 加 了 $direntry 变 量 , 它 封 装 了 我 们 获 得 的 LDAP 路 径 。$dirsearcher变量包含$direntry变量,并将信息用作 SearchRoot,指向层次结构的顶部,DirectorySearcher 将在其中运行 FindAll() 方法。
但是出现了大量的输出
我们需要进行过滤
一种方法是设置一个筛选器,该筛选器将筛选samAccountType属性,该属性是应用于所有用户、计算机和组对象的属性。
我们将从 0x30000000(十进制805306368)开始,它将枚举域中的所有用户。要在脚本中实现过滤器,我们可以简单地将过滤器添加到$dirsearcher.filter
$PDC =[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().PdcRoleOwner.Name
$DN = ([adsi]'').distinguishedName
$LDAP = "LDAP://$PDC/$DN"
$direntry = New-Object System.DirectoryServices.DirectoryEntry($LDAP)
$dirsearcher = New-Object System.DirectoryServices.DirectorySearcher($direntry)
$dirsearcher.filter="samAccountType=805306368"
$dirsearcher.FindAll()
我们可以将从搜索中获得的结果存储在新变量中。我们将循环访问每个对象,并通过嵌套循环在其自己的行上打印每个属性
$PDC =[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().PdcRoleOwner.Name
$DN = ([adsi]'').distinguishedName
$LDAP = "LDAP://$PDC/$DN"
$direntry = New-Object System.DirectoryServices.DirectoryEntry($LDAP)
$dirsearcher = New-Object System.DirectoryServices.DirectorySearcher($direntry)
$dirsearcher.filter="samAccountType=805306368"
$result = $dirsearcher.FindAll()
Foreach($obj in $result)
{
Foreach($prop in $obj.Properties)
{
$prop
}
Write-Host "-------------------------------"
}
筛选 只要jeffadmin用户的
#搜索jeffadmin
$PDC =[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().PdcRoleOwner.Name
$DN = ([adsi]'').distinguishedName
$LDAP = "LDAP://$PDC/$DN"
$direntry = New-Object System.DirectoryServices.DirectoryEntry($LDAP)
$dirsearcher = New-Object System.DirectoryServices.DirectorySearcher($direntry)
$dirsearcher.filter="samAccountType=805306368"
$dirsearcher.filter="name=jeffadmin" #加了这一个filter
$result = $dirsearcher.FindAll()
Foreach($obj in $result)
{
Foreach($prop in $obj.Properties)
{
$prop
}
Write-Host "-------------------------------"
}
再简略一些
$dirsearcher = New-Object System.DirectoryServices.DirectorySearcher($direntry)
$dirsearcher.filter="name=jeffadmin"
$result = $dirsearcher.FindAll()
Foreach($obj in $result)
{
Foreach($prop in $obj.Properties)
{
$prop.memberof
}
Write-Host "-------------------------------"
}
我们可以使用此脚本枚举 AD 中可用的任何对象。