问题描述
这是我的代码:
logonSuccess = LogonUserW(userPartW, domainPartW, pwdW,
LOGON32_LOGON_BATCH,
LOGON32_PROVIDER_DEFAULT, &token);
Int result1 = SetNamedSecurityInfo("C:\\file.crt", SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, yveri, NULL, NULL, NULL);
fprintf(stderr, "result -> %d.\n", result1); //which gives me 0
if (ImpersonateLoggedOnUser(token) == FALSE)
{
printf("Imperesonating failed.\n");
return -1;
}
Int result2 = SetNamedSecurityInfo("C:\\Users\\nx\\.nx\\config\\authorized.crt", SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, yveri, NULL, NULL, NULL);
fprintf(stderr, "result -> %d.\n", result2); //which gives me 5
对SetNamedSecurityInfo的第一次调用有效,但是第二次调用(一旦模拟就位)返回错误代码5.
The first call to SetNamedSecurityInfo works, but the second call (once impersonation is in place) returns error code 5.
推荐答案
以我们在评论中发现的内容为基础:
Building on what we figured out in the comments:
当您调用任何模拟功能(ImpersonateLoggedOnUser
,ImpersonateNamedPipeClient
,RpcImpersonateClient
等)时,您基本上是在调用SetThreadToken(GetCurrentThread(), __GetInterestingToken())
(其中GetInterestingToken()
是用于获取每个令牌的相关令牌的占位符)功能).
When you call any of the impersonation functions (ImpersonateLoggedOnUser
, ImpersonateNamedPipeClient
, RpcImpersonateClient
, etc.) you're basically calling SetThreadToken(GetCurrentThread(), __GetInterestingToken())
(where GetInterestingToken()
is a placeholder for getting the relevant token for each function).
当您执行对当前安全上下文进行安全检查的任何操作时,都会对当前线程的令牌-无论它是什么-如果存在.否则,将根据流程令牌进行检查.
When you perform any action that makes a security check against the current security context it makes the check against the current thread's token - whatever it is - if it exists. Otherwise it makes the check against the process token.
当线程附加了令牌时,从进程的安全性上下文到线程的安全性都没有任何形式的继承性".您要么获得进程的安全性上下文(全部而已,别无所求),要么获得线程的特定安全性上下文(仅此而已!).
There's no "inheritance" of any sort from the process's security context to the thread's when the thread has a token attached to it. You either get the process's security context (all of it and nothing else) or a specific security context for the thread (and nothing else!).
这实际上是模仿背后的全部要点,它是 raison d'etre .
That's actually the whole point behind impersonation, it's raison d'etre.
在模仿之前完成任何操作的任何成功与模仿之后执行相同动作的能力完全无关..由于您尚未启用允许您更改内核对象所有者的特权(SeTakeOwnershipPrivilege
使您自己成为所有者,并且正如哈里·约翰斯顿正确说出的那样-SeRestorePrivilege
将其他人设置为所有者),因此您尝试进行更改它被拒绝了.
Any success you had in doing anything before impersonation is completely irrelevant to your ability to perform the same action after impersonation. Since you haven't enabled the privileges that allow you to change kernel objects' owner (SeTakeOwnershipPrivilege
to make yourself the owner, and as Harry Johnston correctly said - SeRestorePrivilege
to set someone else to be the owner) your attempt to change it is denied.
启用必要的特权(假设令牌具有令牌),以便能够更改所有者.
Enable the necessary privilege (assuming the token has it) to be able to change the owner.
与有意对另一个安全上下文进行检查的代码相反,例如,将OpenAsSelf = TRUE
传递给OpenThreadToken
时.
In contrast to code that intentionally makes the check against another security context, such as when passing OpenAsSelf = TRUE
to OpenThreadToken
.
解释客户端模拟时给出的经典示例是文件服务器,在请求服务期间以LOCAL_SYSTEM
模拟客户端运行,以确保客户端不会意外(或有意...)访问不允许客户端访问的文件.如果在模拟过程中有任何能力(权限或特权)泄漏"到了模拟线程中,那几乎会破坏模拟客户端的目的.
The classic example given when explaining client impersonation is a file server running as LOCAL_SYSTEM
impersonation the client during request servicing to make sure it doesn't accidently (or intentionally...) access files the client isn't allowed to access. If during impersonation any abilities (permissions or privileges) "leaked" to the impersonating thread that would pretty much defeat the purpose of impersonating the client.
除了ImpersonateSelf
的特殊情况外,显然,您应该能够执行模拟之前可以做的任何事情.
Except in the special case of ImpersonateSelf
, where obviously you should be able to do anything you could have done before impersonation.
这篇关于假冒时难以设置所有权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!