Active Directory - Тайна UnicodePwd в AD LDS

В службе Active Directory Lightweight Directory Services используется сложная процедура преобразования и аутентификации паролей.

Фрэнк Ц. Реттиг

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

Открытие доступа к контроллеру домена из Интернет, как правило настоятельно не рекомендуется, независимо от того, как открывается доступ, – непосредственно из производственной среды или через сеть периметра. Естественная альтернатива – разместить сервер под управлением Windows Server 2008 с ролью Active Directory Lightweight Directory Services (AD LDS) в сети периметра.

Ранее службы AD LDS назывались Active Directory Application Mode (ADAM). Это было первое дополнение к Windows 2003, включенное в состав Windows 2003 R2, а теперь оно доступно как роль сервера Windows 2008 или Windows 7. Во многих отношениях эти службы очень похожи на Active Directory (AD). Как некоторые говорят, это упрощенная версия, в которой отсутствует полнофункциональная поддержка предприятия. Реализация AD LDS выглядит практически одинаково в любой версии Windows, но лучше всего это делать в Windows Server 2008 R2, потому что в этой ОС есть Windows PowerShell v2. В этой новой версии Windows PowerShell присутствуют расширенные возможности по управлению атрибутами AD и AD LDS, которых просто не было в других версиях OS.

Легкость необыкновенная

И в AD, и в AD LDS есть атрибут unicodePwd. В AD он хранится в разделе каталога, а в AD LDS – в разделе приложений. Его наличие предполагает, что роль сервера была повышена до контроллера домена AD или был применен надлежащий LDIF шаблон с атрибутом для сервера AD LDS.

Для запроса каталога AD или AD LDS приложения используют протокол LDAP (Lightweight Directory Access Protocol) версии 3.0. При этом приложение (это может быть LDP.EXE, CSVDE.EXE, LDIFDE.EXE, ADSIEdit.exe или любое другое самостоятельно разработанное приложение) должно предоставить учетную запись и пароль. Все кажется достаточно простым, так в чем же проблема? Предоставить пароль просто, а вот получить пароль, хранимый в атрибуте unicodePwd, та еще задачка. И вот почему: в большинстве интерактивных каталогов или приложений предлагается ввести пароль в исходной форме. Так, если пароль – «car», то именно его мы и введем. Так происходит при доступе к лесу или домену в AD или при доступе к экземпляру AD LDS средствами ADSIedit или LDP для назначения или сброса пароля определенной учетной записи.

Когда требуется выполнить массовое создание или замену, используют инструмент LDIFDE.EXE. При добавлении или изменении атрибута unicodePwd требуется, чтобы значение атрибута было в формате unicode-base64.

Логика Unicode-Base64

Так как высчитывается значение unicode-base64? Здесь начинается все самое интересное. Надеемся, мы раскроем тайну unicodePwd (и других атрибутов, связанных с ним) раз и навсегда.

Прежде всего объявляется следующее. Обратитесь к шагам 1–12 (рис. 1). Корпорация Майкрософт требует, чтобы пароль был заключен в двойные кавычки, а затем каждый символ (включая кавычки) был сконвертирован в эквивалент в Юникоде. Это значит, что сначала необходимо найти эквивалент ASCII для каждого символа, а затем создать шестанадцатиричное значение от каждого значения ASCII, затем добавить к каждому шестнадцатиричному значению два нуля (поскольку Windows работает с UTF16), чтобы были представлены 16 битов.

После преобразования эти наборы шестнадцатиричных значений превращаются в одну длинную строку. Поскольку base64 основан на 6 битах, строка передается каждый 6 значений слева. Если остается неполный набор, справа к нему добавляются нули, до тех пор, пока в нем не будет шести символов. Затем каждый набор преобразуется в двоичный формат. С двоичными наборами анализ выполняется справа, каждые шесть символов.

