Моя цель — скопировать привилегии от одного основной пользовательский токен другому, прежде чем я начну процесс пользовательского режима с маркером назначения. Я создал образец псевдокода, чтобы проиллюстрировать, что мне нужно сделать.
Следующее будет запущено из локальной системной службы:
//dwSessionId = user session ID to run process in
HANDLE hToken1 = NULL; //Source user token
WTSQueryUserToken(dwSessionId, &hToken1);
HANDLE hSelfToken = NULL; //User token for system service
HANDLE hToken2 = NULL; //Adjusted self-token
OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS, &hSelfToken);
DuplicateTokenEx(hSelfToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS,
NULL, SecurityIdentification, TokenPrimary, &hToken2);
//Specify user session to run in
SetTokenInformation(hToken2, TokenSessionId, &dwSessionId, sizeof(dwSessionId));
//Now I need to set privileges in 'hToken2' as they are in 'hToken1'
...
//Then use 'hToken2' in CreateProcessAsUser() to start a process
Любая идея, как скопировать привилегии из hToken1
в hToken2
?
Используйте следующий код для получения hToken2
от hToken
, а затем использовать его в CreateProcessAsUser
, Там нет необходимости использовать hSelfToken
, на самом деле.
HANDLE GetAdjustedToken(HANDLE hSrcToken)
{
TOKEN_LINKED_TOKEN admin = {};
HANDLE hTarToken = 0;
DWORD dw = 0;
if (GetTokenInformation(hSrcToken, (TOKEN_INFORMATION_CLASS)TokenLinkedToken, &admin, sizeof(TOKEN_LINKED_TOKEN), &dw))
{
hTarToken = admin.LinkedToken;
}
else
{
DuplicateTokenEx(hSrcToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTarToken);
}
return hTarToken;
}
И если вы хотите создать новый процесс с низким уровнем обязательной целостности, см. этот Статья MSDN.
Сначала вы должны позвонить GetTokenInformation
с помощью TokenPrivileges
класс для получения оригинального токена TOKEN_PRIVILEGES
состав. Тогда позвони AdjustTokenPrivileges
с его помощью обновить ваш клонированный токен. Вам придется позвонить GetTokenInformation
дважды — первый для получения длины буфера и второй — для получения фактических данных.
HANDLE hSelfToken = NULL; //User token for system service
HANDLE hToken2 = NULL; //Adjusted self-token
OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS, &hSelfToken);
DuplicateTokenEx(hSelfToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS,
NULL, SecurityIdentification, TokenPrimary, &hToken2);
PTOKEN_PRIVILEGES pPriv = NULL;
DWORD dwLen = 0;
GetTokenInformation(hSelfToken, TokenPrivileges, (LPVOID)pPriv, 0, &dwLen);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return(0);
pPriv = (PTOKEN_PRIVILEGES)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLen);
if (!GetTokenInformation(hSelfToken, TokenPrivileges, (LPVOID)pPriv, dwLen, &dwLen))
return(0);
AdjustTokenPrivileges(hToken2, FALSE, pPriv, dwLen, NULL, NULL);
ХОРОШО. Я мог бы получить что-то близкое к тому, что мне было нужно. Это на самом деле не копирование привилегий, но с целью «удаления» привилегий я могу создать ограниченный токен, в котором будут удалены почти все привилегии (кроме SeChangeNotifyPrivilege
а также SeSystemtimePrivilege
.)
//Call the following instead of DuplicateTokenEx() in my example above
CreateRestrictedToken(hSelfToken, DISABLE_MAX_PRIVILEGE,
0, NULL, 0, NULL, 0, NULL,
&hToken2);
К вашему сведению: просто любопытный факт. По какой-то причине я не смог удалить SeSystemtimePrivilege
от жетона. Ни с помощью этого метода, ни с помощью AdjustTokenPrivileges
с его атрибутом, установленным в SE_PRIVILEGE_REMOVED
, Все остальные привилегии могут быть просто отменены, кроме этой. Так что, если у кого-нибудь есть идея, почему, я был бы рад узнать это?