Netwrix 1Secure 提供跨数据和身份的统一可见性——免费试用14天,享有完全访问权限。开始免费试用

资源中心博客

使用 PowerShell 的 LDAP 侦察基础

使用 PowerShell 的 LDAP 侦察基础

Mar 17, 2023

在本系列的 入门文章中,我们回顾了什么是 Active Directory(AD)服务账号,解释了这些特权账号为何是严重的安全风险,并承诺在后续文章中详细介绍针对服务账号的 4 种攻击类型。本文将探讨其中的第一种攻击:LDAP 侦察。攻击者可以在规避检测的同时,在 IT 环境中发现服务账号。

具体来说,在这篇文章中,我们将探讨:攻击者即使没有特殊权限(例如 Domain Admin,甚至本地 Administrator 权限),也可以使用简单的 PowerShell 查询来查找服务帐户,而无需安装或学习诸如 Bloodhound 之类的专业工具。

查找特权帐户

Active Directory 提供了许多安全性和管理方面的优势,但也可能让好奇的攻击者觉得事情变得过于容易。由于 AD 的架构,一旦攻击者渗透到任何一台加入域的计算机,就能够查询目录及其对象。而且由于默认情况下 Active Directory 不提供用于对可疑活动进行审计和告警的机制,他们往往可以规避检测。

以下是攻击者通过查询 LDAP 来发现服务帐户的一些方式。

服务主体名称(Service Principal Name,SPN)发现

服务账户利用 SPN 来支持 Kerberos 身份验证。尽管这能提高安全性,但也会留下清晰的线索,说明这些账户具体在哪里被使用以及用于什么用途。攻击者可以轻松利用这些信息。SPN 通常用于运行服务,以支持诸如 Microsoft SQL Server 和 SharePoint 之类的应用程序。

在另一篇 blog post 中,我们演示了如何进行高级 AD 侦察;不过,获取此处所需信息还有更简单的方法。通过使用下面这个简单的 LDAP 查询,攻击者可以获取已注册 SPN 的 AD 账户列表,以及这些账户可访问的计算机、应用程序和数据:

      #Build LDAP filters to look for users with SPN values registered for current domain
$ldapFilter = "(&(objectclass=user)(objectcategory=user)(servicePrincipalName=*))"
$domain = New-Object System.DirectoryServices.DirectoryEntry
$search = New-Object System.DirectoryServices.DirectorySearcher
$search.SearchRoot = $domain
$search.PageSize = 1000
$search.Filter = $ldapFilter
$search.SearchScope = "Subtree"
#Execute Search
$results = $search.FindAll()
#Display SPN values from the returned objects
foreach ($result in $results)
{
    $userEntry = $result.GetDirectoryEntry()
    Write-Host "User Name = " $userEntry.name
    foreach ($SPN in $userEntry.servicePrincipalName)
    {
        Write-Host "SPN = " $SPN      
    }
    Write-Host ""   
}
      

结果中的 SPN 值将揭示每个账户在该系统上注册的位置,以及它注册用于哪些服务。例如,下面是某个 SQL 服务账户的 SPN 值:

Image

使用通用对象属性发现服务账户

尽管 SPN 非常可靠且信息量丰富,但它们并不能生成服务账户的完整清单,因为许多账户并不会通过 SPN 与 Kerberos 集成,并且不会设置任何 SPN 值。不过,即使攻击者没有域权限,仍常常可以通过其他方式发现服务账户。特别是,大多数组织都会使用命名规范,例如让所有服务账户名称都以“ SVC ”或类似内容开头;并且服务账户通常会被放置到它们各自的组织单元(OU)或组中。

基于账户命名规范查找服务账户

下面是一个 PowerShell 脚本,用于查找名称中包含“svc”的所有账户:

      #Build LDAP filter to find service accounts based on naming conventions
$ldapFilter = "(&(objectclass=Person)(cn=*svc*))"
$domain = New-Object System.DirectoryServices.DirectoryEntry
$search = New-Object System.DirectoryServices.DirectorySearcher
$search.SearchRoot = $domain
$search.PageSize = 1000
$search.Filter = $ldapFilter
$search.SearchScope = "Subtree"

#Add list of properties to search for
$objProperties = "name"
Foreach ($i in $objProperties){$search.PropertiesToLoad.Add($i)}

#Execute Search
$results = $search.FindAll()
#Display values from the returned objects
foreach ($result in $results)
{
    $userEntry = $result.GetDirectoryEntry()
    Write-Host "User Name = " $userEntry.name
    Write-Host ""   
}
      

基于 OU 查找服务账户

下面是一个 LDAP 过滤器,可以替换到前面的脚本中,用于查找名称中包含“Service”或“svc”的任何 OU:

      $ldapFilter = "(&(objectClass=organizationalUnit)(|name=*Service*)(name=*svc*)))"

The attacker can then search those OUs for all user objects to find your service accounts. This script focuses on one OU with “Service” in its name:

$search = New-Object System,DirecoryServices.DirectorySearcher
$search.SearchRoot = "LDAP://OU=Service Accounts,OU=JEFFLAB,DC=local"
$search.PageSize = 1000
$search.Filter = $ldapFilter
$search.SearchScope = "Subtree"
      

通过用户账户控制进行服务账户发现

另一种“阴险”的方法是在 Active Directory 中搜索服务账户:查看账户控制设置。因为服务账户的配置往往与普通用户账户不同。最典型的例子就是 “password never expires” 这个设置——服务账户可能会将密码设置为永不过期,因为重置密码的过程可能很繁琐,并导致应用或服务中断。

Image

使用 PowerShell,可以借助稍微复杂一点的 LDAP 过滤器找到启用了此值的所有账户:

      $ldapFilter = "(&(objectclass=user)(objectcategory=user)(useraccountcontrol:1.2.840.113556.1.4.803:=65536))"
      

特权发现

虽然本文只关注在不利用任何权限的情况下查找服务账户的方法,但如果攻击者确实找到一个在网络中的一个或多个系统上拥有权限的账户,那么发现服务账户的其他有效方法还有很多,包括:

  • 枚举终端上的服务并提取 startname 帐户
  • 在 web.config、脚本以及其他可能对服务帐户进行硬编码的位置中查找连接字符串
  • 探究已获得“Log on as a Service”权限的用户的本地策略
  • 提取非交互式登录类型的事件日志
  • 查找应用程序池以及其他 Web 应用程序服务帐户

利用已发现的账户

一旦攻击者拥有服务账户列表,下一步就是对其进行利用。请在以下文章中了解其中的一些选择:

了解 LDAP 侦察以及其他攻击技术,请查看 Netwrix attack catalog

分享到

了解更多

关于作者

Jeff Warren

首席产品官

Jeff Warren 负责监督 Netwrix 的产品组合,在安全领域的产品管理与开发方面拥有十多年的经验。在加入 Netwrix 之前,Jeff 曾在 Stealthbits Technologies 领导产品团队;他运用自己作为软件工程师的经验,开发创新且面向企业规模的安全解决方案。凭借亲力亲为的工作方式以及解决棘手安全挑战的能力,Jeff 致力于打造真正可落地、行之有效的实用解决方案。他拥有特拉华大学(University of Delaware)的信息系统(Information Systems)学士学位。