Windows позволяет разработчикам создавать шифрованные каналы связи, подписывать сообщения между клиентом и службой, аутентифицировать клиента на службе. Злоупотребляя этими возможностями, мы можем извлекать учетные данные пользователя без взаимодействия с LSASS. В этой статье я продемонстрирую, как это работает.
Security Support Provider Interface (SSPI) — это механизм, предоставляющий огромный набор функций для разработчиков. Среди его преимуществ:
SSP, если ты не читал мою прошлую статью, — это набор DLL-файлов, который позволяет использовать протоколы безопасности (NTLMSSP, Kerberos и иные) в клиент‑серверных процессах. Если сильно обобщить, то SSPI — это API для вызова загруженных в систему SSP.
SSPI создает так называемые security blobs. По‑русски — «элементы безопасности» или «компоненты безопасности», но официального перевода мне не попадалось, так что остановимся на «блобах». Этими самыми блобами клиент и сервер обмениваются по удобному для них протоколу.
Чтобы подготовить начальные блобы, клиент получает хендл, указывающий на его реквизиты. Под реквизитами понимается хендл на учетные данные клиента, с помощью которых он может, например, пройти аутентификацию на службе. Получить реквизиты можно с помощью AcquireCredentialsHandle().
Путем обмена блобами выстраивается контекст. Контекст — специальный объект, который хранится и на клиенте, и на сервере. Контекст — результат успешной аутентификации клиента на сервере и в некоторых случаях — сервера на клиенте. С помощью выстроенного контекста можно использовать весь потенциал SSPI. Например, можно построить контекст, получить хендл, а затем шифровать передаваемые между клиентом и сервером сообщения. Причем сервер сможет расшифровать сообщения, так как у него есть контекст, сгенерированный вместе с клиентом, на котором данные шифруются.
Итак, для построения контекста используются специальные функции AcceptSecurityContext() и InitializeSecurityContext(). Контекст выстраивается не сразу. Если требуется еще пару раз обменяться блобами с сервером или клиентом, то возвращается ошибка SEC_I_CONTINUE_NEEDED.
Думаю, звучит страшно. Давай визуализируем. Построение контекста на стороне клиента выглядит следующим образом.
SSPI на клиенте
Клиент сначала получает хендл на свои реквизиты с помощью функции AcquireCredentialsHandle(), затем начинает выстраивать контекст, используя блобы. Как только функция InitializeSecurityContext() перестала возвращать SEC_I_CONTINUE_NEEDED, можно считать, что контекст выстроен, и пользоваться всеми функциями SSPI.
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
9990 рублей 4000 р.
[TD]
920 р.
[/TD]
Я уже участник «Xakep.ru»
Security Support Provider Interface (SSPI) — это механизм, предоставляющий огромный набор функций для разработчиков. Среди его преимуществ:
- независимость от транспорта (данные передавать можно любым образом);
- общий для всех SSP интерфейс;
- аутентификация (в том числе с заимствованием прав);
- конфиденциальность сообщений (шифрование);
- сохранность сообщений (цифровая подпись).
SSP, если ты не читал мою прошлую статью, — это набор DLL-файлов, который позволяет использовать протоколы безопасности (NTLMSSP, Kerberos и иные) в клиент‑серверных процессах. Если сильно обобщить, то SSPI — это API для вызова загруженных в систему SSP.
Реквизиты, контекст и блобы
SSPI создает так называемые security blobs. По‑русски — «элементы безопасности» или «компоненты безопасности», но официального перевода мне не попадалось, так что остановимся на «блобах». Этими самыми блобами клиент и сервер обмениваются по удобному для них протоколу.
Чтобы подготовить начальные блобы, клиент получает хендл, указывающий на его реквизиты. Под реквизитами понимается хендл на учетные данные клиента, с помощью которых он может, например, пройти аутентификацию на службе. Получить реквизиты можно с помощью AcquireCredentialsHandle().
Путем обмена блобами выстраивается контекст. Контекст — специальный объект, который хранится и на клиенте, и на сервере. Контекст — результат успешной аутентификации клиента на сервере и в некоторых случаях — сервера на клиенте. С помощью выстроенного контекста можно использовать весь потенциал SSPI. Например, можно построить контекст, получить хендл, а затем шифровать передаваемые между клиентом и сервером сообщения. Причем сервер сможет расшифровать сообщения, так как у него есть контекст, сгенерированный вместе с клиентом, на котором данные шифруются.
Итак, для построения контекста используются специальные функции AcceptSecurityContext() и InitializeSecurityContext(). Контекст выстраивается не сразу. Если требуется еще пару раз обменяться блобами с сервером или клиентом, то возвращается ошибка SEC_I_CONTINUE_NEEDED.
Думаю, звучит страшно. Давай визуализируем. Построение контекста на стороне клиента выглядит следующим образом.
SSPI на клиенте
Клиент сначала получает хендл на свои реквизиты с помощью функции AcquireCredentialsHandle(), затем начинает выстраивать контекст, используя блобы. Как только функция InitializeSecurityContext() перестала возвращать SEC_I_CONTINUE_NEEDED, можно считать, что контекст выстроен, и пользоваться всеми функциями SSPI.
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Присоединяйся к сообществу «Xakep.ru»!
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
-60% |
1 год
9990 рублей 4000 р.
[TD]
1 месяц
920 р.
[/TD]
Я уже участник «Xakep.ru»