OpenProcessToken()给出“访问被拒绝”

时间:2016-10-02 09:24:24

标签: delphi gpo openprocess

作为在登录屏幕(用于桌面控制)中生成进程的服务运行的项目的一部分,我们调用OpenProcessToken(),然后将其复制并创建进程。这在LocalSystem下按预期成功运行,但是这在域帐户下不起作用。代码片段如下......

procedure LaunchProcess;
var dwPid, dwSessionId: DWord;
  hUserToken, hProcess: THANDLE;
begin
  dwPid := GetProcessID('winlogon.exe', WTSGetActiveConsoleSessionId);
  hProcess := OpenProcess(MAXIMUM_ALLOWED, FALSE, dwPid);
  if (not OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY or TOKEN_DUPLICATE or
    TOKEN_ASSIGN_PRIMARY or TOKEN_ADJUST_SESSIONID or TOKEN_READ or TOKEN_WRITE, hUserToken)) then
      raise Exception.Create('OpenProcessToken failed (' + SysErrorMessage(GetLastError) + ').');

  {...go on to duplicate token, create environment and launch process...}

end;

可以找到周围支持功能的完整来源here

这是一个有点模糊的地方。我理解OpenProcessToken()需要权限,这最终是我收到错误的原因,但是我不清楚我需要什么权限,以及如何有效地为域帐户分配权限。

This表示所需的权限是SeTcbPrivilege(“作为操作系统的一部分”)。

我已经在特权上阅读了Microsoft页面(无法链接,没有足够的声誉 - 抱歉),这表明可以使用本地或组安全策略将SeTcbPrivilege分配给域帐户。还有人建议,目标进程(即winlogon.exe)可能只是不允许除LocalSystem以外的任何其他东西获取其令牌。

我尝试使用帐户服务明确配置域帐户,但在本地安全和组策略中,已重新启动并执行gporesult以确保策略生效,但每次{{1} }返回SeTcbPrivilege已禁用

我的问题是,如果这是可能的(我可以使用域帐户获取winlogon.exe令牌),如果是这样,可以通过编程方式设置权限,还是需要通过GPO? (如果是这样的话,鉴于我之前尝试使用GPO没有效果,怎么可能)

2 个答案:

答案 0 :(得分:1)

  1. 您可以使用LsaAddAccountRights激活权限,您仍然需要至少注销/启动可能重启。
  2. 然后,您需要在代码中为这些权限启用权限。对于不适合用户的本地系统,会自动发生很多事情。
  3. 要进行快速测试,我已启用并启用了SE_TCB_NAME,SE_ASSIGNPRIMARYTOKEN_NAME和SE_INCREASE_QUOTA_NAME
  4. 然后,我只能使用TOKEN_DUPLICATE
  5. 成功调用OpenProcessToken
  6. 在注销/开启后,激活这些权限会给我一个新的SessionID。 SessionID为2,因此您对WTSGetActiveConsoleSessionId的调用将错误地返回1
  7. 所有这些都是以提升的Admin

    完成的

答案 1 :(得分:0)

使用管理员权限运行应用程序时,您的应用程序是否成功运行?如果是,请转到项目选项,选择“应用程序”并选中“清单文件”下的“启用管理员权限”。