Вопрос
При вызове 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
(Negotiate) имеет необязательный параметр TargetName
:
pszTargetName [in, optional]
Указатель на строку с завершающим нулевым символом, которая указывает имя участника службы (SPN) или контекст безопасности целевого сервера.
Приложения должны предоставлять действительный SPN, чтобы помочь смягчить атаки повтора.
Что это должно быть?
Дополнительные сведения
Я пытаюсь проверить набор учетных данных пользователя, например:
Boolean ValidateCredentials(String username, String password, String domain)
{
...
}
Для проверки набора учетных данных пользователя необходимо использовать API SSPI. Первая функция для вызова - InitializeSecurityContext
. Одним из параметров InitializeSecurityContext
является строка "TargetName".
Я попробовал оставить его null, но Application Verifier запускает точку останова, выписывая ошибку:
ПРОВЕРКА ОСТАНОВКИ 00005003: pid 0xF08:
InitializeSecurityContext использует цель NULL или искаженную цель для службы Kerberos.
Пожалуйста, см. PszTargetName для значения цели.
00000000: Не используется.
00000000: Не
На этом этапе было бы полезно помнить, что поставщик Negotiate
попытается использовать Kerberos
, но отступит к NTLM
. В случае Negotiate
, Kerberos
или NTLM
параметр TargetName
задокументирован как:
Имя участника службы (SPN) или контекст безопасности целевого сервера.
Но тогда что я должен пройти?
Я попытался сделать то, что делает статья базы знаний SSPI, ничего (т.е. pass 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. У данного экземпляра службы может быть несколько 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.com
-
ian
на локальной машине
Поэтому мне нужно указать, хочу ли я:
- запросить определенный домен (например,
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 проверить учетные данные:
- Имя пользователя: ian
- Пароль: pass1
- Домен: TURBOENCABULATOR
Использует ли Windows интерфейс пакета поддержки безопасности? Предполагая, что для проверки подлинности Windows использует Negotiate или Kerberos, что означает Windows как параметр pszTarget
? Почти наверняка учетные данные, которые я вводил, не будут действительны. Как Windows определить, действительны ли они? Какой API будет Windows для проверки подлинности?
Windows может проверять credentails. Я хочу также проверить учетные данные.
Возможно, вместо того, чтобы пытаться подключиться к домену TURBOENCABULATOR
, я пытаюсь подключиться к домену turboencabulator.com
, добавив домен к моему имени пользователя как turboencabulator.com\ian
:
Тот же вопрос. Как Windows проверять учетные данные? Я хочу делать то, что делает Windows. Предполагая, что Windows использует Kerberos для авторизации, что Windows передает в качестве параметра pszTargetName
в SSPI?
Возможно, вместо того, чтобы пытаться подключиться к домену turboencabulator.com
, я пытаюсь подключиться к домену turboencabulator.net
:
Обратите внимание, что в этом примере я добавил доменное имя к своему имени пользователя, а не добавлял его.
Возможно, вместо того, чтобы пытаться подключиться к домену turboencabulator.net
, я пытаюсь проверить пользователя как локальную (машинную) учетную запись, префикс моего имени пользователя .\
как:
Как Windows проверяет имя пользователя и пароль на базе локальной учетной записи? Использует ли он SSPI с пакетом Negotiate? Если да, то какое значение оно передается как pszTargetName
?
Люди говорят о веб-серверах, http, сервере создания команды. я действительно не знаю, откуда они это взяли. Или они говорят об изменении пользователя в активном каталоге, чтобы убедиться, что что-то присутствует - я не понимаю, почему мне нужно что-либо редактировать: Windows ничего не редактирует.
Что TargetName
использовать при вызове InitializeSecurityContext
для проверки набора учетных данных?
Бонус-чат
В этой главе из документации Application Verifier о том, почему у них есть тест, если кто-то ошибочно использует NTLM:
Для чего нужен подключаемый модуль NTLM
NTLM - это устаревший протокол аутентификации с изъянами, которые потенциально могут поставить под угрозу безопасность приложений и система. Самым важным недостатком является отсутствие сервера аутентификация, которая может позволить злоумышленнику обмануть пользователей в подключение к поддельному серверу. В качестве следствия недостающего сервера аутентификации, приложения, использующие NTLM, также могут быть уязвимы для тип атаки, называемый атакой "отражения". Последнее позволяет атакующему, чтобы захватить сеанс аутентификации пользователей законного сервера и использовать его для аутентификации злоумышленника компьютер пользователей. Уязвимости NTLM и способы их использования являются целью увеличения исследовательской деятельности в сфере безопасности сообщества.
Хотя Kerberos уже много лет доступен для многих приложений все еще написаны для использования только NTLM. Это неизбежно уменьшает безопасность приложений. Однако Kerberos не может заменить NTLM во всех сценарии - в основном те, в которых клиент должен аутентифицироваться системы, которые не объединены с доменом (домашняя сеть, возможно, являющаяся наиболее распространенные из них). Пакет безопасности Negotiate позволяет обратный совместимый компромисс, который использует Kerberos по возможности и только возвращается в NTLM, когда нет другого варианта. Код переключения для использования Negotiate вместо NTLM значительно увеличит безопасность для наших клиентов при введении небольшого количества заявок или их отсутствие Совместимость. Переговоры сами по себе не являются серебряной пулей - там являются случаями, когда злоумышленник может принудительно понизить ставку до NTLM, но это значительно труднее эксплуатировать. Однако, сразу улучшение заключается в том, что приложения, написанные для правильного ведения переговоров автоматически невосприимчивы к атакам отражения 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.
Как исправить эту ошибку
Исправление этой ошибки состоит в том, чтобы выбрать пакет Negotiate вместо NTLM. Это будет зависеть от конкретной подсистемы сети, используемой клиентом или сервером. Ниже приведены некоторые примеры. Вы должны проконсультироваться с документацией по конкретной библиотеке или набору API, которые вы используете.
APIs(parameter) Used by Application Incorrect Value Correct Value ===================================== =============== ======================== AcquireCredentialsHandle (pszPackage) "NTLM" NEGOSSP_NAME "Negotiate"