Active Directory安全攻防(四)
原创
寰宇秘阁
寰宇秘阁
寰宇密阁
2026年7月6日 10:00
上海
在小说阅读器读本章
去阅读
在前几篇文章中,我们详细介绍了 Active Directory 的访问控制列表(ACL)机制——包括 ACL 与 ACE 的概念、DACL 自主访问控制模型、对象级与属性级的精细权限控制,以及权限继承机制。我们在防御建议中曾简要提到过 AdminSDHolder 保护机制,指出它能够每隔 60 分钟自动检查并重置受保护对象的 ACL。
那么,这个机制的具体工作原理是什么?它保护哪些账户?管理员如何配置和审计它?攻击者又可能如何利用或绕过它?
本篇文章将深入解析 Active Directory 中的安全描述符传播器(Security Descriptor Propagator,SDProp) 机制,这是 AD 为高权限管理员账户提供的一道关键安全防线。
一、SDProp 的基本概念
1.1 为什么需要 SDProp?
Active Directory 中存在一些拥有极高权限的账户——Domain Admins、Enterprise Admins、Schema Admins 等组的成员。这些账户一旦被攻击者篡改权限(例如通过 WriteDACL 给自己添加对这些账户的控制权),后果将是灾难性的。
为了应对这一风险,Active Directory 内置了一套自动化的权限保护机制——安全描述符传播器(SDProp)。
1.2 SDProp 的工作原理
SDProp 是一个在域控制器上周期性运行的后台进程,其核心逻辑如下:
- 定期执行:默认每 60 分钟运行一次
- 检查受保护账户:扫描所有属于预定义高权限安全组的账户
- 重置权限:将这些受保护账户上的继承权限全部移除,替换为 AdminSDHolder 容器上预定义的权限集
- 标记账户:将受保护账户的
adminCount属性设置为1
简单来说,无论攻击者如何篡改高权限账户的 ACL,SDProp 都会在下一个执行周期内将其强制恢复为预定义的安全权限。
SDProp 执行流程:
[每 60 分钟触发]
│
▼
[扫描所有受保护安全组的成员]
│
▼
[读取 AdminSDHolder 容器上的权限模板]
│
▼
[移除受保护账户上的所有继承权限]
│
▼
[将 AdminSDHolder 的权限显式应用到受保护账户]
│
▼
[设置 adminCount = 1]
│
▼
[将变更复制到域内其他域控制器]
二、受 SDProp 保护的安全组
SDProp 并非保护所有账户,而是专门保护属于以下预定义高权限安全组成员的账户:
| 安全组 | 说明 |
|---|---|
| Administrators | 域本地管理员组,对所在域的域控制器拥有管理权限,从而完全控制该域的域分区 |
| Domain Admins | 全局域管理员组,拥有与 Administrators 组相同的权限,同时也是域内所有非域控制器计算机(成员服务器和客户端)的本地管理员组成员 |
| Enterprise Admins | 通用组织管理员组,拥有与 Administrators 组相同的权限,但作用范围覆盖林中所有域 |
| Schema Admins | 架构管理员组,成员可以编辑 AD 架构,从而调整对象的默认权限 |
| Account Operators | 账户操作员组,可以管理 AD 中的账户,权限由架构中的默认安全描述符定义 |
| Server Operators | 服务器操作员组,可以启动服务和管理服务器 |
| Backup Operators | 备份操作员组,可以创建备份和恢复数据。特别注意:该组成员有权备份和恢复 AD 数据库(NTDS.DIT),这意味着他们可以离线提取所有域凭据 |
| Replication Operator | 复制操作员组,用于文件复制 |
| Print Operators | 打印操作员组,可以设置和管理打印机,并有权在服务器上安装驱动程序。由于该组是域级别的组,其成员有权在域控制器上安装驱动程序,这构成了潜在的安全风险 |
| Domain Controllers | 域控制器组,包含域中所有域控制器的计算机账户 |
安全提示:上表中的每一个组都拥有不同程度的高权限。特别值得关注的是 Backup Operators 和 Print Operators——它们的名字看起来\"人畜无害\",但实际上拥有可以被攻击者严重滥用的权限。Backup Operators 可以备份 NTDS.DIT 数据库,Print Operators 可以在域控制器上安装驱动程序(可能用于加载恶意代码)。
三、adminCount 属性
3.1 标记机制
当 SDProp 进程运行时,它会将所有受保护账户的 adminCount 属性设置为 1。这个属性是一个简单的标志位,表示该账户\"值得保护\"。
受保护账户的属性示例:
DN: CN=Administrator,CN=Users,DC=corp,DC=example,DC=com
adminCount: 1 ← SDProp 设置的标记
memberOf: CN=Domain Admins,CN=Users,DC=corp,DC=example,DC=com
3.2 查询受 SDProp 保护的账户
管理员和安全人员可以通过多种方式查询当前受 SDProp 保护的所有账户:
方法一:LDAP 查询
在 Active Directory 用户和计算机(ADUC)控制台中,或使用任何 LDAP 工具,执行以下搜索过滤器:
(adminCount=*)
这将返回所有 adminCount 属性被设置过的对象。
方法二:PowerShell
# 查询所有 adminCount 被设置的对象
Get-ADObject-Filter'admincount -like \"*\"'
# 更精确地查询 adminCount=1 的用户账户
Get-ADUser-Filter'admincount -eq 1'-Properties adminCount, MemberOf |
Select-Object Name, adminCount, @{N='Groups';E={$_.MemberOf -join'; '}}
注意:
Get-ADObject命令需要安装 Active Directory PowerShell 模块。在服务器上,可以通过\"远程服务器管理工具(RSAT)\"功能直接启用;在客户端上,则需要单独安装 RSAT 工具包。
3.3 adminCount 的\"残留\"问题
这是 SDProp 机制中一个非常重要但容易被忽视的特性:
当你将一个账户从受保护的安全组中移除时,
adminCount属性不会被自动重置。
也就是说,即使某个用户已经不再是 Domain Admins 的成员,他的 adminCount 属性仍然保持为 1,其权限仍然受到限制(继承权限被移除)。
这样设计是出于安全考虑——因为你无法确定该账户在拥有高权限期间,是否已经在网络中的其他系统上获得了额外的授权(例如通过本地组成员关系或显式 ACL 授权)。
微软的官方建议是:
如果需要撤销某个账户的管理员权限,建议创建一个全新的账户,而不是简单地将旧账户从管理员组中移除。这样可以确保旧账户残留的权限和授权不会带来安全隐患。
这一建议在实际环境中经常被忽略,但从安全角度来看非常重要。一个 adminCount=1 但已不在任何高权限组中的\"孤儿账户\",可能仍然在某些系统上拥有本地管理员权限或其他敏感授权,构成隐蔽的攻击面。
四、AdminSDHolder 容器
4.1 权限模板的来源
SDProp 在重置受保护账户的权限时,使用的权限模板来自 AdminSDHolder 容器。该容器位于域分区的 System 容器下:
域分区
└── CN=System
└── CN=AdminSDHolder ← 权限模板容器
AdminSDHolder 容器上配置的 ACL 就是所有受保护账户的\"标准权限集\"。每次 SDProp 运行时,都会读取这个容器上的权限,然后将其应用到所有受保护账户上。
4.2 自定义权限模板
如果管理员需要调整受保护账户的默认权限,可以直接修改 AdminSDHolder 容器上的 ACL。修改后的权限将在下一次 SDProp 执行时自动应用到所有受保护账户。
例如,如果安全团队需要对所有高权限账户添加一条审计 ACE,只需在 AdminSDHolder 容器上添加一次,SDProp 就会自动将其传播到所有受保护账户。
安全警告:正因为 AdminSDHolder 是所有高权限账户的权限模板来源,对 AdminSDHolder 容器的修改权限必须严格控制。如果攻击者能够修改 AdminSDHolder 上的 ACL(例如添加一条允许自己完全控制的 ACE),那么这条恶意权限将在 60 分钟内被自动传播到所有高权限账户上——这是一种非常隐蔽且强大的持久化手段。
4.3 权限继承的移除
SDProp 处理过的账户有一个显著特征:所有继承的权限都被移除,只保留显式设置的权限。
在 ADUC 中查看受保护账户的安全选项卡时,你会发现\"继承自(Inherited from)\"列全部显示为 “无(None)”,这表明所有权限都是显式设置的,而非从上级 OU 继承而来。
受保护账户的权限特征:
┌──────────────────────────────────────────────────┐
│ 安全主体 │ 权限 │ 继承自 │
├──────────────────────────────────────────────────┤
│ SYSTEM │ 完全控制 │ None(显式) │
│ Domain Admins │ 完全控制 │ None(显式) │
│ Administrators │ 完全控制 │ None(显式) │
│ ... │ ... │ None(显式) │
└──────────────────────────────────────────────────┘
普通账户的权限特征:
┌──────────────────────────────────────────────────┐
│ 安全主体 │ 权限 │ 继承自 │
├──────────────────────────────────────────────────┤
│ SYSTEM │ 完全控制 │ 父级 OU │
│ Domain Admins │ 完全控制 │ 父级 OU │
│ Help Desk │ 重置密码 │ 父级 OU │
│ ... │ ... │ ... │
└──────────────────────────────────────────────────┘
这意味着,即使管理员在某个 OU 上设置了权限委派(例如允许 Help Desk 重置该 OU 下所有用户的密码),如果该 OU 中包含受 SDProp 保护的账户,这些委派权限也不会对受保护账户生效——因为继承权限已被 SDProp 移除。
五、配置 SDProp 的执行频率
5.1 注册表配置
SDProp 的默认执行间隔为 60 分钟。如果需要调整这个频率,可以通过修改注册表实现:
注册表路径:
HKLM\\SYSTEM\\CurrentControlSet\\Services\\NTDS\\Parameters
值名称: AdminSDProtectFrequency
值类型: DWORD
值数据: 以秒为单位的执行间隔
例如,将值设置为 1800 表示每 30 分钟执行一次,设置为 3600 表示恢复默认的 60 分钟间隔。
注意:缩短执行间隔会增加域控制器的负载,因为每次执行都需要扫描所有受保护账户并进行权限比对。在大型环境中,应谨慎调整此参数。
5.2 排除特定组
在某些场景下,管理员可能希望将某些预定义的受保护安全组从 SDProp 的保护范围中排除。例如,Account Operators、Server Operators、Print Operators 和 Backup Operators 这些组在某些环境中可能需要更灵活的权限委派,而 SDProp 的自动权限重置会干扰这些委派。
Active Directory 提供了一个注册表配置项,允许管理员排除特定的操作员组:
注册表路径:
HKLM\\SYSTEM\\CurrentControlSet\\Services\\NTDS\\Parameters
值名称: dsHeuristics
重要说明:
dsHeuristics实际上不是一个注册表值,而是存储在 配置分区 中的一个属性,位于以下 DN:
CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=<domain>该属性是一个字符串,其中第 16 个字符控制哪些操作员组被排除在 SDProp 保护之外。
dsHeuristics 第 16 个字符的取值及其含义如下:
| 值 | 排除的组 |
|---|---|
| 0 (默认) | 不排除任何组,所有预定义组均受 SDProp 保护 |
| 1 | 排除 Account Operators |
| 2 | 排除 Server Operators |
| 4 | 排除 Print Operators |
| 8 | 排除 Backup Operators |
这些值可以组合使用(按位或运算)。例如:
| 组合值 | 效果 |
|---|---|
| 3 | 排除 Account Operators(1)+ Server Operators(2) |
| 5 | 排除 Account Operators(1)+ Print Operators(4) |
| 7 | 排除 Account Operators(1)+ Server Operators(2)+ Print Operators(4) |
| f (即 15) | 排除所有四个操作员组 |
配置示例:
假设当前 dsHeuristics 的值为 0000000001001(13 个字符),要排除 Account Operators 和 Server Operators,需要将第 16 个字符设置为 3。由于字符串需要至少 16 个字符长,中间缺少的位置用默认值填充:
原始值: 0000000001001
修改后: 0000000001001003
^
第 16 位 = 3(排除 Account Operators + Server Operators)
使用 PowerShell 查看和修改 dsHeuristics:
# 查看当前 dsHeuristics 值
$directoryService = \"CN=Directory Service,CN=Windows NT,CN=Services,\"+(Get-ADRootDSE).configurationNamingContext
Get-ADObject$directoryService-Properties dsHeuristics |Select-Object dsHeuristics
# 修改 dsHeuristics(请务必谨慎操作)
Set-ADObject$directoryService-Replace @{dsHeuristics = \"0000000001001003\"}
安全警告:将安全组从 SDProp 保护中排除意味着这些组的成员将不再受到自动权限重置的保护。攻击者如果能够篡改这些账户的 ACL,修改将不会被自动恢复。因此,除非有明确的业务需求,否则强烈建议保持默认配置,不要排除任何组。
额外注意:
dsHeuristics属性控制着 Active Directory 的多项行为,不仅仅是 SDProp 排除。修改此属性时必须非常谨慎,确保只修改目标位置的字符,不要意外更改其他位置的值,否则可能导致意想不到的 AD 行为变化。
六、SDProp 的安全审计与攻击检测
6.1 审计 AdminSDHolder 容器的权限变更
由于 AdminSDHolder 是所有高权限账户的权限模板来源,对其进行的任何修改都应被视为高优先级安全事件。管理员应配置以下审计策略:
步骤一:启用对象级审计
在组策略中启用以下审计策略:
计算机配置 → Windows 设置 → 安全设置 → 高级审计策略配置
→ DS 访问
→ 审核目录服务更改:成功、失败
步骤二:在 AdminSDHolder 容器上配置 SACL
在 AdminSDHolder 容器的安全描述符中添加系统审计 ACE(SACL),监控以下操作:
- 修改权限(Modify Permissions / WriteDACL)
- 修改所有者(Modify Owner / WriteOwner)
- 写入属性(Write All Properties)
AdminSDHolder 审计配置示例:
SACL:
主体: Everyone
类型: 成功审计
权限: 修改权限、修改所有者、写入所有属性
配置完成后,任何对 AdminSDHolder 容器 ACL 的修改都会在安全事件日志中生成 事件 ID 5136(目录服务对象已修改)。
6.2 检测 adminCount 孤儿账户
如前所述,当账户从受保护组中移除时,adminCount 属性不会自动清除。这些\"孤儿账户\"可能构成安全隐患。安全团队应定期扫描并清理这些账户:
# 查找 adminCount=1 但不属于任何受保护组的\"孤儿\"账户
$protectedGroups = @(
\"Domain Admins\",
\"Enterprise Admins\",
\"Schema Admins\",
\"Administrators\",
\"Account Operators\",
\"Server Operators\",
\"Backup Operators\",
\"Print Operators\",
\"Domain Controllers\",
\"Replicator\"
)
# 获取所有受保护组的成员
$protectedMembers = @()
foreach($group in $protectedGroups){
try{
$members = Get-ADGroupMember-Identity $group-Recursive |Select-Object-ExpandProperty distinguishedName
$protectedMembers+=$members
}catch{
# 某些组可能不存在(如 Enterprise Admins 仅在林根域中)
}
}
$protectedMembers = $protectedMembers|Sort-Object-Unique
# 获取所有 adminCount=1 的用户
$adminCountUsers = Get-ADUser-Filter'admincount -eq 1'-Properties adminCount |
Select-Object distinguishedName, Name, Enabled
# 找出孤儿账户
$orphanedAccounts = $adminCountUsers|Where-Object{
$_.distinguishedName -notin$protectedMembers
}
# 输出结果
$orphanedAccounts|Format-Table Name, Enabled, distinguishedName -AutoSize
对于确认的孤儿账户,管理员应:
- 评估风险:检查该账户在其他系统上是否仍有残留权限
- 重置 adminCount:将
adminCount属性清除 - 恢复权限继承:在该账户的安全选项卡中重新启用权限继承
- 考虑禁用或删除:如果该账户不再需要,应予以禁用或删除
# 清理孤儿账户示例(请在测试环境中验证后再在生产环境执行)
foreach($account in $orphanedAccounts){
# 清除 adminCount 属性
Set-ADUser-Identity $account.distinguishedName -Clear adminCount
# 恢复权限继承(需要使用 .NET 方法)
$user = [ADSI]\"LDAP://$($account.distinguishedName)\"
$user.ObjectSecurity.SetAccessRuleProtection($false,$true)# 启用继承
$user.CommitChanges()
Write-Host\"已清理: $($account.Name)\"
}
6.3 检测针对 AdminSDHolder 的攻击
攻击者可能利用 AdminSDHolder 作为持久化后门。常见的攻击手法是:
- 攻击者获得域管理员权限后,在 AdminSDHolder 容器上添加一条 ACE,授予某个普通账户(或攻击者控制的账户)完全控制权限
- 等待 SDProp 执行(最多 60 分钟),该权限就会被自动传播到所有高权限账户
- 即使管理员发现并修复了攻击者在某个高权限账户上的恶意权限,SDProp 会在下一个周期再次从 AdminSDHolder 模板中恢复这条恶意 ACE
检测方法:
# 获取 AdminSDHolder 容器的 ACL
$adminSDHolder = \"AD:\\CN=AdminSDHolder,CN=System,\"+(Get-ADDomain).DistinguishedName
$acl = Get-Acl$adminSDHolder
# 列出所有显式 ACE,重点关注非默认的安全主体
$acl.Access |Where-Object{$_.IsInherited -eq$false}|
Select-Object IdentityReference, AccessControlType, ActiveDirectoryRights |
Format-Table-AutoSize
安全团队应维护一份 AdminSDHolder 容器的基线 ACL 快照,定期与当前 ACL 进行比对,及时发现未经授权的变更。
七、SDProp 在攻防场景中的意义
7.1 防御视角
从防御角度来看,SDProp 提供了以下关键保护:
- 自动修复:即使攻击者临时篡改了高权限账户的 ACL,SDProp 会在 60 分钟内自动恢复
- 权限隔离:通过移除继承权限,防止低权限管理员通过 OU 级别的委派间接控制高权限账户
- 统一管理:通过 AdminSDHolder 模板集中管理所有高权限账户的权限,确保一致性
7.2 攻击视角
从攻击角度来看,SDProp 也存在可被利用的特性:
| 攻击手法 | 描述 |
|---|---|
| AdminSDHolder 后门 | 在 AdminSDHolder 上添加恶意 ACE,利用 SDProp 自动传播到所有高权限账户,实现持久化 |
| 手动触发 SDProp | 攻击者可以通过修改 RootDSE 的 RunProtectAdminGroupsTask 操作属性,立即触发 SDProp 执行,无需等待 60 分钟 |
| 利用 adminCount 孤儿 | 查找 adminCount=1 但已不在受保护组中的账户,这些账户可能仍在其他系统上拥有残留的高权限 |
| 修改 dsHeuristics | 通过修改 dsHeuristics 属性将某些组排除出 SDProp 保护,使这些组的成员不再受到自动权限重置的保护 |
7.3 防御建议总结
- 严格监控 AdminSDHolder 容器:对其 ACL 的任何变更都应触发高优先级告警
- 定期清理 adminCount 孤儿账户:建立自动化脚本,定期扫描并处理不再属于受保护组但
adminCount仍为 1 的账户 - 监控 dsHeuristics 属性变更:确保没有未经授权的修改将安全组排除出 SDProp 保护
- 遵循最小权限原则:尽量减少高权限安全组的成员数量,降低攻击面
- 使用专用管理员账户:为管理任务创建专用账户,不要将日常使用的账户加入高权限组
- 建立 ACL 基线:维护 AdminSDHolder 和关键高权限账户的 ACL 基线快照,定期比对检测异常
总结
安全描述符传播器(SDProp)是 Active Directory 为高权限账户提供的一道重要安全防线。它通过周期性地将 AdminSDHolder 容器上的权限模板强制应用到所有受保护账户,确保这些关键账户的 ACL 不会被持久性篡改。
然而,SDProp 并非万能的。它的保护机制本身也可能被攻击者利用——特别是通过在 AdminSDHolder 上植入后门 ACE 来实现隐蔽的持久化。因此,安全团队不仅需要理解 SDProp 的工作原理,还需要建立完善的监控和审计机制,确保这道防线本身不会成为攻击者的武器。
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论