活动目录里的“幽灵”:动态对象的隐秘威胁

admin 2026-03-03 05:25:20 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文深入剖析了ActiveDirectory中动态对象功能的隐秘威胁,揭示攻击者如何利用其自动销毁不留痕迹的特性,绕过计算机账户配额限制、污染权限列表、在云端制造同步缺口等。文章通过六个具体攻击场景,详细拆解了攻击手法及其对事后取证造成的困难,并强调防御必须从被动响应转向主动监控,建议实时追踪entryTTL等属性以在证据销毁前识别入侵。 综合评分: 78 文章分类: 内网渗透,安全建设,威胁情报,应急响应,其他


cover_image

活动目录里的“幽灵”:动态对象的隐秘威胁

幻泉之洲

2026年2月26日 09:16 北京

Active Directory里那个不常被提起的“动态对象”功能,现在成了攻击者的完美隐身衣。它能自动销毁不留痕迹,让入侵者绕过配额、污染权限列表,甚至在云端留下后门,而安全分析人员最后什么都找不到。这篇文章将详细拆解攻击者是怎么利用这个功能的,以及防守方应该怎么办。

Active Directory的“动态对象”功能,本质上给攻击者提供了一个绝佳的隐身手段。这东西到点就自动消失,连个“墓碑”(记录删除对象的tombstone)都不会留下。攻击者能用它绕开创建限制,在访问控制列表里埋下隐患,在云环境里持续存在,等事后来调查,现场早就打扫干净了。

说白了,这功能就是个定时炸弹,引爆后连弹片都找不到。管理员可以创建在一定时间后自动删除的条目。但问题在于,攻击者能悄无声息地滥用这个功能,而且不会留下任何可供追踪的痕迹。

动态对象到底是个啥?

简单说,动态对象就是一个自带倒计时的AD对象。创建时你得给它设定一个存活时间。

说白了,这就是个一次性用品,用完就没了。管理员原本可能用它来做临时账户或测试组,没想到成了攻击者的漏洞。

从技术角度看动态对象

要创建这种临时对象,你得在生成时指定一个叫做“dynamicObject”的辅助类。这就等于给AD垃圾回收器(GC)排了个班,TTL一到,立刻清理。

动态对象有两个属性显示它什么时候会被删除:

  • msDS-Entry-Time-To-Die

    :记录一个绝对的过期时间点。

  • entryTTL

    :一个以秒为单位的倒计时。这值还能改,可以缩短也可以延长,对应的绝对时间也会跟着变。

过期之后,对象就彻底没了,只剩下一些间接的“残影”,比如日志里、缓存的Kerberos票据里,或者其他对象上还挂着指向它的链接。

不过,这东西也不总是TTL一归零就马上消失。在我们测试里,刚重启过的域控上删除是即时的,但在运行了不到24小时的系统上,我们观察到最长有15分钟的延迟。对安全团队来说,这段延迟时间很关键,相当于给调查取证留了个短暂的“加时赛”窗口,还能赶在它被永久移除前,把对象的属性备份下来看看。

理论上,动态对象的TTL可以设成1秒到1年。但实际限制是由配置分区里的msDS-Other-Settings属性控制的。这个属性管着最短允许时长和默认时长。

还有一点非常重要:配置分区(Configuration)和架构分区(Schema)不支持动态对象。从安全和稳定角度,这算是个好消息,避免了在最敏感的区域使用这些临时对象。想想看,要是某个架构类(比如一个用户类)突然自动消失了,所有依赖这个类的对象都会出问题,那场面可不好收拾。

下面,我们来看看攻击者是怎么把动态对象当武器使的,一共六个场景。

场景一:绕过计算机账户配额限制

默认情况下,ms-DS-MachineAccountQuota允许任何认证用户创建十个计算机对象。攻击者可以利用这些账户搞事,比如滥用基于资源的约束委派(RBCD),或者进行sAMAccountName欺骗(就是CVE-2021-42278和CVE-2021-42287那种,把计算机账户改名伪装成域控)。

但这里有个麻烦:配额一旦用满,攻击者就卡住了,而且那些恶意账户会一直留着成为证据。如果攻击没成功,没拿到更高权限,他们也删不掉自己建的计算机账户。这就像在犯罪现场留下了永久性的指纹。

