某些Windows API返回主令牌,有些返回模拟令牌.某些API需要主令牌,而其他API则需要模拟令牌.
例如,LogonUser通常返回主令牌,除非LOGON32_LOGON_NETWORK用作登录类型(dwLogonType)时:
在大多数情况下,返回的句柄是您可以在调用CreateProcessAsUser函数时使用的主令牌.但是,如果指定LOGON32_LOGON_NETWORK标志,则LogonUser将返回您无法在CreateProcessAsUser中使用的模拟标记,除非您调用DuplicateTokenEx将其转换为主标记.
SetThreadToken需要一个模拟令牌,而ImpersonateLoggedOnUser这似乎做同样的事情需要一个.
CreateProcessAsUser并且CreateProcessWithTokenW两者都需要一个主令牌,并注意可以通过调用从模拟令牌中获取主令牌DuplicateTokenEx,但令牌类型是什么意思?
词汇表说明如下:
访问令牌包含登录会话的安全信息.系统在用户登录时创建访问令牌,并且代表用户执行的每个进程都具有令牌的副本.令牌标识用户,用户的组和用户的权限.系统使用令牌来控制对安全对象的访问,并控制用户在本地计算机上执行各种系统相关操作的能力.有两种访问令牌,主要和模拟.
通常仅由Windows内核创建的访问令牌.可以将其分配给进程以表示该进程的默认安全信息.
已创建的访问令牌,用于捕获客户端进程的安全信息,允许服务器在安全操作中"模拟"客户端进程.
但这并不完全有用.似乎有人想要使用像"内核"这样的大男孩字样,但这只会引发更多问题,例如除了被分配到进程之外还可以使用主要令牌以及除了内核之外的其他人可以创建访问权限令牌?
(他们的意思是微软的意思,内核只是内核模式运行的一部分,还有执行等等,或者他们是否意味着用户模式代码也可以创建令牌?无论如何,即使用户 - 模式代码可以创建令牌,它必须通过系统调用来完成,就像任何对象管理器对象一样,所以无论如何,令牌实际上都是以内核模式创建的.)
无论如何,这并没有回答基本问题:令牌类型之间有什么区别?不是它们可能被用于什么或通常如何创建它们.
我有一个类库,可以在注册表(HKLM\Software\XXX)中保存系统范围的配置数据.该库用于各种版本的Windows(XP,2003,7,2008 R2)上的各种应用程序(服务,Windows窗体,Web应用程序,控制台应用程序).因此,应用程序的身份不一致,甚至可能不是计算机管理员组的成员.因此,我创建了一个AD域管理员用户并进行模拟,以获得对注册表的写入权限.这在XP/2003中完美运行,但在启用UAC的系统(7/2008R2)中不起作用.我的理解是,只有交互式登录才会拆分令牌,这意味着非交互式登录(服务标识,应用程序池标识等)不会.我找不到任何可以确认的东西,但是根据这个假设,我正在做的模仿应该有效.
我编写了一个包装类来使用本机LogonUser(网络登录类型,默认提供程序)和DuplicateTokenEx(模拟,主令牌)然后使用WindowsIdentity.Impersonate()进行模拟.我得到了我的根密钥的引用:
using (ECR.Impersonator imp = new ECR.Impersonator("XXX", "XXX", "XXX"))
{
_root = Registry.LocalMachine.CreateSubKey("SOFTWARE\\XXX", RegistryKeyPermissionCheck.ReadWriteSubTree);
}
Run Code Online (Sandbox Code Playgroud)
根据MSDN,通过使用ReadWriteSubTree,这应该是安全检查的唯一时间.我可以为该键写入值,创建子键(也使用ReadWriteSubTree)并将值写入这些子键,而无需进行其他安全检查.所以我认为我只需要进行一次昂贵的模拟 - 获取对我的根密钥的引用.
我可以将值写入我的根密钥:
_root.SetValue("cachedDate", value.ToBinary(), RegistryValueKind.QWord); }
Run Code Online (Sandbox Code Playgroud)
但是当我使用ReadWriteSubTree创建/打开一个子键时:
RegistryKey key = _root.CreateSubKey("XXX", RegistryKeyPermissionCheck.ReadWriteSubTree);
Run Code Online (Sandbox Code Playgroud)
它爆炸了Access to the registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\XXX\XXX' is denied.
虽然我很好奇为什么在MSDN说不应该进行安全检查时,我的问题是如何通过假冒来获得可能无法在交互式登录下运行的应用程序的提升权限?
脚本
我有一台远程计算机,我想以编程方式运行安装程序(任意可执行文件).这些安装程序需要两件事:
事实证明这非常具有挑战性.
看起来好像有一些外部工具可以做到这一点,但我正在寻找Windows附带的解决方案.
这个问题的有效解决方案是什么样的
从提升的上下文(例如,提升的批处理文件或可执行程序),有效的解决方案应该能够以管理员模式在另一个用户上下文下以编程方式启动进程.假设其他用户的ID和密码可用,而另一个用户是Administrators组的成员.附加限制:
请在发布前测试您的解决方案以确保其有效!如果您要提供指向其他解决方案的链接,请在发布之前验证链接的解决方案是否有效.许多声称已经解决这个问题的人实际上没有.
我试过了什么
我尝试过使用Batch Scripts,PowerShell和C#.据我所知,这些技术都不能完成任务.它们都遭受同样的基本问题 - 以另一个用户身份运行任务并且在管理员模式下是相互排斥的进程.让我更具体一点:
为何不批量
用于在不同用户上下文下运行的命令是Runas,它不会启动提升的进程.有几种外部工具可以解决这个问题,但如前所述,这些工具是不允许的.
为什么不PowerShell
启动新进程Start-Process的命令可以提升新进程并以不同用户身份运行,但不能同时运行.我在这里提到了一个未解决的问题.不幸的是,没有人提供解决方案,这让我相信这是不可能的.
为什么不C#
这似乎也是不可能的,因为Process类似乎不支持在管理员模式下以及在不同用户的凭据下启动进程.
为什么不是外部工具?
这迫使我依赖别人的代码来做正确的事情,我宁愿自己编码而不是这样做.事实上,我有一个比依赖别人更好的解决方案,但是相当hackish:
提前感谢任何试图帮助的人!非常感谢,我希望如果没有别的,其他人能够找到这个任务计划程序的工作.