Показаны сообщения с ярлыком Безопасность. Показать все сообщения
Показаны сообщения с ярлыком Безопасность. Показать все сообщения

четверг, 7 апреля 2011 г.

PKI: Мифы о мифах.

Еще один миф о мифах, связанный с PKI. Недавно прочитал блог одного специалиста, в котором он рассказывает, что же такое PKI, философию этой инфраструктуры.
В свою очередь, этот специалист писал, так называемую, рецензию на статью другого специалиста, тот на третьего. Запутанная цепочка. Надеюсь, она продолжится. И кто-то напишет про мои неточности и ошибки.

Меня заинтересовали (проще говоря - прикапался) некоторые высказывания, которые достаточно пространно (а на мой взгляд неправильно) характеризуют эту инфраструктуру.
Примерно это звучало как, инфраструктура PKI – это набор правил, которые должны соблюдаться. Что эти правила соблюдаются во всех аспектах PKI. Что у PKI железная логика. Что доверие к сертификату строится по наличию «сертификатов пути» в контейнерах Trusted Root Authority и Trusted People (если говорить о реализации в Windows). Что при использовании приватного ключа для электронной подписи налагаются ограничения на валидность сертификата (конкретно шел разговор о просроченности сертификата). Вроде все.

Так вот, хотелось бы продолжить цепочку этих статей, отрывающих глаза на использование этой загадочной технологии.

Начнем с размышлений о том, что такое PKI. PKI – это инфраструктура открытого ключа. То есть это набор правил, политик, программных и аппаратных средств, которые и составляют эту инфраструктуру. И необязательно это только электронные виды средств, это и люди, и документы (писульки) и т.д. А ключевыми фигурами в этой инфраструктуре выступают закрытый и открытый ключи. Как вы их будете использовать – это ваше дело. Все зависит от требований.
PKI настолько гибкая инфраструктура, что каких-либо правил не налагает, а предоставляет только вспомогательные средства, позволяющие принимать решения по использованию ключей входящих в эту инфраструктуру.
Для меня всегда остается загадкой использование PKI конкретным приложением. Например, нельзя с полной уверенностью сказать налагает ли приложение какие-либо ограничения на сертификат, должен ли этот сертификат быть доверенным, действительным по датам, должен ли он содержать определенную политику приложений, в какое хранилище этот сертификат нужно устанавливать. Я даже не могу точно сказать, как строится цепочка доверия – используются ли промежуточные сертификаты из хранилища пользователя или компьютера.
И это все из-за того, что инфраструктура PKI очень гибкая и ни какой железной логики у нее нет. Используйте ключи так, как хотите.

Рассмотрим пример использования ключей PKI. Попутно ответим на другие заблуждения.
1) Сгенерируем наш объект испытаний (статья написана 08.04.2010):
makecert -a sha1 -sky signature -b 04/01/2011 -e 04/02/2011 -r -pe -sr CurrentUser -n "CN=Self" -ss My
Этот сертификат является самоподписанным, недоверяемым и просроченным. Устанавливается в хранилище пользователя.

2) Продолжим следующим кодом (c#):
X509Store store = new X509Store("My", StoreLocation.CurrentUser);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
X509Certificate2 cert = store.Certificates[1]; // Сертификатов у меня 2. Сгенерированный находится под номером 1. Можно также воспользоваться методом Find для поиска по атрибутам сертификата
RSACryptoServiceProvider csp = null;
csp = (RSACryptoServiceProvider)cert.PrivateKey;
SHA1Managed sha = new SHA1Managed();
string str = "VADIM";
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] data = encoding.GetBytes(str);
byte[] hash = sha.ComputeHash(data); //генерим хэш
byte[] signature = csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")); //Генерируем сигнатуру

//Здесь представим, что принимающая сторона проверяет сигнатуру
str = "VADIM1"; // Исходная строка.. злоумышленник ее изменил.. Затем замените на VADIM без единички.. в конце должно показать true
byte[] destData = encoding.GetBytes(str);
byte[] hashdest = sha.ComputeHash(destData);
csp = (RSACryptoServiceProvider)cert.PublicKey.Key;
MessageBox.Show(
(csp.VerifyHash(hashdest, CryptoConfig.MapNameToOID("SHA1"), signature)).ToString()); // Должно отобразиться false.

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

Что мы получили? Мы развеяли миф об использовании нехороших сертификатов при подписывании. Шифрование нехорошими сертификатами не буду демонстрирова – поверьте на слово или прочитайте про анонимный TLS в Exchange 2010 (в качестве примера).
Давайте теперь разберемся с контейнерами Trusted Root Authority и Trusted People. Не факт, что приложение будет использовать контейнер Trusted People при определении доверия к сертификату.

