- Вступ.
- Отримання повноважень.
- Випробування.
- Один домен без RODC.
- Домени з RODC.
- Ресурсний домен.
- Домени з різних лісів.
- Підсумки.
- Інструментальне засіб.
Часто при проектуванні логічної структури Active Directory виникає питання, яку модель вибрати, щоб вона була більш безпечною, більш надійної і в той же час більш вигідною і керованою.
Єфімов Геннадій
Вступ.
Часто при проектуванні логічної структури Active Directory виникає питання, яку модель вибрати, щоб вона була більш безпечною, більш надійної і в той же час більш вигідною і керованою.
Не секрет, що окремий домен в лісі не є ізольованою одиницею і що повноважний адміністратор з кореневого домену лісу може отримати доступ до будь-яких одиницям даних в лісі. Також будь-який адміністратор домену не з кореневого домену лісу може отримати доступ до інших доменів. Це описано в багатьох посібниках Microsoft. Ось уривок з керівництва по розробці архітектури служби каталогу (Designing and Deploying Directory and Security Services):
Because a domain is not a security boundary, it is possible for a malicious service administrator, such as a member of the Domain Admins group , to use nonstandard tools and procedures to gain full access to any domain in the forest or to any computer in the forest. For example, service administrators in a nonroot domain can make themselves members of the Enterprise Admins or Schema Admins group .
Я досить довго намагався знайти такі утиліти в Інтернеті, але так і не знайшов.
Далі спробуємо обговорити різні логічні моделі доменів / лісів і розглянемо отримання повноважень в цих самих доменах і лісах.
Отримання повноважень.
Є певний набір утиліт, який дозволяє мігрувати облікові записи учасників безпеки між доменами / лісами зі збереженням SID вихідного домену в SIDHistory об'єкта цільового домену. Ось деякі з них: ADMT, sidhist.vbs, sidewalk.exe. Дві останні утиліти з набору Support Tools. Як же працюють ці утиліти / скрипти? Всі вони використовують функцію DsAddSidHistory з бібліотеки Ntdsapi.dll. Функція документована. Використання її досить просте, як-то так (код на Delphi):
if DsBind ( '\\ targetdc.target.com', 'target.com', @hDs) = 0 then
if DsAddSidHistory (hDs, 0, 'source.com', 'SampleUser04', nil, nil, 'target.com', 'SampleUser03') = 0 then
Функція описана тут - http://msdn.microsoft.com/en-us/library/ms675918(VS.85).aspx
Але виконання даної функції накладає певні обмеження, зокрема повинні бути виконані наступні умови:
- адміністративні права в домені джерелі;
- права на додавання SidHistory в цільовому домені;
- на PDC в вихідному домені в реєстрі повинен бути ключ TCPIPClientSupport: DWORD = 1;
- повинна бути створена локальна група в цільовому домені - <SourceNETBIOSDomainName> $$$;
- в цільовому домені повинен бути включений аудит управління обліковими записами (Account Management - Success / Failure).
Міграція SID допускається між обліковими записами з well-known rid обліковими записами (це записи у яких відносний ідентифікатор у всіх доменах однаковий, але sid домену відрізняється), наприклад Domain Admins (S-15-21-SidДомена-512). Але потрібно дотримати весь цей список умов (перший вже говорить про марність спроб отримання якихось повноважень, вони вже є).
Спробуємо поглянути на архітектуру Active Directory:
Зі схеми наведеної вище (взята зі статті Technical Reference Active Directory Collection, Data Store) видно, що сама база даних AD, а точніше база даних ESE, надійно захищена рівнем DSA. DSA реалізує набір інтерфейсів і функцій для доступу до безпосередньо даними, які знаходяться в ntds.dit. Ну відповідно він припиняє будь-які спроби смухлевать.
Навіщо стукати в зачинені двері, вліз через відкриту кватирку. :)
Звернемося безпосередньо до рівня ESE.
Extensible Storage Engine (ESE) - це механізм доступу до даних з використанням індексного-послідовного методу доступу (ISAM). Багато додатків / сервери Windows використовують цей механізм для зберігання і обробки даних, наприклад DHCP, WINS, AD, Exchange (по-моєму, використовується якась особлива версія ESE). Інтерфейси / функції ESE документовані і досить добре описані. Детальніше http://msdn.microsoft.com/en-us/library/ms684493(EXCHG.10).aspx .
Відкривши ntds.dit виявилося невелика кількість таблиць (7): datatable, hiddentable, link_table, quota_rebuild_progress_table, quota_table, sdproptable, sd_table.
Нас цікавить таблиця datatable. Таблиця складається з безлічі атрибутів (стовпців), які відповідають атрибутам, визначеним у схемі AD. Виходить, що на рівні ESE у кожного об'єкта (а об'єктами є кортеж цієї таблиці) є всі атрибути AD. У цій таблиці знаходяться всі об'єкти AD. За назвою інших таблиць не важко здогадатися, що там зберігається. Атрибути (велика частина з них) іменуються наступним чином: ATTb589856, ATTj589855 і так далі. Що означають цифри в іменах і як вони пов'язані з атрибутами в схемі AD з'ясувати не вдалося, може хто-небудь підкаже :).
Отримавши список індексів для даної таблици був виявлений індекс з ім'ям nc_guid_Index, створений за стовпцями NCDNT_col: Long, ATTk589826: LongBinary. Оскільки об'єкти в Active Directory мають унікальні object-GUID, цей індекс нам особливо корисний, по ньому ми з легкістю визначаємо, що атрибут ATTk589826 це якраз Object-GUID. Будемо використовувати даний атрибут для пошуку об'єктів в таблиці.
Наступний цікавий індекс - NC_Acc_Type_Sid - NCDNT_col: Long, ATTj590126: Long, ATTr589970: LongBinary. Не важко здогадатися, що ATTr589970 це SID об'єкта. Він звичайно корисний для нас, але нас більше цікавить SidHistory. Ось тут не вийшло знайти інтуїтивно-зрозумілого індексу. Довелося перебрати значення всіх стовпців з типом LongBinary. Методом перебору з'ясувалося, що SidHistory це атрибут ATTr590433.
Власне все, що нам потрібно їсти, залишилося тільки прописати необхідні дані.
Покроково опишу процес:
- Змінюємо глобальні дані нашого майбутнього примірника ESE. Оскільки за замовчуванням розмір сторінки в ESE - 4КБ, а AD використовує 8Кб сторінки, потрібно поміняти глобальні настройки.
- Створюємо примірник.
- Ініціалізіруем.
- Створюємо сесію.
- Аттачем базу, позику її відкриває базу.
- Відкриваємо таблицю datatable.
- Встановлюємо поточний індекс INDEX_00090002 (це окремий індекс для атрибута ATTr590433).
- Створюємо ключ для пошуку, вказуємо в якості критерію пошуку GUID шуканого об'єкта.
- Здійснюємо пошук.
- У транзакції оновлюємо стовпець ATTr590433, записуючи в нього необхідні SID'и.
- Закриваємо БД, сесію, завершуємо екземпляр ESE.
Ось ніби і все.
Випробування.
Тепер спробуємо обговорити використання даного методу на різних моделях доменів / лісів Active Directory.
Один домен без RODC.
Якщо у користувача (необов'язково це повинен бути адміністратор) є фізичний доступ до контролера домену, то він може собі прописати SidHistory, використовуючи спосіб описаний вище.
Єдине що помічено, контролер домену дуже трепетно ставиться до облікового запису Administrator (S-1-5-21- ....-500), якщо додати цей SID, то прав ніяких не буде. Потрібно прописувати Domain Admins / Enterprise Admins.
Плюс ще є багато способів підвищення собі повноважень маючи фізичний доступ до контролера, наприклад використання rootkitов, або наприклад використання srvany + erd commander.
Домени з RODC.
RODC є Read-only тільки на рівні DSA. Тобто ніщо не заважає нам, скориставшись описаним методом, прописати собі SID повноважного користувача. І ось ми прописали собі SID в SIDHistory, аутентифицироваться у цього контролера, отримали маркер доступу, все чудово - є в ньому необхідний SID. Але такий маркер буде отримано тільки на підвладні RODC-контролеру сервери / служби. Якщо ж у RODC немає довгострокового ключа для якоїсь служби, то нам доводиться звертатися до «повноцінному» контролеру домену. У того в свою чергу немає даних про те, що у нас в SIDHistory прописаний супер-пупер SID. Більш того RODC і «нормальні» контролери домену судячи з усього використовують різні довгострокові ключі (про це говорить кілька учеток krbtgt) для шифрування TGT. Відповідно «нормальний» контролер домену видасть нам TGT з SIDHistory без повноважного SID, ми його дамо TGS для отримання Service Ticket, TGS скопіює набір SID з TGT, передасть Service Ticket нам, ми його надамо тій чи іншій службі, вона створить на його основі маркер . У цьому маркері не буде необхідності нам SIDа, відповідно ніяких повноважень ми не отримаємо.
Довгострокового ключа для служб на «нормальному» контролері домену (наприклад, служби LDAP, CIFS) у RODC немає, стандартними засобами не вдається його направити на RODC, тому ніяких повноважень в лісі ми не отримаємо.
Ось якби спробувати реплицировать дані з бази RODC на записуваний контролер домену, тоді б все вийшло. Вхідних з'єднань для реплікації від RODC немає, ні в Configuration, ні в repsFrom. Але мені здається RODC, як-то все одно в зворотну сторону реплицируется. На це питання поки немає відповіді.
Ресурсний домен.
Тут все теж саме, як і з одним доменом без RODC. Отримуємо фізичний доступ до контролера домену, виробляємо маніпуляції описані вище. Єдино не вийде використовувати rootkit'и і srvany + erd commander. В цьому плані звичайно модель з використанням ресурсних доменів є більш захищеною.
Домени з різних лісів.
Ми можемо прописати собі в SIDHistory SID повноважною облікового запису з іншого лісу. Якщо у нас створені довірчі відносини між доменами / лісами, так що вихідний домен довіряє цільовим домену, а значить може нас аутентифицировать і якщо фільтрація SidHistory відключена на цій довірі, то ми можемо отримати певні права на вихідний ліс / домен.
Якщо фільтрація SIDHistory відключена (за замовчуванням), то прописування SID в SIDHistory нічого нам не дасть. Можна звичайно прописати собі в якості основного SIDа SID Enterprise Adminа з домену джерела (а можна навіть кілька SIDов основних прописати), але це нічого не дасть.
При прописуванні кілька основних SID вивалюється помилка "Internal Error" і аутентифікація не проходить. При прописування в якості основного SID SID з іншого домену, контролер домену вважає цю учетку нерідний і аутентифікація також не відбувається.
Підсумки.
Найбільш захищеною показала себе модель з використанням RODC (хоча будь-які права можна отримати на підвладні RODC-сервери).
Використання окремих лісів надає ізоляцію ресурсів (особливо якщо включена фільтрація SIDHistory) і є одним з найбільш надійних засобів забезпечення безпеки, але є більш ресурсномісткої і витратною справою.
Використання моделі з ресурсними доменами або єдиним кореневим доменом лісу є небезпечним. Ізоляція даних і служб не відбувається. Як правило, це основні моделі проектування AD.
Ну і будь-яка з цих моделей стає безпечною, якщо обмежити фізичний доступ до контролерів домену.
Інструментальне засіб.
Кульмінація статті :). Власне утиліта, яка дозволяє в оффлайн режимі прописувати собі SID в SIDHistory. Без параметрів відображається.
Вимагає наявності встановленого на комп'ютері .Net Framework 2.0. Необхідно запускати на тій версії Windows під якою працює AD (через відмінності у версіях ESE).
http://download.securitylab.ru/_tools/ESEAddSidHistory.zip
MD5: F5489294F66769CAF09CACDA61B26426 ESEAddSidHistory.zip