Какое TargetName использовать при вызове InitializeSecurityContext (Negotiate)?

Вопрос

При звонкеInitializeSecurityContextкакое значение я передаюTargetName параметр?

Пересмотренный Фон

Я вызываю функциюInitializeSecurityContext:

InitializeSecurityContextA(
      @pAS.hcred,           //[in] credentials
      phContext,            //[in] optional] Context handle structure
      pszTargetName,        //[in, optional] Target name
      0,                    //[in] context requirements
      0,                    //[in] reserved1, must be zero
      SECURITY_NATIVE_DREP, //[in] target data representation
      pInput,               //[in] optional] SecBufferDescription
      0,                    //[in] reserved2, must be zero
      @pAS.hctxt,           //[in, out] pointer to context handle structure
      @OutBuffDesc,         //[in, out] pointer to SecBufferDesc
      ContextAttributes,    //[out] context attributes
      @lifetime);           //[out] expiration timestamp

Что я передаюpszTargetName?

я пробовал

null: InitializeSecurityContextA(@pAS.hcred, phContext, null, ...);"": InitializeSecurityContextA(@pAS.hcred, phContext, "", ...);"spn/HOSTNAME": InitializeSecurityContextA(@pAS.hcred, phContext, "spn/HOSTNAME", ...);spn/HOSTNAME.DOMAIN.COM: InitializeSecurityContextA(@pAS.hcred, phContext, "spn/HOSTNAME.DOMAIN.COM", ...);"cargocult/PROGRAMMING": InitializeSecurityContextA(@pAS.hcred, phContext, "cargocult/PROGRAMMING", ...);"http/TFS.DOMAIN.COM": InitializeSecurityContextA(@pAS.hcred, phContext, "http/TFS.DOMAIN.COM", ...);"http/HOSTNAME": InitializeSecurityContextA(@pAS.hcred, phContext, "http/HOSTNAME", ...);

"qwertyasdf": InitializeSecurityContextA(@pAS.hcred, phContext, "qwertyasdf", ...);

"AuthSamp": InitializeSecurityContextA(@pAS.hcred, phContext, "AuthSamp", ...);

Все они либо терпят неудачу, либо переходят на NTLM.

Запись: Моя машина подключена к домену, но доменне названныйdomain.com, или дажеhostname.domain.com, или дажеqwertyasdf, Поэтому я не удивлен, что эти попытки провалились. Но люди говорят, что попробуйте такие вещи, какhttp/HOSTNAMEтак что я положил вhttp/HOSTNAME.

Фон

InitializeSecurityContext (Согласование) функция имеетпо желанию TargetName параметр:

pszTargetName [необязательно]

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

Что это должно быть?

Больше фона

я пытаюсь проверить набор учетных данных пользователя, например:

Boolean ValidateCredentials(String username, String password, String domain)
{
   ...
}

Проверка набора учетных данных пользователя требует использования SSPI API. Первая функция для вызоваInitializeSecurityContext, Один из параметров дляInitializeSecurityContext это«Имя_целевого_объект» строка.

я пытался оставить этозначение NULL, ноПроверка приложения запускает точку останова, выдает ошибку:

ОСТАНОВКА ПРОВЕРКИ 00005003: pid 0xF08:
InitializeSecurityContext использует целевую NULL или неверно сформированную цель для службы Kerberos.
Пожалуйста, смотрите pszTargetName для значения цели.
00000000: не используется.
00000000: нет

На этом этапе было бы полезно помнить, чтоNegotiate провайдер попытается использоватьKerberos, но отступитьNTLM, На случай, еслиNegotiate, Kerberos или жеNTLM,TargetName параметрзадокументировано:

Имя участника службы (SPN) иликонтекст безопасности сервера назначения.

Но тогда что я должен пройти?

я попытался сделать то, что делает статья базы знаний SSPI, ничего (т.е.NULL):

Как проверить учетные данные пользователя в операционных системах Microsoft
ss = _InitializeSecurityContext(
        &pAS->hcred,
        pAS->fInitialized ? &pAS->hctxt : NULL, 
        NULL,        //<-------pszTargetName
        0, 
        0,
        SECURITY_NATIVE_DREP, 
        pAS->fInitialized ? &sbdIn : NULL,
        0, 
        &pAS->hctxt, 
        &sbdOut, 
        &fContextAttr, 
        &tsExpiry);

Но ничего (т.е.NULL) не работает.

Примечание: Статья КБ была массово переписана в 2007 году. В своем первоначальном воплощении 1999 года они прошли"AuthSamp" как цель, но это также не удается.

Бонус Болтовня:

имя участника службы
(SPN) Имя, по которому клиент однозначно идентифицирует экземпляр службы. Если вы устанавливаете несколько экземпляров службы на компьютерах по всему лесу, у каждого экземпляра должен быть свой собственный SPN. У данного экземпляра службы может быть несколько имен участников-служб, если есть несколько имен, которые клиенты могут использовать для проверки подлинности.