Проверка происходит следующим образом (опять же конкретная реализация):
X509Chain chain = new X509Chain(false);
chain.Build(cert); // проверяем наш предыдущий сертификат

На данном этапе сертификат не установлен в Trusted Root Authority и не установлен в Trusted People.
Массив chain.Status должен содержать два элемента – один говорит о том, что нет доверия, второй, что сертификат просрочен.

Давайте теперь добавим сертификат в Trusted People. Copy-Paste.
Выполним тот же код:
X509Chain chain = new X509Chain(false);
chain.Build(cert);

Массив chainStatus содержит те же два элемента.

А теперь добавим в Trusted Root Authority.

Код:
X509Chain chain = new X509Chain(false);
chain.Build(cert);

На этот раз chain.Status содержит только один элемент – просроченный сертификат.
Здесь мы развеяли миф о том, что при построении доверия используются оба контейнера.
Стоит обратить внимание на параметр конструктура – false. True означает, что мы будем использовать при проверке сертификата контекст компьютера, false – пользователя (как в нашем случае). Видите, даже тут нельзя точно сказать какое хранилище будет использоваться при проверке валидности. Гибкий PKI.

Мы провели проверку валидности по умолчанию (можно было указать проверку других параметров). Вопрос: используется или нет Trusted People при построении доверия? Нельзя сказать точно. Поскольку в проверку все-таки можно включить этот контейнер или даже другие контейнеры. Но в нашем случае Trusted People не использовался, а Trusted Root Authority использовался.

После того как мы провели проверку, мы же сами и принимаем решение использовать ли пару ключей, ассоциированную с этим сертификатом или нет.
Все зависит от требований.

Спасибо за внимание, комментарии приветствуются.

пятница, 13 августа 2010 г.

Безопасность в Active Directory. Часть 2.

Введение.
Сейчас все больше и больше развиваются Интернет-технологии, приложения Интернет-коммерции, многоуровневые и распределенные приложения.
Основной плюс таких приложений - это унифицированный интерфейс. Данный подход не требует установки клиенского приложения - пользователи работают при помощи Web-браузера.
Основная архитектура таких систем представлена на рисунке 1.1.
Рис. 1.1. Архитектура Web-приложений
Клиент, используя обозреватель Интернет, взаимодействует с Web-сервером, Web-сервер в свою очередь запрашивает данные из БД, файловых или других источников.
Примерами таких систем являются порталы Sharepoint, Forefront Identity Manager, собственные разработки на ASP.NET и т.д.

В пределах корпоративной сети, как правило используется делегирование Kerberos, тоесть Web-сервер олицетворяет клиента и использует его права для доступа к данным.

При неправильном конфигурировании Kerberos-делегирования, могут возникнуть серьезные проблемы в плане информационной безопасности.

Рассмотрим несколько возможных сценариев неправильных настроек и их последствия.

Сценарий 1. Назовем его "Классический".
В данной архитектуре у нас присутствует Web-Сервер IIS. Как правило база данных находится на другом компьютере с Microsoft SQL Server. На IIS сервере включена имперсонация, MS SQL Server использует windows-аутентификацию. Web-сервер от лица клиентов обращается за данными на MS SQL Server.
Если MS SQL и IIS находятся на разных серверах, то необходимо включить делегирование для учетной записи под которой работает IIS. И тут, как правило, системные администраторы просто включают неограниченное делегирование.
Злоумышленник может воспользоваться этим (в качестве злоумышленника может выступать и сам Web-программист, поддерживающий или разрабатывающий данный программный продукт).

Перечислим необходимые действия для получения дополнительных полномочий:
1) Включаем имперсонацию в IIS. В файл Web.config добавляем следующие строки.

<authentication mode="Windows"></authentication>
<identity impersonate="true"></identity>

Подробнее:
http://msdn.microsoft.com/en-us/library/134ec8tc(VS.80).aspx

2) Включаем делегирование для учетной записи компьютера (Пул-IIS нашего приложения запускается под учетной записью SYSTEM).
Свойство учетной записи компьютера, вкладка Delegation, галочка Trust this computer for delegation to any service (Kerberos only).

3) Используем следующий код (c#):


//Создание пользователя, добавление пользователя в группу Domain Admins
protected void Button1_Click(object sender, EventArgs e)
{
DirectoryEntry de = new DirectoryEntry("LDAP://CN=Users,DC=CONTOSO,DC=COM");
DirectoryEntry user = de.Children.Add("CN=User01", "user");
user.Properties["sAMAccountName"].Value = new object[] { "User01" };
user.CommitChanges();
user.Invoke("SetPassword", new object[] { "P@ssw0rd" });
user.InvokeSet("AccountDisabled", new object[] { false });
user.CommitChanges();
DirectoryEntry admgroup = new DirectoryEntry("LDAP://CN=Domain Admins,CN=Users,DC=CONTOSO,DC=COM");
admgroup.Invoke("Add", new object[] { user.Path });
}
//-----------------------

4) Администратор открывает страницу корпоративного портала (данный код можно повесить на загрузку страницы), выполняется код, в результате которого создается полномочная учетная запись.

Варианты решения данной проблемы:
1) Отслеживать код приложений. Данный способ крайне неудобен и сложен (можно так упрятать деструктивный код, что никто и не найдет при обзоре).
2) Не использовать делегирование и совмещать роли back-end и front-end серверов. Этот способ препятствует масштабированию.
3) Не использовать полномочные учетные записи для выполнения задач, не требующих таких полномочий. Это основное правило. Действует не только в описываемом случае. Безусловно нужно придерживаться данной рекомендации.
4) Использовать расширение протокола Kerberos - Constrained Delegation (более подробнее обсуждается далее).

Сценарий 2. Повышение полномочий.
Данный сценарий на самом деле также использует одно из расширений протокола Kerberos, появившееся в Windows Server 2003 - Protocol Transition (также можно встретить как Service-for-User-to-Self [S4U2Self]).

Подробнее - http://technet.microsoft.com/en-us/library/cc772815(WS.10).aspx

Вкратце, данное расширение позволяет без знания пароля пользователя получать Kerberos-билет и на его основе формировать маркер безопасности. Данный маркер запросившая служба использует для себя. Есть несколько режимов использования маркера - Identify и Impersonation. Первый используется для получения списка групп и полномочий пользователя (очень удобно с учетом распределенности службы Active Directory), второй можно использовать для олицетворения, локально, в системе.

Для использования режима Identify, особых условий не нужно, достаточно только сервера Windows Server 2003 и такого же уровня домена.
Для использования режима Impersonation необходимо соблюдение условий для Identify, плюс наличие полномочий "Act as part of the operating system" локальной политики безопасности. Данная привилегия по умолчанию есть у NT AUTHORITY\SYSTEM. При желании можно дать данную привилегию другой учетной записи, чего не следует делать (только если это действительно нужно).

Опишу данный сценарий по шагам:
1) У нас есть сервер IIS, на нем крутится приложение ASP.NET. Код приложения:
//отключаем делегирование (оно у меня включено в web.config)
WindowsImpersonationContext ctx = WindowsIdentity.Impersonate(IntPtr.Zero);
//Далее используем Protocol Transition
WindowsIdentity wi = new WindowsIdentity("gefimov@contoso.com");
ctx = null;
try
{
ctx = wi.Impersonate();
Response.Write("User:" + wi.User.Value);
File.Create("c:\\gefimov1\\myfile01.txt"); // Здесь полезная нагрузка, у меня просто создание файла в папке (папка находится в эксклюзивном владении - для чистоты эксперимента).
ctx.Undo();
}
catch (Exception err)
{
Response.Write("Error: " + err.Message + "");
}
//-----------------------------

Я не стал здесь правильно обрабатывать ошибки, инициализацию и освобождение. Кому интересно узнать как это правильно делается ("запросам ресурсов путем инициализации")ю необходимо обратиться к книге Бьерна Страуструпа "Язык программирования C++", второе издание, 9 глава.

2) Пул приложения IIS запущен под учетной записью, у которой есть полномочие "Act as part of the operating system".

3) В процессе выполнения кода, поток получает полномочия указанной учетной записи (в нашем случае gefimov@contoso.com), совершенно без пароля (правда какими усилиями:)).

Честно, я не встречал и не могу придумать вариант использования данного сценария (имеется ввиду, такое неправильное конфигурирование полномочий). Может быть кто-то поделится своим опытом.
Данный сценарий скорее всего является вводным для освоения следующего материала.
Тут можно извлечь лишь один урок - не давайте лишних полномочий!

Сценарий 3. Расширения Kerberos.
В данном сценарии рассказывается о получении полномочий с использованием двух расширений Kerberos, появившихся в Windows Server 2003:
1) Protocol Transition - Service-for-User-to-Self (S4U2Self) (обсуждалось выше).
2) Constrained Delegation - Service-for-User-to-Proxy (S4U2Proxy).

В общих чертах, используя два этих расширения можно 1) получать билет Kerberos без знания долгосрочного ключа пользователя (проще говоря, пароля) и при этом 2) использовать данный билет для доступа к другим службам в домене.

