Категория > Новости > Свин API. Изучаем возможности WinAPI для пентестера - «Новости»
Свин API. Изучаем возможности WinAPI для пентестера - «Новости»18-03-2023, 17:07. Автор: Павел |
документации Microsoft. Такие идентификаторы называются хорошо известными (well known). Токен же хранит внутри себя множество различных SID, среди которых можно выделить основные:
Читайте также - Для того, чтобы поднять настроение и зарядиться положительной энергией на целый день рекомендуется смотреть красивые картинки, поделки и многое другое. Фон море пляж посмотреть. Достаточно сложно, правда ведь? Но можно провести простую аналогию. Токен — карточка сотрудника компании. SID пользователя — имя на этой карточке, SID группы — напечатанная должность. Система смотрит на эту карточку каждый раз, когда мы начинаем с ней взаимодействовать. Токен и процессВ Windows есть процессы, а есть потоки. Говоря простыми словами, это некие объекты, обладающие собственным виртуальным адресным пространством. Потоком называют ход выполнения программы. Поток выполняется в рамках владеющего им процесса, или, как говорят, в контексте процесса. Любое запущенное приложение представляет собой процесс, в контексте которого выполняется по крайней мере один поток. У процесса есть токен. Чаще всего используется токен пользователя, запустившего процесс. Когда процесс порождает другие процессы, все они используют этот же токен. Дочерние процессы имеют тот же токен Если нам требуется выполнить одну задачу с токеном одного пользователя, а другую с токеном другого пользователя, запускать новый процесс как‑то не очень удобно. Поэтому токен можно применить и к определенному потоку процесса. Приступаем к работеПолучаем токенСуществует несколько функций для получения токена. Для работы с процессами и потоками можно использовать следующие варианты. Вариант 1: получить токен определенного процесса. BOOL OpenProcessToken( [in] HANDLE ProcessHandle, [in] DWORD DesiredAccess, [out] PHANDLE TokenHandle ); Вариант 2: получить токен определенного потока. BOOL OpenThreadToken( [in] HANDLE ThreadHandle, [in] DWORD DesiredAccess, [in] BOOL OpenAsSelf, [out] PHANDLE TokenHandle ); Переписывать MSDN и объяснять каждый параметр как‑то неправильно. Если вдруг ты незнаком с WinAPI, то можешь написать мне, скину материал для изучения. Предлагаю обратить внимание лишь на второй параметр — Здесь ты должен указать, какой тип доступа к токену хочешь получить. Это значение преобразуется в маску доступа, на основе которой Windows определяет, можно выдавать токен или нельзя. WinAPI предоставляет для такой маски некоторые стандартные значения. Обрати внимание, что просто так засунуть При этом данную ошибку допускают очень часто. Например, лишь в версии 4.7 инструмента Cobalt Strike был исправлен этот недочет. Чаще всего для наших задач мы будем указывать привилегию Вариант 3: запросить токен пользователя, если мы знаем его логин и пароль. BOOL LogonUserA( [in]LPCSTR lpszUsername, [in, optional] LPCSTR lpszDomain, [in, optional] LPCSTR lpszPassword, [in]DWORD dwLogonType, [in]DWORD dwLogonProvider, [out]PHANDLE phToken ); Проверка наличия привилегии в токенеТокен также содержит информацию о привилегиях пользователя. У самих привилегий в Windows есть два представления:
Для проверки можно использовать следующую функцию: BOOL PrivilegeCheck( [in]HANDLEClientToken, [in, out] PPRIVILEGE_SET RequiredPrivileges, [out] LPBOOLpfResult ); Сам код может быть примерно следующий (принимает токен, в котором надо проверить наличие привилегии, и ее имя. Допустим, bool IsPrivilegeEnabled(HANDLE hToken, PCWSTR name) { PRIVILEGE_SET set{}; set.PrivilegeCount = 1; if (!::LookupPrivilegeValue(nullptr, name, &set.Privilege[0].Luid)) return false; BOOL result; return ::PrivilegeCheck(hToken, &set, &result) && result; } Изменение информации токенаДопустимые изменения делятся на две группы:
Для большинства ситуаций можно воспользоваться этой функцией: BOOL SetTokenInformation( [in] HANDLETokenHandle, [in] TOKEN_INFORMATION_CLASS TokenInformationClass, [in] LPVOIDTokenInformation, [in] DWORDTokenInformationLength ); Конечно же, в токене возможно изменить далеко не все параметры. Ниже описаны допустимые классы информации для Что можно изменить Например, чтобы включить виртуализацию UAC, используй следующий код: // hProcess имеет PROCESS_QUERY_INFORMATION HANDLE hToken; OpenProcessToken(hProcess, TOKEN_ADJUST_DEFAULT, &hToken); ULONG enable = 1; SetTokenInformation(hToken, TokenVirtualizationEnabled,&enable, sizeof(enable)); При этом мы можем изменить и привилегии, содержащиеся в токене! Но требуется знать, как получить из программного имени привилегии ее LUID. Это позволяет сделать следующая функция: BOOL LookupPrivilegeValueA( [in, optional] LPCSTR lpSystemName, [in]LPCSTR lpName, [out]PLUID lpLuid ); Следующим шагом мы должны вызвать BOOL AdjustTokenPrivileges( [in]HANDLETokenHandle, [in]BOOLDisableAllPrivileges, [in, optional] PTOKEN_PRIVILEGES NewState, [in]DWORDBufferLength, [out, optional] PTOKEN_PRIVILEGES PreviousState, [out, optional] PDWORDReturnLength ); Эта функция может как включить привилегии, так и отключить их. Не знаю, почему Microsoft не реализовала что‑нибудь подобное: BOOL EnableTokenPrivilege(HANDLE hToken, LPTSTR szPriv, BOOL bEnabled) { TOKEN_PRIVILEGES tp; LUID luid; BOOL bRet = FALSE; __try { // Ищем уникальный для системы LUID привилегии if (!LookupPrivilegeValue(NULL, szPriv /*SE_DEBUG_NAME*/, &luid)) { // Если имя фиктивное __leave; } // Создаем массив привилегий нашего маркера (в данном случае массив из одного элемента) tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = bEnabled ? SE_PRIVILEGE_ENABLED : 0; // Изменяем состояние привилегий маркера, включая или отключая привилегии из нашего массива if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { __leave; } bRet = TRUE; } __finally {}; return(bRet); } Этой функции требуется передать токен, программное имя привилегии и булево значение, Перейти обратно к новости |