为什么OpenProcessToken因ERROR_ACCESS_DENIED而失败

时间:2010-01-15 17:33:41

标签: c security winapi

我正在以管理员组中的用户身份运行进程,尝试获取另一个进程的进程令牌。另一个进程由不在Administrators组中的用户运行。这是我正在使用的代码的要点。此代码中的pid表示非管理进程的进程ID。所有这些都在Windows XP SP 2上,并且都在同一台机器上。这里没有远程访问。

HANDLE handle;
HANDLE token;

handle = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pid);
token = NULL;
OpenProcessToken(handle,TOKEN_DUPLICATE,&token);

这里的OpenProcess参考:http://msdn.microsoft.com/en-us/library/ms684320%28VS.85%29.aspx

这里的OpenProcessToken参考:http://msdn.microsoft.com/en-us/library/aa379295%28VS.85%29.aspx

OpenProcess成功,但无论我将DesiredAccess参数传递给OpenProcessToken,它都会失败并且GetLastError()会返回ERROR_ACCESS_DENIED。我添加了一些代码来了解运行此代码的进程的权限,并尽可能多地启用,以及收集有关我正在尝试获取令牌的进程的信息。这涉及从OpenProcess请求更多访问(READ_CONTROL | ACCESS_SYSTEM_SECURITY以及PROCESS_QUERY_INFORMATION)并调用GetKernelObjectSecurity(句柄)。这就是我所拥有的:

current user: PLEASE_T\dbyron (S-1-5-21-3405506234-1792454352-3826119157-1005)
current process: group 0: flags: 0x00000007 sid: S-1-5-21-3405506234-1792454352-3826119157-513 (PLEASE_T\None)
current process: group 1: flags: 0x00000007 sid: S-1-1-0 (\Everyone)
current process: group 2: flags: 0x0000000F sid: S-1-5-32-544 (BUILTIN\Administrators)
current process: group 3: flags: 0x00000007 sid: S-1-5-32-545 (BUILTIN\Users)
current process: group 4: flags: 0x00000007 sid: S-1-5-4 (NT AUTHORITY\INTERACTIVE)
current process: group 5: flags: 0x00000007 sid: S-1-5-11 (NT AUTHORITY\Authenticated Users)
current process: group 6: flags: 0xC0000007 sid: S-1-5-5-0-91553 (no account mapping)
current process: group 7: flags: 0x00000007 sid: S-1-2-0 (\LOCAL)
SeDebugPrivilege privilege enabled
SeTakeOwnershipPrivilege privilege enabled
SeSecurityPrivilege privilege enabled
SeChangeNotifyPrivilege privilege enabled
SeBackupPrivilege privilege enabled
SeRestorePrivilege privilege enabled
SeSystemtimePrivilege privilege enabled
SeShutdownPrivilege privilege enabled
SeRemoteShutdownPrivilege privilege enabled
SeDebugPrivilege privilege enabled
SeSystemEnvironmentPrivilege privilege enabled
SeSystemProfilePrivilege privilege enabled
SeProfileSingleProcessPrivilege privilege enabled
SeIncreaseBasePriorityPrivilege privilege enabled
SeLoadDriverPrivilege privilege enabled
SeCreatePagefilePrivilege privilege enabled
SeIncreaseQuotaPrivilege privilege enabled
SeUndockPrivilege privilege enabled
SeManageVolumePrivilege privilege enabled
SeImpersonatePrivilege privilege enabled
SeCreateGlobalPrivilege privilege enabled

我试图让每个权限都成为可能,我认为上面的组信息显示调用OpenTokenProcess的进程是Administrators组的成员。

以下是来自GetKernelObjectSecurity的信息:

control(SE_DACL_PRESENT | SE_SELF_RELATIVE, 0x00008004)
owner sid: S-1-5-21-3405506234-1792454352-3826119157-2807 (PLEASE_T\dummyusr)
group sid: S-1-5-21-3405506234-1792454352-3826119157-513 (PLEASE_T\None)
grant: mask(PROCESS_ALL_ACCESS, 0x001F0FFF), flags(0x00000000): S-1-5-21-3405506234-1792454352-3826119157-2807 (PLEASE_T\dummyusr)
grant: mask(PROCESS_ALL_ACCESS, 0x001F0FFF), flags(0x00000000): S-1-5-32-544 (BUILTIN\Administrators)
grant: mask(PROCESS_ALL_ACCESS, 0x001F0FFF), flags(0x00000000): S-1-5-18 (NT AUTHORITY\SYSTEM)

因此,似乎dummyusr(非管理员)进程允许访问Administrators组。我有可能误解了为什么OpenProcessToken失败了ERROR_ACCESS_DENIED?我尝试将TOKEN_DUPLICATE更改为TOKEN_QUERY,但这不会改变结果。

我错过了特权吗?还有什么可以拒绝我访问此进程的访问令牌?我在没有防病毒软件的机器上试过这个,但我得到了相同的结果。

我也试过在系统环境中运行。在这种情况下,有关当前流程的信息是:

current user: NT AUTHORITY\SYSTEM (S-1-5-18)
current process: group 0: flags: 0x0000000E sid: S-1-5-32-544 (BUILTIN\Administrators)
current process: group 1: flags: 0x00000007 sid: S-1-1-0 (\Everyone)
current process: group 2: flags: 0x00000007 sid: S-1-5-11 (NT AUTHORITY\Authenticated Users)

请注意,BUILTIN \ Administrators组的标志略有不同。管理员进程为0xF,系统进程为0xE。从http://msdn.microsoft.com/en-us/library/aa379624%28VS.85%29.aspx开始,0x1位表示SE_GROUP_MANDATORY,这似乎与此无关。

默认情况下,系统上下文进程还具有一些额外的权限:

SeAuditPrivilege
SeCreatePermanentPrivilege
SeLockMemoryPrivilege
SeTcbPrivilege

但是我全部禁用了它们,OpenProcessToken仍然在系统上下文进程中成功。

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

首先,您是否已经走下了淘汰之路? - 将过程作为LOCAL_SYSTEM运行,看看是否可以解决问题。毕竟,如果上帝不能做到,那么没有人可以:P。

答案 1 :(得分:0)

我猜目标进程的SECURITY_DESCRIPTOR只允许SYSTEM用户打开他的进程令牌。 遗憾的是,你无能为力。

答案 2 :(得分:-1)

是的,您可以将服务或应用实例作为服务运行。通过这种方式,您可以将代码作为系统运行....

另一个选项(但更具侵入性),因为你已经是管理员,是改变目标进程acl ....