warning
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону.
В этом году появилось несколько новых способов из такого разряда. Наиболее интересные — WTSImpersonator и GIUDA. Последний позволяет получать тикеты залогиненного пользователя, даже не зная его пароля! Давай разберемся, как это работает, а параллельно напишем реализацию на C++, которую я назвал TGSThief.
Logon Session
При входе пользователя в Windows появляется сессия пользователя, которая хранит все данные о нем. Для каждого нового пользователя создается новая сессия. Например, если на компьютере одновременно работают два пользователя, то будет две сессии.
Каждая сессия определяется с помощью LUID (locally unique identifier). Из названия понятно, что LUID уникален для каждой сессии. Информация хранится в виде одноименной структуры.
typedef struct _LUID { ULONG LowPart; LONG HighPart;} LUID, *PLUID;
Сам LUID представлен в виде двух значений: ULONG и LONG. Причем обычно заполняется лишь поле LowPart
, а HighPart
имеет значение 0.
Эта структура используется во всех функциях WinAPI, которые так или иначе связаны с сессиями пользователя.
С помощью GetTokenInformation() можно получить LUID пользователя. Для этого функции следует передать токен процесса, запущенного от имени текущего пользователя.
#include <windows.h>#include <iostream>#include <sddl.h>int main() { HANDLE tokenHandle; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle)) { std::cerr << "Ошибка OpenProcessToken: " << GetLastError() << std::endl; return 1; } DWORD tokenInformationLength = 0; GetTokenInformation(tokenHandle, TokenStatistics, nullptr, 0, &tokenInformationLength); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { std::cerr << "GetTokenInformation неудачный первый вызов: " << GetLastError() << std::endl; CloseHandle(tokenHandle); return 1; } TOKEN_STATISTICS* tokenStats = reinterpret_cast<TOKEN_STATISTICS*>(new BYTE[tokenInformationLength]); if (tokenStats == nullptr) { std::cerr << "Ошибка выделения памяти для TOKEN_STATISTICS" << std::endl; CloseHandle(tokenHandle); return 1; } if (!GetTokenInformation(tokenHandle, TokenStatistics, tokenStats, tokenInformationLength, &tokenInformationLength)) { std::cerr << "Ошибка GetTokenInformation: " << GetLastError() << std::endl; delete[] tokenStats; CloseHandle(tokenHandle); return 1; } std::cout << "LUID: " << std::hex << "0x" << std::uppercase << tokenStats->AuthenticationId.LowPart << tokenStats->AuthenticationId.HighPart << std::endl; delete[] tokenStats; CloseHandle(tokenHandle); return 0;}
Информация о LUID пользователя упадет в поле AuthenticationId
структуры TOKEN_STATISTICS
.
typedef struct _TOKEN_STATISTICS { LUID TokenId; LUID AuthenticationId; LARGE_INTEGER ExpirationTime; TOKEN_TYPE TokenType; SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; DWORD DynamicCharged; DWORD DynamicAvailable; DWORD GroupCount; DWORD PrivilegeCount; LUID ModifiedId;} TOKEN_STATISTICS, *PTOKEN_STATISTICS;
Именно на манипуляциях с LUID основана логика инструмента GIUDA. Фактически идет подмена LUID, что открывает возможность запросить билет от лица пользователя, чья сессия просто присутствует на устройстве. Свой LUID мы получать научились, а как получать LUID других пользователей?
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»