У данного способа есть свои ограничения (куда же без них):
1) Служба должна работать на сервере с Windows Server 2003 или выше.
2) Уровень домена должен быть Windows Server 2003.
3) Необходимо наличие прав "Act as part of operating system" (напомню что по умолчанию, это право есть у LocalSystem).
4) Необходимо настроить Kerberos Constrained Delegation для учетной записи, под которой выполняется служба.
5) Делегирование может осуществлять только в пределах локального для службы домена. Это не беда, получив права доменного админа, можно с легкостью получить права во всем лесу. (Смотрите мою первую статью про безопасность Active Directory http://gexeg.blogspot.com/2009/12/active-directory.html, также существуют другие способы, в будущем возможно опишу).

1 и 2 выполняется достаточно легко (с учетом того, что на дворе 2010 год). Получение прав для 3 случая проблем тоже не вызывает (ERD Commander и различные Live CD вам в помощь). Осталось только упросить системного администратора включить делегирование Kerberos для учетной записи компьютера или служебной учетной записи (4). Ограничение 5 приходится воспринимать как должное, тут уж никуда не денешься.
Может быть вам удастся уговорить системного администратора дать вам права "Enable computer and user accounts to be trusted for delegation" (данное полномочие позволяет владельцу учетной записи настраивать делегирование, как ему вздумается), тогда вы сами сможете настроить нужное вам делегирование.

По шагам опишу весь процесс:
1) У нас есть приложение ASP.NET на IIS (c#):
//----------
WindowsImpersonationContext ctx = WindowsIdentity.Impersonate(IntPtr.Zero);
WindowsIdentity wi = new WindowsIdentity("Administrator@contoso.com");
ctx = wi.Impersonate();
createuser(); //Создание пользователя
ctx.Undo();
//Обработка ошибок

2) Пул приложения запущен под учетной записью SYSTEM ("Act as part of operating system").
3) Для учетной записи компьютера, я настроил constrained delegation, делегируемая служба LDAP/FIM-DC01.
4) Выполняется код, происходит имперсонация и делегирование, наш поток работает с маркером Администратора домена (Administrator@contoso.com).
5) В процессе выполнения приложения, создается учетная запись пользователя и добавляется в группу Domain Admins. Миссия выполнена.

Как же этого избежать? Конечно же нужно очень трепетно относиться к делегированию.
Приведу некоторые правила:
1) Никому не давайте права "Enable computer and user accounts to be trusted for delegation".
2) Запускайте службы под учетными записями с ограниченными полномочиями (актуально для SharePoint, самому иногда было лень разбираться с доступом - запускал под SYSTEM, но конечно же не в корпоративной среде ;))
3) Ограничивайте использование полномочия "Act as part of operating system".
4) Используйте делегирование только тогда, когда это действительно нужно.
4) Используйте Constrained Delegation, при этом не указывайте службы "на всякий случай, а вдруг используется", указывайте только действительно нужные и используемые службы в делегировании.

Напоследок приведу список полезной литературы:
http://msdn.microsoft.com/en-us/library/134ec8tc(VS.80).aspx
http://gexeg.blogspot.com/2009/12/active-directory.html
http://technet.microsoft.com/en-us/library/cc772815(WS.10).aspx
http://msdn.microsoft.com/en-us/library/ff647404.aspx#paght000023_impersonatingbyusingwindowsidentity

Во вложении файл с проектом Visual Studio 2008:

MD5: DA8E5373CB6775E4F8B0C6090D67D4B7

понедельник, 28 декабря 2009 г.

Безопасность в 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

Но выполнение данной функции налагает определенные ограничения, в частности должны быть выполнены следующие условия:

1) административные права в домене источнике;
2) права на добавление SidHistory в целевом домене;
3) на PDC в исходном домене в реестре должен быть ключ TCPIPClientSupport:DWORD=1;
4) должна быть создана локальная группа в целевом домене – $$$;
5) в целевом домене должен быть включен аудит управления учетными записями (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.
Собственно все, что нам нужно есть, осталось только прописать необходимые данные.
Пошагово опишу процесс:
1) Изменяем глобальные данные нашего будущего экземпляра ESE. Поскольку по умолчанию размер страницы в ESE – 4КБ, а AD использует 8КБ страницы, нужно поменять глобальные настройки.
2) Создаем экземпляр.
3) Инициализируем.
4) Создаем сессию.
5) Аттачим базу, затем ее открываем.
6) Открываем таблицу datatable.
7) Устанавливаем текущий индекс INDEX_00090002 (это отдельный индекс для атрибута ATTk589826).
8) Создаем ключ для поиска, указываем в качестве критерия поиска GUID искомого объекта.
9) Осуществляем поиск.
10) В транзакции обновляем столбец ATTr590433, записывая в него необходимые SID’ы.
11) Закрываем БД, сессию, завершаем экземпляр 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

P.S.: жду коментариев, замечаний :)