真正了解NT/2000下的空连接

/ns/wz/sys/data/20040418173018.htm


空连接是在没有信任的情况下与服务器建立的会话,此文将讨论在NT4.0及Windows2000下的空连接问题,将研究连接的使用及弱点,同时将显示如何控制和消除这些弱点。

在NT 4.0下的LANMAN会话

在我们开始讨论空连接之前,我们需要知道连接是什么,有一个非常好的关于NTLM验证的讨论在URL:

http://www.[M$].com/msj/defaultframe.asp?
page=/msj/0299/security/security0299.htm
&nav=/msj/0299/newnav.htm

security/security0299.htm&nav=/msj/0299/newnav.htm


Windows NT 4.0使用挑战响应协议与远程机器建议一个会话,这个会话是一个安全隧道,通过它参与隧道的机器之间可以互通信息,这个事件的顺序如下:

1) 会话请求者(客户)对会话接收者(服务器)传送一个数据包,请求安全隧道的建立。

2) 服务器产生一个随机的64位数(挑战)传送回客户。

3) 客户取得这个由服务器产生的64位数,用试图建立连接的帐号的口令打乱它,将结果返回到服务器(响应)。

4) 服务器接受响应发送到本地安全验证(LSA),LSA确认请求者身份通过使用用户正确的口令核实响应。如果请求者的帐号是服务器的本地帐号,核实本地发生;如果请求的帐号是一个域的帐号,响应传送到域控制器去核实。当对挑战的响应核实为正确,一个访问令牌产生,然后传送给客户。客户使用这个访问令牌连接到服务器上的资源直到建议的会话被终止。


在Windows 2000下 LANMAN 会话 - Kerberos 验证

Windows 2000使用Kerberos 建立一个会话"入场券",对Kerberos v5的RFC文档可在下面地址找到:

http://www.ietf.org/rfc/rfc1510.txt

事件发生的顺序如下:


1) 客户为一个TGT(票据授权票据)传送一个请求到KDC(密钥分发中心),这个请求包含了用用户口令散列算法加密的预验证数据,这个预验证数据也在最后包含了一个保证TGT不被截获的时间戳。KDC运行在承认入场券的域控制器上。

2) KDC 从它的数据库中提取用户标识的散列,用它解密预验证数据,如果解密进行有一个非常近的时间戳,进程继续。

3) 服务器产生一个TGT,它包含其它一些事项,如一个用用户散列口令加密的会话key,它也包含了标识用户和所属组的安全标识符(SID)。

4) 用户使用用户口令的散列解密会话key。

5) 客户使用入场券访问服务器上的资源,客户现在被验证,一个会话建立。


用这种方式产生的入场券包含下面未加密的信息:


发布入场券的Windows 2000 域的域名

入场券标识的名字


入场券也包含了下面加密的信息:


入场券"标记"

会话加密key

包含被发布入场券的用户帐号的域名

入场券被发布的用户的主要的名字

会话开始时间

会话结束时间:当入场券过期,入场券有一个有限的使用期限。

客户机器的地址

包含客户允许访问信息的验证信息


什么是空连接?

现在我们理解了一个连接是什么,连接包含的访问到资源的验证信息,我们可以掀开空连接的神秘面纱了。一个空连接是与一个服务器的连接的建立,没有用户验证执行。换句话说,它是一个到服务器的匿名访问。在建立连接时没有提供可信任的用户名和口令。访问令牌(在Windows 2000上的"验证数据")包含对用户的"S-1-5-7"的SID,一个"ANONYMOUS LOGON"的用户名,这个访问令牌包含下面伪装的组:


Everyone

NETWORK


在安全策略的限制下,这将授权访问到上面两个组有权访问的一切信息。

如何创建空连接

从一个用户点来看,一个与服务器的连接建立或在登陆时,或在其它任何需要访问到服务器资源时。例如,一个名为"BOB"的用户希望访问到名为"DATASTORE"的服务器上共享名为"DATA"的某些文件,先前他并没有验证,他将发布下面的命令:

net use * \\DATASTORE\DATA * /user:BOB

他将提示输入他的口令,相关的验证方法将去掉,假定他被验证,他将产生一个"访问令牌"或"入场券",使用这些,他将能连接到希望的共享。

另一方面,如果空连接允许,"DATA"共享作为一个"空共享",他只需要简单输入:

net use * \\DATASTORE\DATA "" /user:""

这将连接Bob作为一个匿名用户到"DATA"共享,不需要提供用户名或口令…一个黑客的梦想!

空连接也能通过语言如C++建立在API对话上,一个使用WIN32 API调用建立空连接的如下:

http://www.securityfocus.com/cgi-bin/vulns-item.pl
?section=exploit&id=494

空连接能使用来建立连接到"空连接命名管道",如果服务器是如此配置的话。一个"管道"是一个便利,它允许在一个系统上的进程与其它不同系统上的进程通讯。空连接也通常对共享建立连接,包括系统共享如\\servername\IPC$,IPC$是一个特殊的隐藏共享它允许在同一个系统上的两个进程间通讯(内部进程传达),IPC$共享是在机器上对服务器进程的一个分界面,它也关联一个管道所以它能被远程访问。

为什么创建空连接?

这个问题逻辑上说是:"为什么[M$]提供对空连接的支持?"在[M$]吹捧NT和Windows2000的安全时,空连接不是或多或少绕过了验证安全吗?

在一般的感觉上,"是",空连接趋向于破坏操作系统的下层的安全结构。然而,有强制性的原因合并它们进入[M$]的网络,空连接最初的目的是允许未验证的机器从服务器获得浏览列表。应该记得NT和Windows 2000在机器在组里是作为"域",域是共享同样安全边界的机器的集合,也就是说,它们共享着同样的用户和机器帐号数据库,也包括连接到彼此的口令。一个用户口令通常在域中验证一个用户,一个机器口令通常去维护机器之间和域控制器之间的安全通道。在这两样上,口令通常在机器/用户和域服务器之间建立一个信任尺寸。

如果所有的通讯是在域内部,空连接将是不需要的,这不是问题,然而,经常需要域之间连接去执行下面的任务:


从一个不同域中的服务器上得到浏览列表

验证不同域中的用户


这个问题通过域之间信任关系的概念来部分完成,信任关系是两个不同域之间的一种协作关系,通过一个域同意去信任其它域的安全完整性,因此在两个域的控制器间允许信息流。在建立信任关系时口令是被商议的,基本上,信任关系是两个域间的一种验证关系。

问题是信任关系并不能解决在一个站点上内部连接的所有问题。例如,首先,建立信任关系的进程,如果"DOMAIN1"希望与"DOMAIN2"建立信任关系,它需要联系那个域的PDC为安全隧道协商一个口令,为实现此,它需要列举域中的机器,决定"DOMAIN2"的PDC的名字,有许多发现名字(随后,地址)的方法,包括WINS、DNS、LMHOSTS、AD (活动目录)等。空连接使这个进程更容易实现,因为它允许从一个非验证的机器上带有极少优先的知识直接列举域中机器和资源。

有其它情节受益于空连接,例如,考虑到在多个域站点上的管理员,因某种原因,在所有的域之间并没有建立信任关系。在一个管理员的工作过程中,经常需要连接在所有域中的资源,空连接使用户、机器和资源的列举更容易。

另一种情形,也需要空连接,就是LMHOSTS.SAM文件使用"INCLUDE "标签的环境下,包含included文件的共享点必须安装为空连接共享,关于这点的文章可以在以下站点找到:

http://support.[M$].com/default.aspx?
scid=kb;EN-US;q121281

有一些更早一些的文章,最初是在1994年发布,但在8/8/2001更新,它应该被注释掉了,在NT 4.0 和Windows 2000 的模板LMHOSTS.SAM 文件中,许多LANMAN 方面的在Windows 2000中保留了下来。

在这也应该被提到的是,有许多卖主鼓吹在他们的软件中空连接的使用,关于这些方面一些有意思的文章在:

http://www.dcs.ed.ac.uk/home/archives/bugtraq/msg00784.html

这篇文章引用了一个卖主的一个安装进程,它在服务器上创建空连接去执行它的任务,可以想象对服务器而言是多危险,而管理员却又没意识到。

在最后一个空连接有用的例子下,一个服务,运行在本地"SYSTEM"帐号下,需要访问到网络某些资源,这仅仅可能如果资源通过一个空连接可访问,在[M$]有关于此方面的文章:

http://support.[M$].com/default.aspx?
scid=kb;EN-US;q124184

关于这个问题,[M$]并不推荐打开空连接,然而,他们推荐使用用户特定的帐号去运行服务。

