首页 -> 安全研究

安全研究

安全漏洞
Windows NT 4 提升用户权限的漏洞

发布日期:2000-01-14
更新日期:2000-01-18

受影响系统:
Microsoft Windows NT 4.0SP6
   + Microsoft Windows NT 4.0
Microsoft Windows NT 4.0SP5
   + Microsoft Windows NT 4.0
Microsoft Windows NT 4.0SP4
   + Microsoft Windows NT 4.0
Microsoft Windows NT 4.0SP3
   + Microsoft Windows NT 4.0
Microsoft Windows NT 4.0SP2
   + Microsoft Windows NT 4.0
Microsoft Windows NT 4.0SP1
   + Microsoft Windows NT 4.0
Microsoft Windows NT 4.0
不受影响系统:
Microsoft Windows NT 3.5.1
Microsoft Windows NT 2000.0
描述:
来源: Todd Sabin <tsabin@bos.bindview.com>
  

NT4中的NtImpersonateClientOfPort系统调用问题
  
综述:
    由于Windows NT 4中的NtImpersonateClientOfPort系统调用的缺陷,使得任何本地用户都可以冒用这台计算机上的其他用户身份。为了说明这个问题,我们写了一个演示,表明任何用户都可以得到一个本系统的cmd.exe。
  
影响:
    任何用户可在本地登陆的NT 4.0机器都受此影响。如果该机器是管理域信任,那可能会获得域管理员的访问权限级别。在终端服务器上,它可能会被用来作为“跳板”,利用该服务器对某些用户的信任来冒充他们访问另一段的网络。 (这一想法还没有经过测试。*_~)
  
细节:
    NT中有一个是非公开系统端口--Lpc端口,它主要是在本地程序调用中用到。而NtImpersonateClientOfPort正是使用到Lpc端口的一个系统API,它允许用户利用NT子系统来进行通讯。特别是当子系统的服务端进程是以客户端进程请求来激活运行时。当客户端调用它时,它允许服务端在刚建立起来的安全上下文中执行。然而,该调用的接口可以在调用中被客户端用来做过程与线程ID的欺骗。系统内核会检查参数,以确认该调用是合法的。但还是有可能骗过系统的检查。首先,内核校验你真正要冒用的端口,而该端口实际上是在发出请求。这个条件非常容易满足,只要我们自己给它发个请求。接着,它会检查发出请求的消息ID与在线程中你正在请求冒用的消息ID是否匹配。这个很容易可以取得信任,因为如果一个线程不是正在发出请求的话,那么,它的特征消息ID是零.因此,作为服务端,当有一个请求发过来的时候,我们马上更改它的pid和tid到我们想要的那个。然后将消息ID改为0。一些攻击者会利用在服务端和客户端线程间的这些先天条件,来达到欺骗服务线程的目的。最终是服务端线程取得该标识和安全上下文的欺骗线程。在攻击者冒用其他正在运行的线程后,它就拥有了合法用户的系统权限了。

  
    我们是这样伪装实现的。
    有两个线程.
  
        服务器线程                          客户机线程

        NtCreatePort
        NtReplyWaitReceivePort...
                                            NtConnectPort...
        (returns)返回
         NtAcceptConnectPort
         NtCompleteConnectPort
         NtReplyWaitReceivePort...
                                            (returns)返回
                                            NtRequestWaitReplyPort...
        (returns)返回
        修改接收到的LpcMessage,这样进程与线程ID就会指向我们所希望的,然后更改消息ID为0。
        NtImpersonateClientOfPort
  
    在这时,我们是在上面我们得到的线程中运行的。为了实现我们的目标,我们选择了冒用LSASS线程。因为必须要lsass的使能权限才可以。在冒用过程中,似乎只有在客户端被使能的的令牌才可以被冒用。否则,即便是在禁用的状态,也不可以。现在正好lsass具有CREATE_TOKEN使能的权限,所以我们可以冒用这个,然后在这个基础上利用它来创建我们自己的令牌,这个新的令牌带有all的权限。随后,我们就可以用这个令牌来启动另外一个进程:

        // 得到当前令牌的信息。
        // TOKEN_USER, TOKEN_GROUP, etc. (esp. TOKEN_PRIVILEGES)
  
        NtOpenThreadToken
        GetTokenInformation // (several times)
        // 在我们的TOKEN_PRIVILEGES结构中,增加 _all_ 的权限
        // 所有的用户空间,都为NtCreateToken准备好了

        NtCreateToken // 带有lsass令牌的信息,除了                        
                      // all权限被使能了
  
    最后,我们得到了我们自己的令牌。现在,我们可以利用它来CreateProcessAsUser,当然其中会存在很多跳转。CreateProcessAsUser要求比lsass更多的使能权限,所以目前我们不用它,因为我们的令牌能做到。我们可以伪造一个新的令牌。当然,这个还远远不够。CreateProcessAsUser在_process_令牌中检查权限,这样就会忽略任何伪造的令牌。所以最后一步就是我们把新的令牌变成我们目前的那个。
  
        ImpersonateLoggedOnUser
        NtSetInformationProcess (... ProcessAccessToken ...)
        CreateProcessAsUser
  
    现在就可以了。
  

参考:
  
Microsoft's security bulletin:
    http://www.microsoft.com/Security/Bulletins/ms00-003.asp
  
Microsoft's Knowledge Base article:
    http://support.microsoft.com/support/kb/articles/q247/8/69.asp
  
    要得到更多的关于LPC端口API的信息,参见Undocumented Windows NT, ISBN# 0-7645-4569-8, 第8章。


建议:
Microsoft hotfix:
Intel: http://www.microsoft.com/Downloads/Release.asp?ReleaseID=17382
Alpha: http://www.microsoft.com/Downloads/Release.asp?ReleaseID=17383

1、安装从Microsoft得到的hotfix。
2、如有可能,限制本地登录的权利。

浏览次数:7752
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障