但是,攻击者可以改改脚本(比如用PowerMad),创建动态的计算机账户。关键改动就一行代码:把创建时的objectClass从单纯的“Computer”,改成同时包含“dynamicObject”和“Computer”。

$request.Attributes.Add((New-Object “System.DirectoryServices.Protocols.DirectoryAttribute” -ArgumentList “objectClass”, “dynamicObject”, “Computer”)) > $null

如果攻击失败或者搞完了,这个计算机账户会在24小时后(默认TTL)自动删除。配额位置腾出来了,恶意计算机账户的痕迹也彻底消失了。

我们试过自定义一个很短的TTL,比如60秒,但由于标准用户账户的权限限制,请求被拒绝了。所以只能不指定TTL,让系统应用默认值:24小时(86400秒)后过期。

时间一到,这个计算机账户就静默、彻底地消失了,绕过了所有标准的保留机制。

有意思的是,用PowerShell代码创建动态用户或组时,你还能在ADUC管理控制台里看到entryTTL和msDS-Entry-Time-To-Die属性的值。

但奇怪的是,通过MAQ创建的动态计算机账户,在ADUC里却看不到entryTTL属性。用LDP.exe工具验证,其实这属性是设好了的。这说明微软管理控制台(MMC)在这块有点毛病。

不过,msDS-Entry-Time-To-Die属性倒是正常显示了。

所以,最根本的防御策略没变:应该把MAQ设成0来禁用它。靠事后排查已经没用了,重点得放在预防上。

场景二:污染主组ID

在这个攻击里,攻击者利用primaryGroupID属性。他把一个用户的主组ID设成一个动态组的相对标识符(RID)。

这会给用户一种不体现在常规工具(如memberOf属性)里的“隐形”组成员身份,但在获取Kerberos票据和访问令牌时,这个身份是完全有效的。

当那个动态组过期被删了,这个用户就剩下一个指向不存在的组的RID。这让审计变得非常困难。而且,AD不会在组被删时自动清理用户的主组ID,导致用户这个属性就废了,指向一个不存在的“幽灵”引用。

正常情况下,如果你把一个组设为用户的主组,那这个组是删不掉的。

这里就有个问题:主组删除保护,和动态对象的TTL自动删除,哪个优先级更高?

我们做了个测试:建了个动态组“DynGroup”,把“TestUserPGID”加为成员,然后把“TestUserPGID”的主组ID设成这个动态组的RID。

首先,我们试着手动用管理工具去删这个组。不出所料,操作被拦截了,报错和之前测试看到的一样。

后来,等对象过期了,系统自动把这个动态组删了。但这次删除并没有触发对用户primaryGroupID属性的清理。结果,这个属性现在指向一个不存在的对象了。

这就带来了不可预见的副作用。至少,这破坏了引用完整性,在AD数据库里留下了一堆“垃圾”。

更糟的是,如果这个动态组权限很高,它的自动删除会留下一个巨大的调查空白。因为动态对象绕过了标准的墓碑生命周期,防守方根本找不到这个组本身的任何记录。这种转瞬即逝的特性掩盖了用户权限的来源,让追根溯源和应急响应变得更复杂。说实话,这个漏洞挺阴的。

要降低风险,企业就该严格限制对primaryGroupID属性的修改。安全团队得靠实时监控来发现这些异常变动。

场景三:遗留的“幽灵”SID与AdminSDHolder污染

这可能是了解动态对象生命周期后,你脑子里蹦出来的第一个风险。为了说明它有多严重,我们不看普通文件服务器的ACL,直接拿AdminSDHolder对象开刀。

为啥选它?因为AdminSDHolder是所有AD里特权组和用户的安全模板。往这儿加的任何权限,都会被SDProp进程自动传播给所有Tier-0账户。结果就是,安全工具会报出一个有管理员权限的“未知SID”(一串数字)。调查员能看到有人有过权限,但根本不知道是谁。

这就演示了,一个短暂存在的对象,怎么能在不到60分钟的时间里,污染整个域的特权环境。

为了测试,我们对比一下标准删除和动态过期的行为:

  1. 创建两个用户:一个是普通AD用户“User_Standard”,另一个是设置了短TTL的动态用户“User_Dynamic”。
  2. 给这两个用户在AdminSDHolder的ACL里都加上一个允许访问的控制项(ACE)。

  1. 等“User_Dynamic”的TTL到期,被系统彻底删除。紧接着,手动删除“User_Standard”,它会进回收站/变成墓碑。

现在看看AdminSDHolder的ACL。

通常每60分钟,AdminSDHolder后台任务会重置所有特权对象的ACL,以匹配容器的安全描述符。

  • User_Standard

    :安全工具会标记这个SID,但因为对象还在AD里(作为墓碑),SID能解析出名字、删除日期等更多属性。

  • User_Dynamic

    :SID完全无法解析。它成了一个“幽灵SID”。

这对SOC分析师和事件响应人员来说工作量巨大。安全工具会不停地在你的核心资产上报告“具有提升权限的未知SID”。

取证调查立刻就受到损害了:

  • 没对象可恢复:动态对象不进回收站,没东西能还原。
  • 没墓碑:目录里完全没有这个对象的元数据痕迹。

蓝队会浪费大量时间去确认这到底是配置损坏,还是一种隐秘的持久化机制,而不是简单的配置错误。这制造了噪音和混乱,攻击者可能正是想用这个来分散你对真实威胁的注意力。

想抓住这个,你需要能实时追踪ACL和对象状态关系的安全监控。光靠事后分析没戏了。

场景四:滥用GPO和文件路径属性

在这个场景里,攻击者创建一个动态GPO,让它指向攻击者控制的服务上的恶意脚本。然后把这个GPO链接到一个组织单位(OU)上,目标计算机刷新策略时就会执行代码。

等TTL一到,GPO对象被删除。结果是啥?OU上的链接还在,但“断了”,因为GPO本身没了。这种手法把取证证据剥离了,调查人员只能看到一个坏掉的链接,没东西可分析。

标准的GPO由两部分组成,一是LDAP对象代表的组策略容器(GPC),二是SYSVOL文件夹里的文件(GPT)。GPC里有个属性叫gPCFileSysPath,告诉计算机去哪儿取文件执行。

根据Synacktiv的“GPODDITY”研究,攻击者可以修改这个属性,让它不指向SYSVOL,而是指向一个攻击者控制的恶意SMB共享。

把这种欺骗技术和动态对象结合起来,攻击者就能这么干:

  1. 创建一个动态GPO(类为dynamicObject和groupPolicyContainer),设个短TTL。
  2. 把gPCFileSysPath属性设成指向恶意服务器。
  3. 通过修改OU上的gPLink属性,把这个GPO链接到一个敏感OU上。
  4. 那个OU里的计算机刷新策略,读取恶意路径,执行载荷。

和之前一样,我们对比一下动态对象和标准对象的行为。

  1. TTL到期,系统彻底删除GPO对象。为了对比方便,我们也同时把“StdGpoOu”这个标准GPO删除。

标准GPO被删后,会进回收站或变成墓碑。分析人员可以恢复它,看看执行了什么脚本,或者gPCFileSysPath指向哪儿。

动态GPO呢?没有墓碑。对象直接没了。包含恶意路径(gPCFileSysPath)的属性被销毁了。唯一剩下的证据就是OU上的gPLink,指向一个已经不存在了的GUID。分析人员看到一个“断开的链接”,但根本无法证明是这个消失的对象执行了代码,也拿不到攻击者服务器的路径去分析载荷。

检测这类对象很难,因为它们经常在扫描发生前就消失了。但你可以找它们留下的痕迹和不一致性。比如动态对象是GPO时,它留下的不止是LDAP痕迹,可以通过寻找结构上的不一致性来识别。

场景五:转瞬即逝的DNS记录

第五个场景,攻击者可以创建一个动态DNS记录来重定向流量(比如伪装成文件服务器),以窃取凭据。这招利用了DNS记录本质上就是AD里的标准对象这一点。

结果就是,受害者的电脑查询服务器,缓存了恶意IP地址。动态DNS记录过期,从AD服务器上消失了。

