Is there a way to set a token for another process?
There is SetThreadToken() function but no such function as "SetProcessToken()".
Is there a way to set a token for another process? How to write "Se开发者_JAVA技巧tProcessToken()"?
Yes, you can, using the undocumented NtSetInformationProcess
function, however once the process has started running the process token is locked and can no longer be modified. You must therefore start the process with the CREATE_SUSPENDED
creation flag, set the process token, then resume the process using ResumeThread()
. In order to set the process token the caller must have and enable the SeAssignPrimaryTokenPrivilege
privilege.
Code such as the following should be sufficient:
// A few required typedefs
typedef enum _PROCESS_INFORMATION_CLASS
{
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers,
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
MaxProcessInfoClass
} PROCESS_INFORMATION_CLASS, *PPROCESS_INFORMATION_CLASS;
typedef struct _PROCESS_ACCESS_TOKEN
{
HANDLE Token;
HANDLE Thread;
} PROCESS_ACCESS_TOKEN, *PPROCESS_ACCESS_TOKEN;
typedef NTSTATUS (NTAPI * NtSetInformationProcess) (HANDLE processHandle, PROCESS_INFORMATION_CLASS infoClass, PVOID info, ULONG infoLength);
// Assume we have a handle to an existing process: targetProcessHandle, started in a suspended state, and a new token: newToken to assign to this process.
// First we must enable SeAssignPrimaryTokenPrivilege.
// Note: The user under which this runs must already hold the privilege, this only enables it (it is initially disabled by default).
LUID luid;
LookupPrivilegeValue(0, SE_ASSIGNPRIMARYTOKEN_NAME, &luid);
TOKEN_PRIVILEGES privs;
privs.PrivilegeCount = 1;
privs.Privileges[0].Luid = luid;
privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
HANDLE myToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &myToken))
{
wprintf("Unable to open own process token to enable permissions\n");
return FALSE;
}
if (!AdjustTokenPrivileges(myToken, FALSE, &privs, sizeof(TOKEN_PRIVILEGES), 0, 0))
{
wprintf("Error setting token privileges: 0x%08x\n", GetLastError());
CloseHandle(myToken);
return FALSE;
}
// Even if AdjustTokenPrivileges returns TRUE, it may not have succeeded, check last error top confirm
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
wprintf("Unable to enable a required privilege\n");
CloseHandle(myToken);
return FALSE;
}
CloseHandle(myToken);
PROCESS_ACCESS_TOKEN tokenInfo;
tokenInfo.Token = newToken;
tokenInfo.Thread = 0;
// Get a handle to ntdll
HMODULE ntdll = LoadLibrary(L"ntdll.dll");
// And a pointer to the NtSetInformationProcess function
NtSetInformationProcess setInfo = (NtSetInformationProcess)GetProcAddress(ntdll,"NtSetInformationProcess");
NTSTATUS setInfoResult = setInfo(targetProcessHandle, ProcessAccessToken, &tokenInfo, sizeof(PROCESS_ACCESS_TOKEN));
if (setInfoResult < 0)
{
wprintf(L"Error setting token: 0x%08x\n", setInfoResult);
return FALSE;
}
FreeLibrary(ntdll);
// You can now resume the target process' main thread here using ResumeThread().
return TRUE;
Yes. get your one token by OpenProcessToken()
, duplicate the token with DuplicateTokenEx()
, set the duplicated token as you like with SetTokenInformation()
, and create a new process with this token by CreateProcessAsUser()
you need for this the SeTcbPrivilege
, SeAssignPrimaryTokenPrivilege
and SeIncreaseQuotaPrivilege
A process only has one security token, the primary, which is a copy of the user's security token.
Threads have a second security token, the impersonation token. Processes do not have these, only threads. You cannot make a process impersonate another user's security token.
精彩评论