Хоть это и необязательно, для каждого неполного двоичного набора слева добавляются нули, пока в наборе не будет шести символов (помните, что нули в начале – это все равно нули, однако это упрощает чтение, поскольку в других наборах тоже по шесть символов). Теперь каждое двоичное значение конвертируется в цифровой эквивалент 11. Это число используется в качестве индекса для поиска в таблице base64 (рис. 2) и получения ее символа. Если полный шестисимвольный набор состоит только из добавленных нулей, он представлен знаком равенства.

На рис. 1 видно, как за 12 шагов слово car преобразовано в IgBjAGEAcgAiAA==.  Добавление нулей справа требуется при подготовке Юникода для base64, как видно из текста, выделенного синим. Что касается добавления нулей слева, представленного текстом, который выделен красным, это сделано из соображений однородности и простоты в чтении относительно других двоичных наборов из шести символов.

Figure 1 Steps to create a unicode-base64 password

Рис. 1 Шаги по созданию пароля unicode-base64.

Figure 2 Base64 Mapping

Рис. 2 Сопоставление Base64.

Если вы раздумываете о том, верна ли эта странная логика, загрузите файл Stringconverter.exe с веб-сайта gbordier.com/gbtools/stringconverter.htm и запустите следующую строку в командной строке DOS:

stringconverter \"car\" /encode /unicode
IgBjAGEAcgAiAA==

Как видите, результат тот же.

Создание пароля Unicode-Base64

Для начальной простой проверки использование следующих функций Excel (рис.1 был создан в Excel) позволит быстро создать правильное отображение в кодировке Unicode-Base64 любого введенного текста:

  • CODE() – возвращает числовой код символа;
  • DEC2HEX() – преобразует десятичное число в шестнадцатеричное;
  • Concatenate() – объединяет несколько строк в одну;
  • BIN2DEC() – преобразует двоичное число в десятичное;
  • MID() – возвращает заданный символ из строки.

Большое число значений unicodePwd лучше всего создавать, написав сценарий. Выполнение этого в Excel средствами VBA позволяет увидеть все сгенерированные значения и сохранить их в электронной таблице для использования в будущем. Используя другой сценарий на VBA, я смог моментально сгенерировать LDIF-файл для импорта в экземпляр AD LDS.

Передача значения UnicodePwd в кодировке Unicode-Base64

Поскольку работа с unicodePwd ведется средствами программы LDIFDE.exe, передаваемое значение unicodePwd должно соответствовать формату LDIF-файла. Так как я задействовал роль AD LDS операционной системы Windows Server 2008 R2, использовался приведенный ниже формат LDIF-файла – я загрузил только базовую информацию. Обратите внимание, что учетная запись пользователя John Doe – первая, у которой пароль car передан как значение IgBjAGEAcgAiAA== атрибута unicodePwd.

 

dn: CN=JohnDoe,OU=Accounts,DC=CONTOSO,DC=COM
Changetype: add
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: John Doe
givenName: John
sn: Doe
userPrincipalName: johnd@Contoso.COM
mail: johnd@Contoso.COM
unicodePwd::IgBjAGEAcgAiAA==\
msDS-UserAccountDisabled: FALSE

dn: CN=Jess  Wanders,OU=Accounts,DC=CONTOSO,DC=COM
Changetype: add
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: Jess Wanders
givenName: Jess
sn: Wanders
userPrincipalName: JessW@Contoso.COM
mail: JessW@Contoso.COM
unicodePwd::IgA3ACQANQBNAHMAIwA0AEQAaQBHACIA
msDS-UserAccountDisabled: FALSE

Чтобы импортировать этот файл (допустим, что его имя – Accounts.ldf), выполните следующую команду в командной строке Windows Server 2008 R2:

C:\Windows\system32\LDIFDE –i –f Accounts.ldf.

Привязка и проверка пароля учетной записи

После загрузки одной или нескольких вновь созданных учетных записей в раздел каталога и подключения или привязки к службе LDAP с userPrincipalName и unicodePwd учетной записи очень важно убедиться в правильности формата unicode-base64 атрибута unicodePwd. Для выполнения этой задачи наиболее удачный и удобный в использовании инструмент – LDP.exe. Можно было бы подумать, что при его использовании надо вводить IgBjAGEAcgAiAA==, но это не так. Правильный пароль тот, с которого мы начали: car.