这么一来,受害者已经中招了(还在用缓存的IP),但DNS服务器看起来干干净净。分析人员检查服务器日志,根本找不到那条恶意记录的影子。

和用户、组一样,AD集成的DNS记录也是标准的LDAP对象(类dnsNode),存放在DomainDnsZones或ForestDnsZones分区。因为它们不在配置或架构分区,所以可以被做成动态的。

这就给攻击者开了扇门,让他们能执行临时的流量重定向,比如伪装成合法服务器,或者通过中间人手法窃取凭据,还不会在目录里留下永久痕迹。

攻击者创建一个动态DNS记录会导致:1. DNS服务器读取它并应答查询;2. 客户端缓存这个应答。

为了说明取证上的影响,我们把它和标准DNS记录做个对比。

  1. 动态对象自我销毁。
  2. 攻击还在继续,因为受害者本地缓存着恶意数据,而DNS服务器上已经没有任何痕迹了。

注意:如果你在DNS管理器里还能看到这些记录,那只是因为DNS缓存。手动刷新一下视图,就能确认它们已经被删了。

这就造成了一种脱节:攻击在终端上持续,但源头证据在基础设施里已经没了。

追踪这些记录不容易:

  • 除非开启影响性能的调试模式,否则标准DNS日志很少捕获这种临时记录。
  • 和前面场景一样,没有墓碑,AD里没记录。
  • 分析人员调查一个奇怪的连接时,去查DNS服务器,会发现一个完全干净的域。

因为证据自我销毁,事后分析变得更困难。虽然你可以尝试实时捕捉配置变化,但区分恶意记录和合法记录本身就很难,还容易误报。

最可靠的检测策略是标记异常本身:报告任何是动态对象的DNS记录。这可以通过基于AD复制流的实时检测,或者通过事件日志来实现。

场景六:在Entra ID中制造混合同步缺口

最后一个场景,我们演示动态对象如何创建持续的“残影”,从本地域延伸到Entra ID云上。

攻击者在AD上创建一个动态用户时,Microsoft Entra Connect会照常把它同步到云端。但问题是,Entra Connect的增量同步依赖“墓碑”来识别被删除的对象。当动态用户过期时,同步引擎检测不到。

由于这些对象自我销毁不留痕迹,同步引擎永远不会在租户里触发删除。结果就是,云用户保持活跃状态,成了一个孤立的、在云端完全可用的“幽灵”用户。

我们来细看这个同步缺口。

为了看清,我们对比一个同步的动态用户和一个标准用户的生命周期。

TTL到零后,动态对象自我删除且无墓碑。我们手动删除标准对象来做对比。

标准对象的删除已经同步到了Entra租户,Entra用户被Entra Connect删掉了。但动态对象的删除没有被同步,这就产生了一个缺口。

更麻烦的是,尝试去管理这个对象(比如重置密码)会发现,尽管本地源早就没了,这个对象在云端仍是活跃且有效的。

注意:这种孤立的Entra用户,只能通过在Entra Connect中触发一次手动完全同步来移除,这会重新评估所有AD对象。

总结

滥用AD动态对象,把一个标准的、但很少被注意的功能,变成了取证的噩梦。利用自我删除,攻击者可以绕过回收站,滥用MAQ和DNS欺骗等机制。影响还不止在本地,它会蔓延到云,在Entra ID中制造同步缺口,而且在攻击结束后很久都还存在。

因为对这些对象进行事后分析往往非常困难,唯一有效的防御就是主动出击。道理很简单:赶在它自毁前抓住它。这需要近乎实时的监控和告警,专门盯着那些带有entryTTL或msDS-Entry-Time-To-Die属性的对象创建,并且把这些和出现的“幽灵SID”关联起来,抢在证据销毁前识别出入侵。

指望事后从日志里扒拉出真相,黄花菜都凉了。防御思路必须转变,从“出了事再查”变成“不让它出事”,或者至少,“出事了能马上知道”。


参考资料

[1] https://www.tenable.com/blog/active-directory-dynamic-objects-stealthy-threat


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:幻泉之洲 《活动目录里的“幽灵”:动态对象的隐秘威胁》

评论:0   参与:  0