Как скопировать привилегии с одного токена основного пользователя на другой?

Моя цель — скопировать привилегии от одного основной пользовательский токен другому, прежде чем я начну процесс пользовательского режима с маркером назначения. Я создал образец псевдокода, чтобы проиллюстрировать, что мне нужно сделать.

Следующее будет запущено из локальной системной службы:

//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?

2

Решение

Используйте следующий код для получения 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.

1

Другие решения

Сначала вы должны позвонить 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);
0

ХОРОШО. Я мог бы получить что-то близкое к тому, что мне было нужно. Это на самом деле не копирование привилегий, но с целью «удаления» привилегий я могу создать ограниченный токен, в котором будут удалены почти все привилегии (кроме 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, Все остальные привилегии могут быть просто отменены, кроме этой. Так что, если у кого-нибудь есть идея, почему, я был бы рад узнать это?

0
По вопросам рекламы [email protected]