Here is my code:
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
The first call to SetNamedSecurityInfo works, but the second call (once impersonation is in place) returns error code 5.
答案 0 :(得分:1)
基于我们在评论中发现的内容:
当您调用任何模拟函数(ImpersonateLoggedOnUser
,ImpersonateNamedPipeClient
,RpcImpersonateClient
等)时,您基本上会调用SetThreadToken(GetCurrentThread(), __GetInterestingToken())
(其中{{1}是一个占位符,用于获取每个函数的相关标记。)
当你执行任何针对当前安全上下文 1 进行安全检查的操作时,它会检查当前线程的令牌 - 无论它是什么 - 如果它存在。否则,它会对进程令牌进行检查。
没有"继承"当线程附加了一个令牌时,从进程的安全上下文到线程的任何类型。您要么获得进程的安全上下文(所有内容而不是其他内容),要么获得该线程的特定安全上下文(没有别的!)。
这实际上是模仿背后的全部观点,它是 raison d' etre 2 。
在模仿之前你做任何事情都取得了成功与你在模仿 3 之后执行相同动作的能力完全无关。由于您尚未启用允许您更改内核对象的权限。所有者(GetInterestingToken()
让自己成为所有者,正如Harry Johnston正确地说 - SeTakeOwnershipPrivilege
将其他人设为所有者一样,您拒绝更改它的尝试。
启用必要的权限(假设令牌具有权限)以便能够更改所有者。
1 与有意对另一个安全上下文进行检查的代码相反,例如将SeRestorePrivilege
传递给OpenAsSelf = TRUE
时。
2 在解释客户端模拟时给出的经典示例是在请求服务期间以OpenThreadToken
模拟客户端的文件服务器,以确保它不会(或故意)。 ..)访问客户端不允许访问的文件。如果在假冒期间任何能力(权限或特权)"泄露"模仿线程几乎无法冒充客户的目的。
3 除LOCAL_SYSTEM
的特殊情况外,显然你应该能够做任何你在模仿之前可以做的事情。