Подключившись к AD LDS средствами LDP, создайте привязку, используя UPN загруженной учетной записи и введите пароль. Если вы правильно следовали за логикой разъяснений, как создавать значение unicodePwd в формате unicode-base64, вы увидите в окне LDP подтверждение об успешной привязке к экземпляру AD LDS.

Использование Windows PowerShell для изменения атрибута UnicodePwd

Было бы несправедливо, если б я сказал, что LDIFDE.exe – единственный имеющийся инструмент, способный выполнять массовые изменения атрибута unicodePwd. Конечно, тогда бы вы не узнали, как генерировать значение unicode-base64.

В Windows Server 2008 R2 в Windows PowerShell v2 появилось чуть больше возможностей выборочного управления атрибутами AD и AD LDS. Работая с AD LDS, я придумал синтаксис, показанный на рис. 3 (обратите внимание, что ради удобочитаемости я поместил каждый параметр команды в отдельной строке), для выполнения той же задачи, что и сценарий на VBA в электронной таблице Excel.

Ясно, что всего лишь несколькими строками кода Windows PowerShell можно быстро выполнить необходимые изменения, не проходя через все мучения с преобразованием в формат unicode-base64 каждого пароля. Это свидетельство мощи Windows PowerShell, но она достигается за счет дополнительного расходования ресурсов, особенно если учесть все то, что оболочка делает в фоновом режиме. Это особенно очевидно про обработке сотен или тысяч учетных записей.

Так что, если иногда надо создать или изменить несколько учетных записей, используйте Windows PowerShell. Если вам часто приходится создавать или обновлять сотни или тысячи учетных записей, LDIFDE.exe выполнит эту задачу намного быстрее.

Рис. 3  Сценарий Windows PowerShell v2 для обновления пароля учетной записи.

Import-Csv c:\scripts\accounts.csv | 
New-ADUser
–Name $_.commonName
–GivenName $_.givenName
–Surname $_.sn

-EmailAddress $_.email
-Type user
-UserPrincipalName $_.userPrincipalName
–Server LDS01:389 |
Set-ADAccountPassword
-Identity $_.distinguishedName
-NewPassword (ConvertTo-SecureString -AsPlainText $_.Password -Force)
-Reset

-Server LDS01:389 |

Enable-ADAccount

-Identity $_.distinguishedName

-Server LDS01:389

При работе с AD или AD LDS (или даже ADAM) есть несколько способов изменения атрибута unicodePwd. Если надо изменить лишь одну учетную запись, используйте для этого LDP.exe или ADSIedit. Если иногда приходится менять несколько учетных записей, задействуйте Windows PowerShell v2 и роль AD/AD LDS в Windows Server 2008 R2.

Однако, если вы все еще используете Windows Server 2003 и у вас сотни или тысячи учетных записей, которые нужно регулярно обновлять, выполните заранее подготовительную работу по созданию процедуры генерации значения unicode-base64 атрибута unicodePwd, а затем используйте LDIFDE.exe, чтобы одним разом загрузить все изменения.

Frank Rettig

Фрэнк Реттиг (Frank Rettig)* – консультант работает консультантом в госслужбах США, Вашингтон, округ Колумбия, и обладает 26-летним опытом работы как в Америке,так и за границей. Он специализируется в области интеграции каталогов, управления идентификационной информацией, мобильных решений и государственных вычислительных стандартов. С им можно связаться по адресу frank.rettig@microsoft.com.*

 

Благодарности:

Я хотел поблагодарить таких членов команды Microsoft Information Security ACE Services, как Роджер Граймс (Roger Grimes) (ведущий архитектор безопасности) и Шон Рабурн (Shawn Rabourn) (старший консультант по безопасности), за проверку правильности этой статьи, а также Энтони де Лагарда (Anthony de Lagarde) (старший консультант) из компании USPS Federal Services за рецензирование статьи.