什么是空连接的弱点?

现在我们对会话和空连接有了一个更好的理解,通常情况下,特别是空连接,表现出哪些弱点呢?有几个可能引起安全关注的原因,就如同我们无庸置疑地意识到,访问控制列表(ACL),即一系列ACE(访问控制条目)的列表,控制着在NT或Windows 2000 域中资源的访问。一个ACE通过SID指定一个用户/组,列举用户/组被允许或否认的权限。位于ACE的问题是授权对内嵌的组"Everyone",用NT的说法,"Everyone"意味着字面上的每个人,如果"Everyone"组通过ACE有权访问到一个资源,就意味着可以访问那个资源,如管道或共享,也对"Everyone"开放的,然后资源对任何人是匿名可访问的。

那,包含哪些种类的事情呢?如果你执行一个NT4.0的out-of-the-box安装,你将注意到许多事情对"Everyone"都是可访问的,特别是系统盘的根(通常C:\),一个显著的对"Everyone"开放的是包含修复信息的文件夹:

%SystemRoot%\Repair (通常:"C:\Winnt\Repair")

一对更敏感的文件,如"sam._",有更限制性的安全要求,但文件的大多数是位于可读的位置,为某种原因,如果一个共享点的父文件夹可用,共享是一个空连接,这个文件对任何匿名入侵者都是容易利用的。你也将注意到注册的许多区域对"Everyone"是可访问的,这使连接到一个服务器的IPC$共享成为一种可能,运行注册表编辑器(REGEDT32.EXE)去查看,甚至改变某些注册表值…来自于匿名的便利。

另外通过空连接暴露的弱点是在域中用户帐号的列举,为什么这是一个问题?因为它移走了侵占一个域帐号的一半的屏障,为伪装成其他人,你需要两部分信息:


用户名

密码


一旦你知道了用户名,它就仅仅只是一个猜测或破坏口令的问题了。如果你将域中已重命名的管理员的帐户(你肯定已重命名了管理员帐户,不是吗?)暴露的话,那么这种弱点也就达到了它的顶点。入侵者只需连接一个空会话,然后枚举用户寻找SID为500的用户即可。可以在一下站点找到可完成此任务的例子代码:

http://www.securityfocus.com/cgi-bin/vulns-item.pl?section=exploit&id=494

这个弱点对著名的"红色代码攻击"是一个非常重要的部分,它在NT4.0的SP3中得到解决。

在一个域中机器或资源的枚举也使得某人的闯入更容易,如果一个可以匿名得到域中所有机器的名字,然后列出这些机器上的资源共享,这就变成一件很简单的事情,尽力去试所有的资源直到找到一个对"Everyone"是开放的。默认情况下系统盘的根对
"Everyone"是开放,默认共享级安全应用到一个新创建的共享授权"完全访问"对"Everyone",这个问题是显然的。

如何保护以防范攻击?

最好的阻止办法是对所有范围的可能不允许空连接,为做到这一点,攻击的评估是一个好的开始,"DumpSec"工具列举系统上的共享,同时也对每个提供安全约束,它也关注注册表权限执行其它有用的安全审核任务,DumpSec可以从以下得到:

http://www.systemtools.com/somarsoft/

有一对相关的注册表键:

HKLM\System\CurrentControlSet\Control\Lsa
\RestrictAnonymous

"HKLM"参考配置单元"HKEY_LOCAL_MACHINE",如果设置为"1",匿名连接被限制,一个匿名用户仍然可以连接到IPC$ 共享,但限制通过这种连接得到信息,"1"值限制了匿名用户列举SAM帐号和共享;在Windows 2000 中增加了"2",限制所有匿名访问除非特别授权。

其它应该检查的键为:

HKLM\SYSTEM\CurrentControlSet\Services\
LanmanServer\Parameters\NullSessionShares

和:

HKLM\SYSTEM\CurrentControlSet\Services\
LanmanServer\Parameters\NullSessionPipes

这些是MULTI_SZ (多线程的)注册参数,它分别地列举共享和管道,打开空连接。如果你不想打开的话,确认没有共享和管道打开。也放置安全在这些键上确认不容易更改,确认仅"SYSTEM"和"Administrators"有权访问到这些键。

