0

我想要实现的是当进程在非管理员用户(Windows 登录用户)下以管理员身份运行时来自会话 ID 的实际令牌句柄。

        DWORD dwSessionId = 0;
        if (false == ProcessIdToSessionId(dwProcessId, &dwSessionId))
        {
            LOG_ERROR(L"Failed obtaining session id");
            return false;
        }

        HANDLE hToken
        if (false == WTSQueryUserToken(dwSessionId, &hToken))
        {
            LOG_ERROR(L"Failed to obtain session's handle");
            return false;
        }

当我调用 WTSQueryUserToken 时出现我的问题,它失败并出现错误 1314,这意味着我需要授予具有 SE_TCB_NAME 权限的调用令牌。

所以我尝试使用以下代码这样做:

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
bool bSuccess = DynamicAPI::AdjustTokenPrivileges(
    %%WHICH_TOKEN_EXACTLLY%%,
    FALSE,
    &tp,
    sizeof(TOKEN_PRIVILEGES),
    (PTOKEN_PRIVILEGES)nullptr,
    (DWORD)nullptr);

但我不完全确定应该准确提供哪个令牌。我已经用%%WHICH_TOKEN_EXACTLLY%%占位符标记了它。对于我的测试,我尝试 AdjustTokenPriviliges 我的进程的令牌(管理员权限),但它也没有帮助。

4

2 回答 2

1

如果需要调整权限的线程正在模拟用户,使用OpenThreadToken(GetCurrentThread())获取模拟令牌。否则,用于OpenProcessToken(GetCurrentProcess())获取调用进程的令牌。

于 2015-02-26T20:12:24.597 回答
0

您通常需要在您的进程令牌中启用权限,您可以使用 GetProcessToken() 函数获得该权限。例外情况是,如果您打算在模拟时使用该特权,那么您应该在模拟令牌中启用该特权。

我使用此代码启用恢复权限:

DWORD enable_restore() 
{    
  // This allows us to override security to delete files

  HANDLE token;
  BOOL flag;

  struct {
    DWORD count;
    LUID_AND_ATTRIBUTES privilege;
  } token_privileges;

  token_privileges.count = 1;
  token_privileges.privilege.Attributes = SE_PRIVILEGE_ENABLED;

  flag = LookupPrivilegeValue(0, SE_RESTORE_NAME, &token_privileges.privilege.Luid);
  if (!flag) return GetLastError();

  flag = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token);
  if (!flag) return GetLastError();

  flag = AdjustTokenPrivileges(token, 0, (PTOKEN_PRIVILEGES)&token_privileges, 0, 0, 0);
  if (!flag) return GetLastError();

  return 0;    
}

请注意,此代码不检查权限是否实际被授予。为此,请在调用 AdjustTokenPrivileges() 后检查 GetLastError() - 这是最后一个错误代码有意义的罕见情况之一,即使函数报告成功也是如此。

注意:这是您尝试使用进程令牌失败的最可能原因;如果您没有将代码作为本地系统运行,并且没有重新配置 Windows 以赋予您使用 SE_TCB_NAME 权限的帐户,则对 AdjustTokenPrivileges() 的调用将报告成功但没有效果。

另外,请记住,无论您是否具有 SE_TCB_NAME 权限,如果您在本地系统上下文中运行,则只能使用 WTSQueryUserToken(),即通常只有系统服务或在系统服务上下文中运行的应用程序可以用它。(我不确定冒充本地系统是否足够。我怀疑不是。)

于 2015-02-26T22:16:14.150 回答