有SetThreadToken()函数,但没有“SetProcessToken()”这样的函数。
有没有办法为另一个进程设置令牌?如何写“SetProcessToken()”?
答案 0 :(得分:7)
是的,您可以使用未记录的NtSetInformationProcess
函数,但是一旦进程开始运行,进程令牌就会被锁定,无法再进行修改。因此,您必须使用CREATE_SUSPENDED
创建标志启动流程,设置流程令牌,然后使用ResumeThread()
恢复流程。为了设置进程令牌,调用者必须拥有并启用SeAssignPrimaryTokenPrivilege
权限。
以下代码应该足够了:
// 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;
答案 1 :(得分:3)
是。通过OpenProcessToken()
获取一个令牌,使用DuplicateTokenEx()
复制令牌,使用SetTokenInformation()
设置重复令牌,然后使用此令牌创建一个新进程CreateProcessAsUser()
< / p>
您需要SeTcbPrivilege
,SeAssignPrimaryTokenPrivilege
和SeIncreaseQuotaPrivilege
答案 2 :(得分:1)
进程只有一个安全令牌,即主要安全令牌,它是用户安全令牌的副本。
线程有第二个安全令牌,即模拟令牌。进程没有这些,只有线程。您无法使进程模拟其他用户的安全令牌。