2

在 Unix 中,当代表某个用户执行某些操作时,系统程序通常调用 seteuid(UID)(附带 setegid())首先切换到该用户,执行操作,然后在完成时使用 seteuid( 0)。我对 seteuid() 计时,它的时间大约是一到几微秒(这意味着,相对于需要完成的操作(例如操作文件或运行 CGI 程序)而言,它非常便宜)。

我不熟悉 Windows API。我们是否在 Windows 上做同样的事情(但使用 ImpersonateLoggedOnUser() + RevertToSelf() API 函数)?一般来说,这些功能有多快?

4

1 回答 1

2

它几乎是相同的,但要记住一个重要的区别:您提到的 Windows API 需要一个有效令牌的 HANDLE。

换句话说,即使作为 SYSTEM(或任何具有 SeTcbPrivilege 的进程)运行,您也需要模拟登录用户

用户可以通过多种方式登录:

  • 与物理计算机交互
  • 通过远程桌面会话
  • 几乎所有 Microsoft 网络连接,如文件共享、名称管道、邮槽、RPC 和所有其他构建在上面的。

在大多数情况下,创建进程会使其继承当前令牌。

在 IIS 中使用 Kerberos、NTLM 还是 HTTP BASIC auth 都没有关系。它全部由 Windows 进行身份验证,因此您会获得一个令牌。另一方面,Tomcat 中的 HTTP BASIC 身份验证不会为您提供 Windows 令牌,因此无法进行模拟。

现在有了棘手的部分。

当您考虑它时,令牌实际上只是一个内存结构,其中包含用于授权 (DACL) 和审计 (SACL) 的访问控制列表。它由身份验证包(AP) 创建。创建令牌的是 AP。有点像 Unix 中的 PAM,AP 可以被自定义代码替换。

事实上,存在一个开源的 setuid Authentication Package。将 CVS 移植到 Windows NT 的人们编写了一个 AP 来凭空创建一个令牌,只要您有 SeTcbPrivilege(root 等效项)。我从未尝试过,但它可以在本地机器上为不存在的用户提供令牌。该代码相当旧(它只会创建提升的令牌),但除此之外,它是 LGTM。不涉及身份验证,不涉及密码或智能卡,因此使用该组成令牌运行的进程将无法使用它对另一台计算机进行身份验证。

总结:

  • 大体思路是一样的
  • 如果您遵守规则,则无论登录程序或位置如何,您都只能冒充登录用户
  • 你可以改变这种行为,但它
  • 模拟在 Unix 和 Windows 中可能一样快,因为内部工作大致相似。您可能不会注意到差异。

一个建议:我的《 Programming Windows Security》副本全是咖啡色的黄色,上面挂着便利贴和撕破的页面。有关该主题的最佳文本,如果您想了解 Windows 安全性,必须阅读。

于 2012-09-07T03:54:05.800 回答