Какое 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) не работает.

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

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

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

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

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

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

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

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

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

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

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

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

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

Обновление 3

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

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

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

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

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

никто

Обновление 4

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

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

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

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

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

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

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

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

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

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

TURBOENCABULATOR\ian

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Вот глава из документации 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