контекст безопасности
Атрибуты безопасности или правила, которые в настоящее время действуют. Например, текущий пользователь вошел в систему на компьютере или персональный идентификационный номер, введенный пользователем смарт-карты. Для SSPI контекст безопасности - это непрозрачная структура данных, которая содержит данные безопасности, относящиеся к соединению, такие как ключ сеанса или указание продолжительности сеанса.

Бонус Болтовня 2

Из документации верификатора приложения:

Подключаемый модуль Verifier обнаруживает следующие ошибки:

Пакет NTLM указывается непосредственно в вызове AcquireCredentialsHandle (или API-оболочки более высокого уровня).

Имя цели в вызове InitializeSecurityContext имеет значение NULL.

Целевое имя в вызове InitializeSecurityContext не является правильно сформированным именем домена в стиле SPN, UPN или NetBIOS.

Последние два случая заставят Negotiate перейти к NTLM либо напрямую (первый случай), либо косвенно (контроллер домена вернет ошибку «принципал не найден» во втором случае, что приведет к откату Negotiate).

Плагин также регистрирует предупреждения при обнаружении перехода на NTLM; например, когда SPN не найден контроллером домена. Они регистрируются только как предупреждения, поскольку они часто являются допустимыми случаями - например, при аутентификации в системе, которая не присоединена к домену.

В моем случае домен, который я проверяю, являетсяnull (так как я не знаю доменное имя машины, или даже если тамявляется домен). Но результаты будут такими же, если жестко закодировать доменное имя моей машины для разработки.

Обновление 3

ЗначенияpszTargetName что вызывает ошибку AppVerifier, но вход в системупреуспевает:

null"""AuthSamp""qwertyasdf"* имя домена, с которым я проверяю (например,"avatopia.com")* имя домена, к которому присоединен компьютер (например,"avatopia.com")* имя домена, в котором находится учетная запись пользователя (например,"avatopia.com")

ЗначенияpszTargetName которые не вызывают ошибку AppVerifier, но входят в системутерпит неудачу:

"http/HOSTNAME""http/TFS.DOMAIN.COM""frob/GROBBER""cargocult/PROGRAMMING""spn/HOSTNAME""spn/HOSTNAME.DOMAIN.COM"

ЗначенияpszTargetname которые не вызывают ошибку AppVerifier,а также вход в систему успешен:

никто

Обновление 4

Что я пытаюсь сделать: выяснить, если имя пользователя / пароль действительны.

у меня есть имя пользователя: например"ian"у меня есть пароль: например"pass1"

Теперь есть еще одна складка, что аккаунтian может бытьместный аккаунт илидомен учетная запись. И вам нужно решить, еслиian является локальной или доменной учетной записью, прежде чем вы можете спросить. Это потому чтоian может иметьдва учетные записи:

ian на доменеstackoverflow.comian на локальной машине

Поэтому мне нужно указать, если я хочу:

задать конкретный домен (например,stackoverflow.com), или жеспросите локальную машину (которую япредставлять как".")

Теперь мы можем придумать перекрестную ссылку:

Username  Password  Domain             Machine on domain?  Validate as
========  ========  =================  ==================  ==============
iboyd     pass1     .                  No                  Local account
iboyd     pass1     (empty)            No                  Local account
iboyd     pass1     stackoverflow.com  No                  Domain account

iboyd     pass1     .                  Yes                 Local account
iboyd     pass1     (empty)            Yes                 Domain account
iboyd     pass1     stackoverflow.com  Yes                 Domain account

Обновление 5

Это может помочь объяснить, что я пытаюсь сделать, тогда, возможно,как сделать это станет легче. Допустим, я захожу в случайное офисное здание в центре города, захожу в случайную кабину и набираю случайное имя пользователя и пароль:

я собираюсь попробовать войти в доменTURBOENCABULATOR, я указал, что я хочу попробовать аутентифицироваться противTURBOENCABULATOR домен с префиксом моего имени пользователя как:

TURBOENCABULATOR\ian

Примечание: я очень сомневаюсь, что в сети есть домен под названиемturboencabulator, так как само название приходит толькоот автоматизации Rockwell, Попытка войти будет почтиконечно провал. Но как Windows проверяет их?

КакWindows пытаться проверить эти учетные данные? КакWindows проверить учетные данные:

имя пользователяЯнпароль: pass1Домен: TURBOENCABULATOR

Есть лиWindows использоватьИнтерфейс пакета поддержки безопасности? Если предположить, Windows используетвести переговоры или жеKerberos для аутентификации, что делаетWindows передать какpszTarget параметр? Почти наверняка введенные мной учетные данные не будут действительными. Как будетWindows определить, действительны ли они? Какой API будетWindows позвонить, чтобы подтвердить полномочия?

Windows может проверить учетные данные.I хочу также проверить учетные данные.

Возможно, вместо того, чтобы пытаться подключиться кTURBOENCABULATOR домен, я пытаюсь подключиться кturboencabulator.com домен, добавив домен к моему имени пользователя какturboencabulator.com\ian:

Тот же вопрос применим. КакWindows проверить учетные данные? Я хочу сделать то, что делает Windows. Предполагая, что Windows использует Kerberos для авторизации, что Windows передает какpszTargetName параметр в SSPI?

Возможно, вместо того, чтобы пытаться подключиться кturboencabulator.com домен, я пытаюсь подключиться кturboencabulator.net домен:

Обратите внимание, что в этом примере яприлагается доменное имя для моего имени пользователя, а непредваряя Это.

Возможно, вместо того, чтобы пытаться подключиться кturboencabulator.net домен, я пытаюсь проверить пользователя как локальную (машинную) учетную запись, поставив перед моим именем пользователя.\ как:

Как Windows проверяет имя пользователя и пароль в локальной базе данных учетных записей? Использует ли он SSPI свести переговоры пакет? Если да, то какое значение он передает какpszTargetName?

Люди говорят о веб-серверах, http, Team Foundation Server. Я действительно не знаю, откуда они это получают. Или они говорят о редактировании пользователя в активной директории, чтобы убедиться, что что-то присутствует - я не понимаю, почему мне нужно что-то редактировать:Windows ничего не редактирует

какаяTargetName я использовал при звонкеInitializeSecurityContext для проверки набора учетных данных?

Бонус Болтовня

Вот глава из документации Application Verifier о том, почему у них есть тест, если кто-то по ошибке использует NTLM:

Почему нужен плагин NTLM

NTLM - это устаревший протокол аутентификации с недостатками, которые могут поставить под угрозу безопасность приложений и операционной системы. Наиболее важным недостатком является отсутствие проверки подлинности сервера, что может позволить злоумышленнику обманом заставить пользователей подключиться к поддельному серверу. Как следствие отсутствия аутентификации на сервере, приложения, использующие NTLM, также могут быть уязвимы к типу атаки, известной как атака «отражения». Последнее позволяет злоумышленнику перехватить сеанс аутентификации пользователя на легитимном сервере и использовать его для аутентификации злоумышленника на компьютере пользователя. Уязвимости NTLM и способы их использования являются целью увеличения исследовательской активности в сообществе безопасности.

Хотя Kerberos был доступен в течение многих лет, многие приложения все еще написаны для использования только NTLM. Это излишне снижает безопасность приложений. Однако Kerberos не может заменить NTLM во всех сценариях - главным образом в тех, где клиент должен пройти аутентификацию в системах, которые не присоединены к домену (домашняя сеть, возможно, является наиболее распространенной из них). Пакет безопасности Negotiate обеспечивает обратно-совместимый компромисс, который использует Kerberos всякий раз, когда это возможно, и возвращается к NTLM только тогда, когда нет другой возможности. Переключение кода для использования Negotiate вместо NTLM значительно повысит безопасность для наших клиентов, в то же время практически не применяя совместимость приложений. Переговоры сами по себе не являются «серебряной пулей» - бывают случаи, когда злоумышленник может принудительно перейти на NTLM, но их значительно труднее использовать. Однако одно немедленное улучшение заключается в том, что приложения, написанные для правильного использования Negotiate, автоматически защищены от атак отражения NTLM.

В качестве последнего слова предостережения против использования NTLM:в будущих версиях Windows будет возможно отключить использование NTLM в операционной системе. Если приложения имеют жесткую зависимость от NTLM, они просто не смогут аутентифицироваться, когда NTLM отключен.

Как работает плагин

Подключаемый модуль Verifier обнаруживает следующие ошибки:

Пакет NTLM указывается непосредственно в вызове AcquireCredentialsHandle (или API-оболочки более высокого уровня).

Имя цели в вызове InitializeSecurityContext имеет значение NULL.

Целевое имя в вызове InitializeSecurityContext не является правильно сформированным именем домена в стиле SPN, UPN или NetBIOS.

Последние два случая заставят Negotiate вернуться к NTLM либо напрямую (первый случай), либо косвенно (контроллер домена вернет ошибку «принципал не найден» во втором случае, что приведет к откату Negotiate).

Плагин также регистрирует предупреждения при обнаружении перехода на NTLM; например, когда SPN не найден контроллером домена. Они регистрируются только как предупреждения, поскольку они часто являются допустимыми случаями - например, при аутентификации в системе, которая не присоединена к домену.

NTLM останавливается

5000 - Приложение явно выбрало пакет NTLM

Серьезность - Ошибка

Приложение или подсистема явно выбирают NTLM вместо Negotiate при вызове AcquireCredentialsHandle. Даже если клиент и сервер могут пройти аутентификацию с использованием Kerberos, это предотвращается явным выбором NTLM.

Как исправить эту ошибку

Исправление этой ошибки - выбрать пакет переговоров вместо NTLM. Как это сделать, будет зависеть от конкретной сетевой подсистемы, используемой клиентом или сервером. Некоторые примеры приведены ниже. Вам следует обратиться к документации по конкретной библиотеке или набору API, который вы используете.

APIs(parameter) Used by Application    Incorrect Value  Correct Value  
=====================================  ===============  ========================
AcquireCredentialsHandle (pszPackage)  “NTLM”           NEGOSSP_NAME “Negotiate”
Смотрите такжеПараметр InitializeSecurityContext pszTargetName

Ответы на вопрос(4)

Ваш ответ на вопрос