在Windows 2000,安全策略中安全保护的地方,策略设置通过相关嵌入式MMC([M$]管理控制台)。在一个域控制器(DC)上,从"管理工具"中下拉菜单"域安全策略"MMC面板,在非DC上,下拉菜单"本地安全策略"MMC面板,你将发现一个条目:

"对匿名连接的额外限制"

在3个可能设置的值:

"无。依赖于默认许可权限"

"不允许枚举SAM帐号和共享"

"没有显式匿名权限就无法访问"

最后的值是最安全的,它相当于"2"在注册表值:

HKLM\System\CurrentControlSet\Control\
Lsa\RestrictAnonymous

上面讨论的,确信检验"有效的设置",在其它水平上的策略设置能影响"有效设置"。

其它明智的步骤是限制注册表的访问,在Windows 2000 和以后版本中默认只有仅管理员和备份操作员有权网络访问到注册表,它是一个好的主意,在你的服务器上检查远程注册表访问设置,可以通过确认安全权限在以下注册键中来完成:

HKLM\System\CurrentControlSet\Control\
SecurePipeServers\winreg

当一个用户企图连接到远程计算机的注册表时,在目标机器上的"server"服务检查上述(winreg)键的存在,如果这个键不存在,用户允许连接到目标机器的注册表,如果键存在,在键上的ACL被检查,如果ACL给用户读或写的访问,用户可以连接到注册表。一旦用户允许远程连接到注册表,在单独键上的ACL开始生效。例如,如果在一个给定键上安全设置为对"Everyone"允许"读"访问,通过空连接匿名"读"访问到注册表是可能的,不是一个好的想法!它将使人担心和危险的,从所有注册键中移走对"Everyone"的远程安全,所以最好的想法是不允许访问除非特定的帐号和组。有几个值在"winreg"键也应用,这些值在NT4.0是:

HKLM\...\winreg\AllowedPaths\Machine

HKLM\...\winreg\AllowedPaths\Users

这两个值是MULTI_SZ类型的,在Windows 2000下,默认没有"Users"值,这些键分别枚举哪些注册键对机器和用户的远程访问是开放的。它们能覆盖在"winreg"键上的安全,机器可能需要访问对某些服务如目录复制和假脱机打印,有两篇关于此方面的文章也包括了远程注册表访问的细节:

http://support.[M$].com/directory/
article.asp?ID=KB;EN-US;Q186433

http://support.[M$].com/directory/
article.asp?ID=kb;en-us;Q153183

这是一个好的想法,在服务器上安装完软件后,确认安装进程没有打开任何空连接共享和管道,事实上,在一个"真实"服务器上安装前先在一台试验机上测试总是一个好的主意,特别是如果这台服务器是放在DMZ区或外部LAN。匿名访问到一台公网或半公网的机器将是损失惨重的。

也需要记住的是对一个空连接安全令牌包含两个预设组"Everyone"和"NETWORK",你可以定位在卷上文件的具体位置,通过更改权限来进行保护。当然这些卷必须是NTFS。除非你确实需要一个空连接来访问资源,否则用内置?quot;Authenticated Users"替代"Everyone"组。XCACLS或一个第三方的访问控制管理软件可完成此任务。然而,进行这样的操作一定要小心,尤其是用于子文件夹时。当用XCACLS时一定要打开"/E"选项,以确认是在编辑ACL而不是替代它们。在所有发现"Everyone"组的地方,将其删除,同时把相同的权限添加给"Authenticated Users"组。另外,每创建一个共享时,一定要将"Everyone"组从ACL中删除,代以"Authenticated Users"或合适的用户或组。

最后一步能采用的是设置策略对:

"从网络上访问计算机"

如果"Everyone"组享有这种特权的话,从组中移走,在从"Everyone"组撤走前确保添加这个特权给相应的用户和组。在NT4.0下,如果为一个非DC的机器上通过"用户管理器",在一个域控制器上通过"域用户管理器"实现。在Windows 2000下通过在相应MMC安全策略管理单元下更改"用户权力指派"下的策略。

结束语

空连接创建是为了便利内部平台通讯,特别是在服务级上,然而,使用空连接也对可能危及系统安全的匿名用户暴露了信息。如果可能的话,从你的系统上完全消除空连接,如果因为其它原因不可能实现,采取所有可能的预防措施确保只暴露你想暴露的信息。如果没有的话,空连接能提供一个便利的入口进出你的系统,它可能导致安全危险。

=========================
文章类型:转载 提交:沙加II 核查:NetDemon