冒充时无法设置所有权

Posted

技术标签:

【中文标题】冒充时无法设置所有权【英文标题】:Trouble setting ownership when impersonating 【发布时间】:2016-04-04 16:57:51 【问题描述】:

这是我的代码:

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。

【问题讨论】:

为什么在服务器端使用CreateFile()?您应该改用ConnectNamePipe()。命名管道客户端使用CreateFile() 连接到命名管道。命名管道服务器使用CreateNamedPipe() 打开管道,然后ConnectNamedPipe() 接受管道上的客户端。如果您在服务器端使用CreateFile(),它将连接到自己的管道,然后模拟自己。 感谢@RemyLebeau 的回复我在这里输入了错误的代码,请检查编辑后的代码 你创建的进程具体没有哪些权限? 现在您正在谈论命名管道客户端。您的问题表明问题出在命名管道服务器正在运行的程序上。请确定是什么问题。我的通灵调试能力(TM Raymond Chen)告诉我,用户名存储在userPartW 中的用户根本没有权限设置文件C:\Users\nx\.nx\config\authorized.crt 的所有者,并且之后您还没有启用SeTakeOwnershipPrivilege 权限开始模仿。为什么它应该起作用? 一个猜测:yveri 包含当前用户的 SID,因此当您以当前用户身份运行时,允许更改,但当您以其他人身份运行时,则不允许. (除非您启用了恢复权限,否则您不能将文件的所有权授予其他人。)所示代码可以工作的唯一情况是yveri 包含本地Administrators 组的SID。 (问题也可能是您为主进程令牌启用了一个或多个特权,而忘记为模拟令牌执行相同的操作。) 【参考方案1】:

以我们在 cmets 中得出的结论为基础:

当您调用任何模拟函数(ImpersonateLoggedOnUserImpersonateNamedPipeClientRpcImpersonateClient 等)时,您基本上是在调用SetThreadToken(GetCurrentThread(), __GetInterestingToken())(其中GetInterestingToken() 是一个占位符,用于获取每个模拟函数的相关令牌函数)。

当您执行任何对当前安全上下文进行安全检查的操作1时,它会检查当前线程的令牌 - 不管它是什么 - 如果存在。否则,它会检查进程令牌。

当线程附加了令牌时,从进程的安全上下文到线程的安全上下文没有任何形式的“继承”。您要么获取进程的安全上下文(仅此而已),要么获取线程的特定安全上下文(仅此而已!)。

这实际上是模仿背后的全部意义,它是存在的理由2

您在模仿之前做任何事情的成功与您在模仿之后执行相同操作的能力完全无关3。由于您尚未启用允许您更改内核对象所有者的权限(SeTakeOwnershipPrivilege 使您自己成为所有者,正如 Harry Johnston 正确所说 - SeRestorePrivilege 将其他人设置为所有者)您尝试更改它被拒绝了。

启用必要的权限(假设令牌拥有它)以便能够更改所有者。


1 与有意对另一个安全上下文进行检查的代码相比,例如将OpenAsSelf = TRUE 传递给OpenThreadToken 时。

2 解释客户端模拟时给出的经典示例是文件服务器以LOCAL_SYSTEM 身份运行,在请求服务期间模拟客户端,以确保它不会意外(或有意...)访问不允许客户端访问的文件。如果在模拟过程中任何能力(权限或特权)“泄露”到模拟线程,这几乎会破坏模拟客户端的目的。

3 除了ImpersonateSelf 的特殊情况,显然你应该能够做任何你在模仿之前可以做的事情。

【讨论】:

以上是关于冒充时无法设置所有权的主要内容,如果未能解决你的问题,请参考以下文章

无法为自定义 UITableView 单元设置约束,在 xib 中创建,因为所有数据在大小类更改时消失

将“HttpOnly”属性添加到所有会话 cookie

骗子爱比特币,冒充马斯克骗走百万美金还无法追踪(FTC报告全文)

调整一个行高时如何设置wpf数据网格的所有行高

javascript 组合模式,对象冒充+原形链继承

为啥文件夹会出现 无法显示当前所有者