📄 753.html
字号:
换句话说,你最好保证你的计算机安装了最新的系统补丁。Security Analyzer 就能够向你提供有关这方面的信息,而通过下面的脚本也同样能够做到:<br />
<br />
strComputer = "."<br />
Set objWMIService = GetObject("winmgmts:\\" & strComputer &<br />
"\root\cimv2")<br />
Set colOperatingSystems = objWMIService.ExecQuery _<br />
("Select * from Win32_OperatingSystem")<br />
For Each objOperatingSystem in colOperatingSystems<br />
Wscript.Echo objOperatingSystem.ServicePackMajorVersion _<br />
& "." & objOperatingSystem.ServicePackMinorVersion<br />
Next<br />
<br />
在你开始提问之前,首先申明一点:WMI不会显示你所安装的所有升级包的信息,它只会告诉你安装的最新的升级包情况。但是这个应该不成问题,因为最新的升级包都包含了以前版本中的修补程序和升级程序。如果你在 WINDOWS 2000 中安装了 Service Pack 4,那么你安装的不仅仅是 Service Pack 4 中所增加的内容,它也包含了 Service Pack 1、2 和 3 中的所有内容。或者说,只要你知道自己的计算机已经安装了 Service Pack 4,你就没有必要担心你的计算机是否已经安装了Service Pack 1、2 或 3。事实上,它们肯定已经全部安装了。<br />
<br />
任务五:检查 Hot Fix<br />
<br />
你知道有关最近几次病毒以及蠕虫攻击的真正悲哀的地方在哪里吗?其实很多补丁已经提供很久了,如果用户能够使用的话,就能够避免计算机遭受攻击。但是出于多种原因,人们就是没有使用这些补丁,直到病毒找上门来,后果我不说大家也知道了。我说这些是什么意思?确保自己有最新的补丁和热修补程序(有关如何操作的更多信息请点击此处),并且确保自己的计算机安装了必需的修补程序。<br />
<br />
但是你怎么知道机器上装了哪些热修补程序呢?你问的真是好笑:<br />
<br />
strComputer = "."<br />
Set objWMIService = GetObject("winmgmts:\\" & strComputer &<br />
"\root\cimv2")<br />
Set colQuickFixes = objWMIService.ExecQuery _<br />
("Select * from Win32_QuickFixEngineering")<br />
For Each objQuickFix in colQuickFixes<br />
Wscript.Echo "Description: " & objQuickFix.Description<br />
Wscript.Echo "Hot Fix ID: " & objQuickFix.HotFixID<br />
Next<br />
<br />
注意: 如果你使用的是 WINDOWS 2000 操作系统,有些计算机在进入Win32_QuickEngineering 类的时候可能会发生死机现象。有关此已知问题的更多信息以及如何修复,请点击这里。<br />
<br />
这段脚本可以很好的工作,但是老实说,和 Security Analyzer 比起来还是要逊色一点。因为 Security Analyzer的确有些不俗的表现:它不仅仅告诉你哪些热修补已经安装了,还显示哪些没有安装。换句话说,如果没有安装某些必须的补丁的话,它会提示你。<br />
<br />
那么 Security Analyzer 如何分辨哪些必须安装哪些不必呢?当你运行 Security Analyzer 时,它会参考一个文件(Mssecure.xml),该文件包含一个重要补丁列表以及哪些计算机(不同版本的 WINDOWS)需要哪些补丁的信息。<br />
<br />
编写 Mssecure.xml 文件超出了本专栏的范围(虽然对于掌握 XML 知识的人来说这并非不可能)。但是,在以后的专栏中,我们将展示一些你也可以执行针对特定热修补 和补丁的类似方法。<br />
<br />
任务六:检查本地管理员数目<br />
<br />
人多手脚乱,太多的管理员同样也会坏了好事。更加重要的是,有更多的管理员意味着某人(管理员)犯某种错误从而将计算机暴露与他人攻击之下的可能性也大大增加。你也许会给你的邻居一把备用钥匙,好让他在你不在的时候更好的照看你的东西。但是你不会将你的备用钥匙分发给公共汽车上遇到的每个人。(我们暂且假设你不会这么做)同理,所以你会限制本地管理员的数量,因为从定义上来说,他们可以做许多超出你期望范围以外的事。<br />
<br />
同 Security Analyzer 一样,脚本也能够返回计算机上本地管理员组的所有成员。事实上,下面这段代码就是完成这项功能的:<br />
<br />
Set objNetwork = CreateObject("Wscript.Network")<br />
strComputer = objNetwork.ComputerName<br />
Set objGroup = GetObject("WinNT://" & strComputer &<br />
"/Administrators,group")<br />
For Each objUser in objGroup.Members<br />
Wscript.Echo objUser.Name<br />
Next<br />
<br />
这些材料是非常有用的;无任什么时候,只要你有时间(假设你能够抽出时间),你可以仔细研究这份名单,必要的话,删除那些完全没有必要成为管理员的人。<br />
<br />
但是如果你所在机构已经制定出与管理员资格有关的政策,应该如何实施这项功能?例如,假设已经规定普通用户不能成为管理员,而合格的管理员只能是本地管理员用户帐号和域管理员帐号(我们在此例中假设你工作于 fabrikam.com)。这种情况下,你所要求脚本做的不是返回多少个外部帐号,而是希望它能够删除那些外部帐号,只剩下 Administrator和fabrikam\Administrator 帐号。这才算够酷,不是吗?<br />
<br />
好吧,如果这真的是你所想的,为什么不承认呢?这段脚本列举出管理员组的所有成员。如果它发现某个既不是 Administrator 也不是 fabrikam\Administrator 帐号的话,就会使用删除方法从该组中删除此帐号。<br />
<br />
Set objNetwork = CreateObject("Wscript.Network")<br />
strComputer = objNetwork.ComputerName<br />
Set objGroup = GetObject("WinNT://" & strComputer &<br />
"/Administrators,group")<br />
For Each objUser in objGroup.Members<br />
If objUser.Name <> "Administrator" and objUser.Name <> _<br />
"fabrikam\Administrator" Then<br />
objGroup.Remove(objUser.ADsPath)<br />
End If<br />
Next<br />
<br />
对了:这就是如何使用脚本来增强 Security Analyzer 功能的典型例子。<br />
<br />
任务7:检查未过期密码<br />
<br />
如果说有什么东西用户会不喜欢的话,那么定时过期的密码肯定名列其中。毕竟,你还没有记住它时,它就已经需要更换了。那么,既然用户们这么憎恨定时过期密码的话,那么干嘛要用他们呢?(我们并不是指为了那些在想密码的时候倒在键盘和鼠标上的无数杯咖啡)。<br />
<br />
但是,事实是黑客们和用户们一样憎恨定时过期密码。设想一名黑客想要进行字典穷举攻击。他或者是她也许已经排除了aardvark是密码的可能,而这时候用户恰恰在攻击进行一半的时候将 aardvark更改为系统密码。即使黑客真的猜中了密码,那么这种胜利也是暂时的。也许正当黑客猜中密码的时候,用户马上就将其更改为其它的了。经常更改系统密码是有效提高安全性的途径之一,而经常更改密码最好的办法就是让密码经常过期。<br />
<br />
因为用不过期的密码会造成某种安全弱点,所以如果 Security Analyzer 发现任何帐户使用不过期密码的时候,它都会报告这一情况。也许你已经猜到了,我们恰巧也有一段相应的脚本来完成这个相同功能:<br />
<br />
Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000<br />
Set objNetwork = CreateObject("Wscript.Network")<br />
strComputer = objNetwork.ComputerName<br />
Set colAccounts = GetObject("WinNT://" & strComputer & "")<br />
colAccounts.Filter = Array("user")<br />
For Each objUser In colAccounts<br />
Set usr = GetObject("WinNT://" & strComputer & "/" & _<br />
objUser.Name & ", user")<br />
flag = usr.Get("UserFlags")<br />
If flag AND ADS_UF_DONT_EXPIRE_PASSWD Then<br />
Wscript.Echo usr.Name & ": Password does not expire."<br />
Else<br />
Wscript.Echo usr.Name & ": Password expires."<br />
End If<br />
Next<br />
<br />
而且你还以通过以下脚本将密码全部设置为过期密码:<br />
<br />
Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000<br />
Set objNetwork = CreateObject("Wscript.Network")<br />
strComputer = objNetwork.ComputerName<br />
Set colAccounts = GetObject("WinNT://" & strComputer & "")<br />
colAccounts.Filter = Array("user")<br />
For Each objUser In colAccounts<br />
Set usr = GetObject("WinNT://" & strComputer & "/" & _<br />
objUser.Name & ", user")<br />
flag = usr.Get("UserFlags")<br />
If flag AND ADS_UF_DONT_EXPIRE_PASSWD Then<br />
usr.UserFlags = flag XOR ADS_UF_DONT_EXPIRE_PASSWD<br />
usr.SetInfo<br />
End If<br />
Next<br />
<br />
任务8:进行本地帐户密码测试<br />
<br />
蠕虫和病毒得到大家的广泛关注,这个可以理解,但是某些时候真正造成计算机安全威胁的往往是那些最最简单的东西,比如说微不足道的留言便条。在办公室里,职员们经常在留言便条上记录密码,并且将它们贴在显示器上面。现在,你要禁止这种做法了,或者可以严惩那些乱贴这类留言条的家伙这种做法会导致另外一个问题(我们不是指使用走私的便条)。为什么人们会将他们的密码记录下来?因为这些密码太难记了。如果用户不可以记录这些密码,那么他们会倾向于使用他们无需记录就可以记下来的更加简单的密码——例如password。<br />
<br />
即使是一个业余黑客或者发泄不满的人使用密码password也可以侵入计算机。虽然 Security Analyzer 不能检测在显示器上是否有记录密码的便条,但是它却可以检查是否有本地用户帐号:<br />
<br />
&#8226; 使用空密码<br />
<br />
&#8226; 使用与用户名相同的密码<br />
<br />
&#8226; 使用与计算机名相同的密码<br />
<br />
&#8226; 使用password作为密码<br />
<br />
&#8226; 使用单词admin或administrator作为密码<br />
<br />
<br />
Security Analyzer 是如何进行这么酷的测试的?毕竟,它不可能检索用户的密码。不然的话这也成了一个安全突破口。好了,告诉你答案,事实上我们也不知道。但是我们怀疑它使用 ADSI ChangePassword 方法(或者某种相当的API)来测试并且修改用户密码。为什么是 ChangePassword ?因为使用这种方法时,如果你不知道当前用户的密码,就不可能顺利实现此项功能,你需要一起提供当前密码以及新密码来完成。因为 Security Analyzer 并没有真正修改密码,所以我们怀疑它只是简单的提供相同的密码(例如password)来同时作为当前密码和新密码,或者与之类似的情况:<br />
<br />
objUser.ChangePassword "password", "password"<br />
<br />
如果当前密码不是password,这个方法就行不通,系统就会报错。如果当前密码是password,这种方法就会成功,不会产生任何错误,然后密码会被改成password。当然,这一过程的净效果就是密码没有改变,但是系统现在知道当前的密码就是password。这听起来似乎有点混乱,但是先看看这段脚本,看看它到底做些什么。思路其实非常简单。<br />
<br />
而且,是的,这也是黑客可能进行的测试。我们现在是借用黑客方法来做正事。<br />
<br />
以下就是一段用来检测帐户是否使用的密码是否是password的脚本。这段脚本也可以做简单的修改来检测帐户使用的密码是不是空白的,或者使用登录名作为密码,或者其它。<br />
<br />
On Error Resume Next<br />
Set objNetwork = CreateObject("Wscript.Network")<br />
strComputer = objNetwork.ComputerName<br />
strPassword = "password"<br />
Set colAccounts = GetObject("WinNT://" & strComputer & "")<br />
colAccounts.Filter = Array("user")<br />
For Each objUser In colAccounts<br />
objUser.ChangePassword strPassword, strPassword<br />
If Err = 0 or Err = -2147023569 Then<br />
Wscript.Echo objUser.Name & " is using the password " & _<br />
strpassword & "."<br />
End If<br />
Err.Clear<br />
Next<br />
<br />
注意: 你可能注意到了,我们的脚本检测是否出现错误(Err=0);如果没有错误,就说明密码已经被改变,这就说明我们知道这个帐号的密码就是password。但是我们同样检测是否存在错误-2147023569。如果当前的密码是password但是这个密码不能被更改,因为自从上次密码更改以后还没有经过足够长的时间,那么就会产生上述这个错误。(根据默认设置,密码只有每14天才能被更改一次)。<br />
<br />
任务9:检测文件系统<br />
<br />
如果计算机运行的是 Windows NT、Windows 2000、Windows XP 或者 Windows 2003操作系统,那么将硬盘各个分区格式成NTFS文件系统是非常重要的。(或许会有很少的用户会例外,我们这里暂且不管了。)除非你喜欢将你的硬盘暴露给外界,否则你需要将硬盘格式成为 NTFS 格式,然后就可以享受 NTFS 安全机制了。同样这就好像是家庭的安全一样:除非你想其他人或者他们的狗能够自由出入你家,并且随意使用屋里的东西,否则你就应该在门上加锁,并且在你人不在的时候把锁锁上。<br />
<br />
那么你如何检测硬盘上安装的是什么文件系统呢?这里有一个非常简便的方法:<br />
<br />
strComputer = "."<br />
Set objWMIService = GetObject("winmgmts:\\" & strComputer &<br />
"\root\cimv2")<br />
Set colDisks = objWMIService.ExecQuery _<br />
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -