腳本故事

腳本故事 - 2003年11月
發佈者 The Scripting Guys
如果腳本是非法的,那麼只有非法者才使用腳本

如需獲得腳本專欄所有腳本故事的列表以及其他信息,請點擊此處。


Microsoft 的員工生活在虛幻的世界中,這是針對 Microsoft 員工的批評之一。意思是說我們這些 Microsoft 員工只是關注各種理想情況而對於系統管理員真正需要面對的實際問題卻從不考慮。這可能適用與某些 Microsoft 員工,但是至於我們對系統管理員所面臨的問題一無所知這種說法,Scripting Guys是有意見的。而且也有許多其他同仁同意我們的看法。例如,就在今天早上坐車來上班的路上,我們對司機說:“Bentley,你認爲Scripting Guys是生活在虛幻的世界中的嗎?是不是在系統管理員有需要的時候總是不能提供幫助?” “我不這樣認爲,”Bentley說,“絕對不是這樣的。”

畢竟我們認爲他是這麼說的。說實在話,由於坐在後排的 Jacuzzi 的說話聲音過大,我們聽得並不是很清楚。

不過,問題是,Scripting Guys也只不過是些平常人物罷了,和其他人並沒有什麼區別。把我們歸爲那類不食人間煙火的“傑出精英”有點誇張了。我們覺得我們在一個重要的領域可能的確不夠盡職:也許——注意,僅僅是也許——當系統管理員遇到安全問題時,我們沒有出色地完成自己的工作。

我們承認,讓Scripting Guys談論安全問題可能會讓你們聽起來有點好笑,因爲有好多人認爲如果沒有腳本程序那麼就不會有那麼多的安全問題。每當出現黑客攻擊或者破壞攻擊以及新的病毒或者蠕蟲病毒的時候,人們就會自然而然地將責備對號入座到腳本,然後擴大到我們這些從事與腳本有關的工作的人。他們會說,也許我們應該全面禁止腳本。也許, Microsoft 應該從操作系統中刪除 Windows Script Host,也應該永久禁止宏功能。而且,把Scripting Guys都投入監獄並扔掉鑰匙,讓他們再沒機會重見天日。(有趣的是,那些並不支持禁止腳本的人卻也極力支持後面這個處罰措施。)

此外,我們也不否認腳本編寫的確是某些上述攻擊中的途徑。是的,我們已經注意到了Kak.hta,我們也已經看到了 ILoveYou.vbs 病毒。(事實上,我們是最先遭受他們攻擊的人之一。就權當真的有那麼多人愛我們吧。)但是設想一下,如果我們真的放棄腳本編寫,情況會變成怎麼樣?這些瘋狂的舉動就會停止了嗎?

好吧,這的確是一個不錯的想法,可是通過買魔力球彩票贏取十億美元也是一個很不錯的想法,而且兩者發生的機率也是十分的相似(同爲0)。當然,蠕蟲和其他病毒的確可以寫成腳本,但是它們也同樣被寫成批處理文件,難道我們也要全面禁止批處理文件嗎?它們還被編寫成可執行文件,難道我們也要禁止在電腦中使用可執行文件嗎?將電腦中的可執行文件全部刪除,那麼你的電腦除了看起來有點酷之外,就毫無其它用處了。

嘿嘿,那樣我們豈不是發明了一臺 Macintosh!(致無處不在的 Macintosh 的愛好者:開玩笑而已。)

事實上,腳本編寫只不過是使蠕蟲以及其他病毒的編寫變得更加簡便,即使是這點還是值得商榷的(某些病毒是十分複雜的)。但是如果我們禁止使用腳本的話,病毒編寫者只需回覆從前的樣子用 C 或者 C++語言編寫即可。但是請記住,在病毒當道的今天,即使我們通過某種方法消除了所有病毒,計算機在處理的時候也並不是百分之百的安全。設想,如果一個連接到 Internet 的計算機用戶共享了他(她)的整個硬盤。在這種情況下,對計算機進行肆意破壞時甚至不需要任何腳本的幫助。設想將計算機設置成無論是誰打開機器都能登錄到操作系統的情況;某些人因爲貪圖方便將密碼設置過於簡單的情況以及其他你能想象的到的一些不安全設置。

這個問題的實質在於:只要我們使用電腦,那麼一些不好的事情就有可能發生。這和生活中的所有事情都是一樣的。比如讓人們開車,就會有人會闖紅燈或者倒車時撞上路旁的信箱。對於這些意外我們無能爲力。我們所能做的就是教會人們怎樣安全行車,並且提供安全帶、安全氣囊以及其他一些能夠降低人們出事故時造成損害的安全設施。

這就是我們欄目今天所要傳遞給大家的信息。我們是否能夠讓人們停止傳播病毒?我們是否能夠讓人們再不要將自己的計算機暴露於他人的潛在攻擊下?我們是否能夠保證計算機進行計算時百分之百的安全,消除一切出錯的機會?不,我們做不到。至少在沒有拔掉所有網絡適配器、斷開所有 Internet 連接以及徹底隔離各個計算機用戶之前,我們是無法做到的。(致所有系統管理員:我們知道這聽起來很誘人,但是這並不是Scripting Guy的正式建議。)不過,我們還是能夠做些事情來幫助改善系統脆弱性的,防患於未然。腳本能夠讓我們的計算機變得更加安全,雖然這聽起來似乎有點瘋狂。(是的,我們說的的確是更加安全。請相信我們。)



本頁內容
知識就是力量
最後的思考

知識就是力量
好了,好了:站在走廊上往下看,看那些手中掌握實權的傢伙們。我們有時很難理解,他們的權利到底和他們所掌握的知識有什麼聯繫。雖然事實如此,但是儘量多地掌握你所能得到的知識和信息畢竟不是一件壞事,這對於計算機安全這個問題尤其正確。你對於你的計算機以及它的設置知道得越清楚,那麼你也就越有信心。這就是爲什麼計算機安全專家們建議大家對自己的計算機進行階段性安全檢查的原因。那麼現在就剩一個問題:如何正確地進行這項階段性安全檢查?

事實上, Microsoft 已經發布了一款小巧實用的工具——Microsoft Baseline Security Analyzer——它能夠幫助你完成這項安全檢查。(我希望你已經下載了這個免費的小工具,如果還沒有,請點擊此處下載。)這款小工具的功能如其名稱所示:它能夠對一臺計算機(如果你願意,也可以是多臺)進行分析,指出潛在的安全隱患,例如沒有安裝的安全補丁或者密碼設置過於簡單(甚至完全沒有密碼)的本地帳戶。此軟件個頭雖小但卻非常有用,無論是在家裏還是辦公室它都是必備軟件。

當然,現在你也許在想:“好吧,既然 Security Analyzer 這麼好用,我決定將它送給老媽作爲聖誕禮物算了。但是這和腳本有什麼關係呢?如果 Security Analyzer 能夠提供我需要的一切,那我還要腳本幹什麼?Scripting Guys,我說的對嗎?”

事實上,你說的很對:如果 Security Analyzer 能夠做你所需要的一切,那麼完全不必再使用腳本了。(或許你也並不是很需要那些救生圈,爲什麼不寄給 Scripting Guys,讓我們來照顧它好了。)但是如果 Security Analyzer 並不能做你所需要的所有事情的時候怎麼辦?雖然 Security Analyzer 在收集信息方面做得很不錯,但是畢竟它不能夠對所收集到的信息做出任何反應。例如,它能夠檢測所有 5000 臺工作站計算機的情況,並針對每臺機子上的來賓帳戶是否已經關閉做出詳細報告(絕大多數機構都選擇關閉來賓帳戶以避免匿名或者沒有授權的用戶登錄網絡)。假設你的網絡中有 2967 臺計算機的來賓帳戶沒有關閉,那麼 Security Analyzer 會將這一情況報告給你,但是最後還是需要你自己對每臺機器進行處理,手動關閉這些機器上的來賓帳戶。

後者就是腳本的用武之地。假如你想知道計算機上的來賓帳戶是否已經關閉,你可以寫一段腳本來完成上述過程,但是如果你只是想要檢查一下這個帳戶的狀態的話,有什麼意義?畢竟 Security Analyzer 就能夠幫你檢查帳戶的狀態,你完全沒有必要寫腳本。但是如果你想要做的不僅僅是檢查一下帳戶的狀態而是想把打開的帳戶全部關閉呢?單單靠 Security Analyzer 是不能完成上述兩步的,但是你可以通過編寫腳本來完成。

這也就是我們想在這裏指出的。(如果你讀過ADSI Scriptomatic Readme也許覺得很難相信,但是 Scripting Guys 實際上做的還是有點道理的)。腳本是一個很有用的工具,因爲它可以幫助你得到與安全性相關的信息,但是它之所以成爲必不可少的工具,其原因在於它可以對收集到的信息進行處理。這就是我們所要展示的:我們將向你展示 Security Analyzer 檢索的信息,我們也想你展示如何通過編寫能夠檢索同樣信息的腳本。然後,在可能的時候,我們向你展示如何通過修改腳本來使它能夠對檢索的信息進行處理。

完全公佈。好了,我們可能說的稍微有點誇張了:考慮到篇幅的原因,我們並不打算在此介紹 Security Analyzer 的所有功能。所以,我們會跳過中間的某些步驟,比如校驗 SQL 服務器的帳戶密碼。希望你沒有什麼意見;Bentley 說他沒問題。

順便說一句,我們可能會在以後的專欄中更加深入地探討與安全有關的話題。例如,我們會解釋(或者至少試着解釋)安全標識符奇怪而神祕的世界以及如何通過腳本來控制它。我們也會向你展示腳本在管理補丁程序和安全補丁方面發揮的作用。但是現在我們暫且先把這些內容擱置一旁。現在,就讓我們不受任何打擾,開始講解 Security Analyzer 能做什麼以及如何通過腳本來實現相同的功能。

注意: 再打擾一下。爲了使我們的腳本片段儘可能短,你在這裏看到的腳本都是針對單機(本地單機)的。Security Analyzer 的實力在於它可以針對多機使用。腳本是否也能夠做到呢?你猜猜看;有關更多詳細信息請參閱前一期腳本故事專欄。擦亮你的眼睛,看看 Runomatic 是如何貼到腳本中心的。

什麼是 Runomatic?你不想我們來破壞你自己找到答案時的那種驚奇感,是吧?

任務1:檢索計算機名

老實告訴你吧,通過腳本來檢索計算機名的途徑數不勝數。但是因爲 WMI 將要成爲檢索信息的主流技術,所以我們所展示的是一段返回目標計算機名稱的 WMI 腳本。

strComputer = "."
Set objWMIService = GetObject("winmgmts:/" & strComputer & "/root/cimv2")
Set colComputers = objWMIService.ExecQuery _
    ("Select * from Win32_ComputerSystem")
For Each objComputer in colComputers
    Wscript.Echo objComputer.Name
Next

這看起來似乎有點可笑,尤其是這段腳本只是針對單機運行的時候。但是當它的目標計算機有 100 臺的時候,它能夠幫助我們將各臺計算機區分開來。

任務2:檢索 IP 地址

通過腳本實現 IP 地址檢索同樣非常簡單:

strComputer = "."
Set objWMIService = GetObject("winmgmts:/" & strComputer & "/root/cimv2")
Set IPConfigSet = objWMIService.ExecQuery _
    ("Select IPAddress from Win32_NetworkAdapterConfiguration " _
        "Where IPEnabled=TRUE")
For Each IPConfig in IPConfigSet
    If Not IsNull(IPConfig.IPAddress) Then
        For Each strAddress in IPConfig.IPAddress
            WScript.Echo strAddress
        Next
    End If
Next

在判定一臺計算機的 IP 地址時,只要注意兩點。第一,WMI 將包括 VPN 和 RAS 連接在內的所有東西都認爲是計算機網絡適配器設置的一部分,爲此,我們需要使用 WHERE 語句Where IPEnabled = TRUE來將返回的信息限定爲實際網絡適配器的信息。

第二,IP 地址通常以數組的形式返回,因此我們需要用一個 For-Each 循環來獲得真正的 IP 地址。如果我們直接回應 IP 地址屬性值的話,將會發生“類匹配”錯誤。

任務3:報告安全檢查進行的日期和時間

實現這個功能也是非常的容易,但是鑑於我們複製絕大多數 Security Analyzer 的功能,下面是一行返回日期和時間的代碼:

Wscript.Echo Now

你們有人不是覺得腳本是非常高深的嗎!其實就這麼簡單。

任務4:檢查升級包

好的,我們承認:從來就沒有誰發佈過完美的操作系統。(嗯,如果任何來自 Microsoft 的人這麼問,我們可是不會這麼說的。明白嗎?)在操作系統發佈後,總是會找到各種缺陷。不幸的是,我們同時也會找到各種安全漏洞和易遭受攻擊的薄弱處。沒有人喜歡發現缺陷這個事實,但是生活就是這個樣子。沒有人願意切到自己的手指,但是萬一你真的切了自己的手指,你不會坐以待斃,你肯定會翻出急救包然後給傷口上繃帶。同樣,如果一個操作系統需要類似的措施時,你應該翻出急救箱給系統裝好升級包。

換句話說,你最好保證你的計算機安裝了最新的系統補丁。Security Analyzer 就能夠向你提供有關這方面的信息,而通過下面的腳本也同樣能夠做到:

strComputer = "."
Set objWMIService = GetObject("winmgmts:/" & strComputer &
"/root/cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
    ("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
    Wscript.Echo objOperatingSystem.ServicePackMajorVersion  _
        & "." & objOperatingSystem.ServicePackMinorVersion
Next

在你開始提問之前,首先申明一點:WMI不會顯示你所安裝的所有升級包的信息,它只會告訴你安裝的最新的升級包情況。但是這個應該不成問題,因爲最新的升級包都包含了以前版本中的修補程序和升級程序。如果你在 WINDOWS 2000 中安裝了 Service Pack 4,那麼你安裝的不僅僅是 Service Pack 4 中所增加的內容,它也包含了 Service Pack 1、2 和 3 中的所有內容。或者說,只要你知道自己的計算機已經安裝了 Service Pack 4,你就沒有必要擔心你的計算機是否已經安裝了Service Pack 1、2 或 3。事實上,它們肯定已經全部安裝了。

任務五:檢查 Hot Fix

你知道有關最近幾次病毒以及蠕蟲攻擊的真正悲哀的地方在哪裏嗎?其實很多補丁已經提供很久了,如果用戶能夠使用的話,就能夠避免計算機遭受攻擊。但是出於多種原因,人們就是沒有使用這些補丁,直到病毒找上門來,後果我不說大家也知道了。我說這些是什麼意思?確保自己有最新的補丁和熱修補程序(有關如何操作的更多信息請點擊此處),並且確保自己的計算機安裝了必需的修補程序。

但是你怎麼知道機器上裝了哪些熱修補程序呢?你問的真是好笑:

strComputer = "."
Set objWMIService = GetObject("winmgmts:/" & strComputer &
"/root/cimv2")
Set colQuickFixes = objWMIService.ExecQuery _
    ("Select * from Win32_QuickFixEngineering")
For Each objQuickFix in colQuickFixes
    Wscript.Echo "Description: " & objQuickFix.Description
    Wscript.Echo "Hot Fix ID: " & objQuickFix.HotFixID
Next

注意: 如果你使用的是 WINDOWS 2000 操作系統,有些計算機在進入Win32_QuickEngineering 類的時候可能會發生死機現象。有關此已知問題的更多信息以及如何修復,請點擊這裏。

這段腳本可以很好的工作,但是老實說,和 Security Analyzer 比起來還是要遜色一點。因爲 Security Analyzer的確有些不俗的表現:它不僅僅告訴你哪些熱修補已經安裝了,還顯示哪些沒有安裝。換句話說,如果沒有安裝某些必須的補丁的話,它會提示你。

那麼 Security Analyzer 如何分辨哪些必須安裝哪些不必呢?當你運行 Security Analyzer 時,它會參考一個文件(Mssecure.xml),該文件包含一個重要補丁列表以及哪些計算機(不同版本的 WINDOWS)需要哪些補丁的信息。

編寫 Mssecure.xml 文件超出了本專欄的範圍(雖然對於掌握 XML 知識的人來說這並非不可能)。但是,在以後的專欄中,我們將展示一些你也可以執行鍼對特定熱修補 和補丁的類似方法。

任務六:檢查本地管理員數目

人多手腳亂,太多的管理員同樣也會壞了好事。更加重要的是,有更多的管理員意味着某人(管理員)犯某種錯誤從而將計算機暴露與他人攻擊之下的可能性也大大增加。你也許會給你的鄰居一把備用鑰匙,好讓他在你不在的時候更好的照看你的東西。但是你不會將你的備用鑰匙分發給公共汽車上遇到的每個人。(我們暫且假設你不會這麼做)同理,所以你會限制本地管理員的數量,因爲從定義上來說,他們可以做許多超出你期望範圍以外的事。

同 Security Analyzer 一樣,腳本也能夠返回計算機上本地管理員組的所有成員。事實上,下面這段代碼就是完成這項功能的:

Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
Set objGroup = GetObject("WinNT://" & strComputer &
"/Administrators,group")
For Each objUser in objGroup.Members
    Wscript.Echo objUser.Name
Next

這些材料是非常有用的;無任什麼時候,只要你有時間(假設你能夠抽出時間),你可以仔細研究這份名單,必要的話,刪除那些完全沒有必要成爲管理員的人。

但是如果你所在機構已經制定出與管理員資格有關的政策,應該如何實施這項功能?例如,假設已經規定普通用戶不能成爲管理員,而合格的管理員只能是本地管理員用戶帳號和域管理員帳號(我們在此例中假設你工作於 fabrikam.com)。這種情況下,你所要求腳本做的不是返回多少個外部帳號,而是希望它能夠刪除那些外部帳號,只剩下 Administrator和fabrikam/Administrator 帳號。這纔算夠酷,不是嗎?

好吧,如果這真的是你所想的,爲什麼不承認呢?這段腳本列舉出管理員組的所有成員。如果它發現某個既不是 Administrator 也不是 fabrikam/Administrator 帳號的話,就會使用刪除方法從該組中刪除此帳號。

Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
Set objGroup = GetObject("WinNT://" & strComputer &
"/Administrators,group")
For Each objUser in objGroup.Members
    If objUser.Name <> "Administrator" and objUser.Name <> _
        "fabrikam/Administrator" Then
        objGroup.Remove(objUser.ADsPath)
    End If
Next

對了:這就是如何使用腳本來增強 Security Analyzer 功能的典型例子。

任務7:檢查未過期密碼

如果說有什麼東西用戶會不喜歡的話,那麼定時過期的密碼肯定名列其中。畢竟,你還沒有記住它時,它就已經需要更換了。那麼,既然用戶們這麼憎恨定時過期密碼的話,那麼幹嘛要用他們呢?(我們並不是指爲了那些在想密碼的時候倒在鍵盤和鼠標上的無數杯咖啡)。

但是,事實是黑客們和用戶們一樣憎恨定時過期密碼。設想一名黑客想要進行字典窮舉攻擊。他或者是她也許已經排除了aardvark是密碼的可能,而這時候用戶恰恰在攻擊進行一半的時候將 aardvark更改爲系統密碼。即使黑客真的猜中了密碼,那麼這種勝利也是暫時的。也許正當黑客猜中密碼的時候,用戶馬上就將其更改爲其它的了。經常更改系統密碼是有效提高安全性的途徑之一,而經常更改密碼最好的辦法就是讓密碼經常過期。

因爲用不過期的密碼會造成某種安全弱點,所以如果 Security Analyzer 發現任何帳戶使用不過期密碼的時候,它都會報告這一情況。也許你已經猜到了,我們恰巧也有一段相應的腳本來完成這個相同功能:

Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000
Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
Set colAccounts = GetObject("WinNT://" & strComputer & "")
colAccounts.Filter = Array("user")
For Each objUser In colAccounts
    Set usr = GetObject("WinNT://" & strComputer & "/" & _
        objUser.Name & ", user")
    flag = usr.Get("UserFlags")
    If flag AND ADS_UF_DONT_EXPIRE_PASSWD Then
        Wscript.Echo usr.Name & ": Password does not expire."
    Else
        Wscript.Echo usr.Name & ": Password expires."
    End If
Next

而且你還以通過以下腳本將密碼全部設置爲過期密碼:

Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000
Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
Set colAccounts = GetObject("WinNT://" & strComputer & "")
colAccounts.Filter = Array("user")
For Each objUser In colAccounts
    Set usr = GetObject("WinNT://" & strComputer & "/" & _
        objUser.Name & ", user")
    flag = usr.Get("UserFlags")
    If flag AND ADS_UF_DONT_EXPIRE_PASSWD Then
        usr.UserFlags = flag XOR ADS_UF_DONT_EXPIRE_PASSWD
        usr.SetInfo
    End If
Next

任務8:進行本地帳戶密碼測試

蠕蟲和病毒得到大家的廣泛關注,這個可以理解,但是某些時候真正造成計算機安全威脅的往往是那些最最簡單的東西,比如說微不足道的留言便條。在辦公室裏,職員們經常在留言便條上記錄密碼,並且將它們貼在顯示器上面。現在,你要禁止這種做法了,或者可以嚴懲那些亂貼這類留言條的傢伙這種做法會導致另外一個問題(我們不是指使用走私的便條)。爲什麼人們會將他們的密碼記錄下來?因爲這些密碼太難記了。如果用戶不可以記錄這些密碼,那麼他們會傾向於使用他們無需記錄就可以記下來的更加簡單的密碼——例如password。

即使是一個業餘黑客或者發泄不滿的人使用密碼password也可以侵入計算機。雖然 Security Analyzer 不能檢測在顯示器上是否有記錄密碼的便條,但是它卻可以檢查是否有本地用戶帳號:

&#8226; 使用空密碼

&#8226; 使用與用戶名相同的密碼

&#8226; 使用與計算機名相同的密碼

&#8226; 使用password作爲密碼

&#8226; 使用單詞admin或administrator作爲密碼


Security Analyzer 是如何進行這麼酷的測試的?畢竟,它不可能檢索用戶的密碼。不然的話這也成了一個安全突破口。好了,告訴你答案,事實上我們也不知道。但是我們懷疑它使用 ADSI ChangePassword 方法(或者某種相當的API)來測試並且修改用戶密碼。爲什麼是 ChangePassword ?因爲使用這種方法時,如果你不知道當前用戶的密碼,就不可能順利實現此項功能,你需要一起提供當前密碼以及新密碼來完成。因爲 Security Analyzer 並沒有真正修改密碼,所以我們懷疑它只是簡單的提供相同的密碼(例如password)來同時作爲當前密碼和新密碼,或者與之類似的情況:

objUser.ChangePassword "password", "password"

如果當前密碼不是password,這個方法就行不通,系統就會報錯。如果當前密碼是password,這種方法就會成功,不會產生任何錯誤,然後密碼會被改成password。當然,這一過程的淨效果就是密碼沒有改變,但是系統現在知道當前的密碼就是password。這聽起來似乎有點混亂,但是先看看這段腳本,看看它到底做些什麼。思路其實非常簡單。

而且,是的,這也是黑客可能進行的測試。我們現在是借用黑客方法來做正事。

以下就是一段用來檢測帳戶是否使用的密碼是否是password的腳本。這段腳本也可以做簡單的修改來檢測帳戶使用的密碼是不是空白的,或者使用登錄名作爲密碼,或者其它。

On Error Resume Next
Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
strPassword = "password"
Set colAccounts = GetObject("WinNT://" & strComputer & "")
colAccounts.Filter = Array("user")
For Each objUser In colAccounts
    objUser.ChangePassword strPassword, strPassword
    If Err = 0 or Err = -2147023569 Then
        Wscript.Echo objUser.Name & " is using the password " & _
            strpassword & "."
    End If
    Err.Clear
Next

注意: 你可能注意到了,我們的腳本檢測是否出現錯誤(Err=0);如果沒有錯誤,就說明密碼已經被改變,這就說明我們知道這個帳號的密碼就是password。但是我們同樣檢測是否存在錯誤-2147023569。如果當前的密碼是password但是這個密碼不能被更改,因爲自從上次密碼更改以後還沒有經過足夠長的時間,那麼就會產生上述這個錯誤。(根據默認設置,密碼只有每14天才能被更改一次)。

任務9:檢測文件系統

如果計算機運行的是 Windows NT、Windows 2000、Windows XP 或者 Windows 2003操作系統,那麼將硬盤各個分區格式成NTFS文件系統是非常重要的。(或許會有很少的用戶會例外,我們這裏暫且不管了。)除非你喜歡將你的硬盤暴露給外界,否則你需要將硬盤格式成爲 NTFS 格式,然後就可以享受 NTFS 安全機制了。同樣這就好像是家庭的安全一樣:除非你想其他人或者他們的狗能夠自由出入你家,並且隨意使用屋裏的東西,否則你就應該在門上加鎖,並且在你人不在的時候把鎖鎖上。

那麼你如何檢測硬盤上安裝的是什麼文件系統呢?這裏有一個非常簡便的方法:

strComputer = "."
Set objWMIService = GetObject("winmgmts:/" & strComputer &
"/root/cimv2")
Set colDisks = objWMIService.ExecQuery _
    ("Select * from Win32_LogicalDisk Where DriveType = 3")
For Each objDisk in colDisks
    Wscript.Echo "Disk drive: "& objDisk.DeviceID & " -- " & objDisk.FileSystem
Next

在前述 WQL 查詢中,你可能已經發現我們只是查詢 DriveType 等於 3 的邏輯盤。爲什麼這麼做?因爲 DriveType 等於 3 代表的是硬盤,通過將返回數據限定在硬盤上,可以省去我們在軟盤、CD-ROM 驅動器以及其它我們知道不會(也不可能)安裝 NTFS 文件系統的驅動器上花費的時間。

任務10:檢測自動登錄

可以將 Windows 設置成每當開機就自動使用註冊的用戶名和密碼登錄。這聽起來很方便,但是的確不適用於那些始終與 Internet 保持連接或者在信息亭中使用的計算機。但是,從另一方面來說,這卻有點安全漏洞的嫌疑,至少可以這樣說。畢竟它允許任何打開計算機的人以儲存在註冊表中的用戶名和密碼登錄。正因爲如此,Security Analyzer 所執行的一項檢查就是查看計算機的自動登錄功能是否打開。同樣,你也可以使用腳本來完成這項檢查:

Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set objReg=GetObject("winmgmts:/" & strComputer &
"/root/default:StdRegProv")
strKeyPath = "Software/Microsoft/Windows NT/CurrentVersion/WinLogon"
strValueName = "AutoAdminLogon"
objReg.GetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName,
dwValue
If dwValue = 1 Then
    Wscript.Echo "Auto logon is enabled."
Else
    Wscript.Echo "Auto logon is disabled."
End If

同樣,你肯定不希望計算機上的自動登錄打開。所以,爲什麼不用一段腳本來關閉自動登錄功能而不是像 Security Analyzer 那樣僅僅只是提示自動登錄功能的狀態呢。可以使用類似以下的腳本:

Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set objReg=GetObject("winmgmts:/" & strComputer &
"/root/default:StdRegProv")
strKeyPath = "Software/Microsoft/Windows NT/CurrentVersion/WinLogon"
strValueName = "AutoAdminLogon"
dwValue = 0
oReg.SetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName,
dwValue

任務11:檢查來賓帳戶狀態

這個問題取決於你如何看待,來賓帳戶在不需要證實身份的情況下向他人提供了一種登錄你的計算機的途徑(我們假設唯一的例外就是,此 Guest 不是指 Christopher Guest)。正因爲如此,在 Windows XP 和 Windows 2003 中來賓帳戶在默認條件下是關閉的,而且在 Windows 2000 和 Windows NT 4.0 中同樣也應該是關閉的。這是一段報告本地計算機上來賓帳戶狀態的腳本:

Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
Set objUser = GetObject("WinNT://" & strComputer & "/Guest")
If objUser.AccountDisabled Then
    Wscript.Echo "The Guest account is disabled."
Else
    Wscript.Echo "The Guest account is enabled."
End If

看,酷吧。但是假設你決定所有計算機上的來賓帳戶都應該關閉。可以修改這段腳本來讓它在檢查來賓帳戶以外多做一兩件其它的事。如果來賓帳戶已經關閉,那麼它只需要報告狀態事實;但是如果來賓帳戶開啓的話,它進一步關閉此帳戶:

Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
Set objUser = GetObject("WinNT://" & strComputer & "/Guest")
If objUser.AccountDisabled Then
    Wscript.Echo "The Guest account is already disabled."
Else
    objUser.AccountDisabled = True
    objUser.SetInfo
    Wscript.Echo "The Guest account has been disabled."
End If

任務12:檢查匿名登錄

在默認設置下,非授權用戶是無法連接到任何 Windows 計算機以獲得域用戶名和共享名列表的。這是什麼意思?好的,黑客以你的身份登錄需要兩條信息:你的用戶名和你的密碼。他可以簡單地通過將便攜式電腦接駁到你所在的網絡然後向最近的計算機查詢就可以獲取你的用戶名,這樣就獲得了攻擊帳戶所需信息的一半。(謝天謝地,還沒有人發明無線的 Internet 便條,雖然我們知道有人正在鑽研這一技術。)

那麼你如何知道自己的計算機是否正在象分發萬聖節糖果那樣發送信息呢?你可以用 Security Analyzer 或者你也可以使用下面這段腳本:

Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set objReg=GetObject("winmgmts:/" & strComputer &
"/root/default:StdRegProv")
strKeyPath = "System/CurrentControlSet/Control/Lsa"
strValueName = "RestrictAnonymous"
objReg.GetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue
If dwValue = 0 Then
    Wscript.Echo "Anonymous access is enabled."
Else
    Wscript.Echo "Anonymous access is disabled."
End If

你這樣問很有趣;通過腳本有一種方法可以關閉計算機上的匿名登錄:

Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set objReg=GetObject("winmgmts:/" & strComputer &
"/root/default:StdRegProv")
strKeyPath = "System/CurrentControlSet/Control/Lsa"
strValueName = "RestrictAnonymous"
dwValue = 1
oReg.SetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName,
dwValue

任務13:列出安裝的服務

知道計算機上正在運行什麼服務很有用。畢竟,有些陰險的病毒會將自己僞裝成服務的形式,所以你必須知道是否有這種病毒正在你的計算機上運行。但是查看合法服務是否在一臺計算機上運行也很有用處。對了,我們知道你告訴過你的用戶不要在他們的機子上運行網站服務器或者 FTP 服務器,但是你如何知道他們是否聽話呢?以下這段腳本會告訴你:

strComputer = "."
Set objWMIService = GetObject("winmgmts:/" & strComputer &
"/root/cimv2")
Set colRunningServices = objWMIService.ExecQuery _
    ("Select * from Win32_Service")
For Each objService in colRunningServices
    Wscript.Echo objService.DisplayName, objService.State
Next

那麼假如你發現有人運行了你不希望運行的服務時怎麼辦呢?我們可以從停止通用即插即用設備主機服務的腳本上得到啓發(停止它們):

strComputer = "."
Set objWMIService = GetObject("winmgmts:/" & strComputer &
"/root/cimv2")
Set colRunningServices = objWMIService.ExecQuery _
    ("Select * from Win32_Service Where Name = 'upnhost'")
For Each objService in colRunningServices
    objService.StopService()
Next

任務14:檢查共享文件以及共享權限

難道你不知道嗎:在你整個生命過程中,你都被告知和他人進行分享是多麼的重要,但是現在我們發現共享(至少從計算機角度來說)事實上並不一定是件好事。

共享文件的功能絕對是利弊兼備的。文件共享能夠讓用戶們在不用管理員幫忙以及不佔用文件服務器儲存空間的情況下就某個工作開展協作。但是,不幸的是,它同樣允許人們將一些不應該共享的文件共享(例如侵權的 MP3 文件)。另外,網絡共享提供了進入計算機的便捷通道。如果你共享了一個文件夾而沒有正確地設置共享權限,那麼……。

那麼腳本是否能提示你計算機上是否有共享文件呢?你猜猜看:

strComputer = "."
Set objWMIService = GetObject("winmgmts:/" & strComputer &
"/root/cimv2")
Set colShares = objWMIService.ExecQuery("Select * from Win32_Share")
For each objShare in colShares
    Wscript.Echo "Name: " & objShare.Name
    Wscript.Echo "Path: " & objShare.Path
    Wscript.Echo "Type: " & objShare.Type
Next

當然,許多機構都會選擇徹底不共享文件,至少在客戶端機器上是這樣的。如果你也做了同樣的決定,那麼你就會發現腳本在這個問題上會很有用。Security Analyzer 會告訴你是否在計算機上找到了共享文件;但是,最後還是需要你連接到各臺計算機上取消各個共享文件。而腳本不僅僅會識別出共享的文件夾,它還能夠同時取消這些文件夾的共享。例如,這裏有一段能夠取消所有類型爲 0 的文件共享(我們稍後就會解釋這一點):

strComputer = "."
Set objWMIService = GetObject("winmgmts:/" & strComputer &
"/root/cimv2")
Set colShares = objWMIService.ExecQuery _
    ("Select * from Win32_Share Where Type = 0")
For each objShare in colShares
    objShare.Delete
Next

注意: 別慌,雖然這個方法叫做刪除,但是它只是刪除共享功能(也就是說,它只是停止在網絡上共享這個文件夾而已)。雖然我們認爲完全刪除它們也是禁止在網絡上共享它們的一條途徑,但是它不會正真刪除文件夾或者文件夾中的任何內容。

那麼爲什麼是類型爲 0 的文件呢?在 WMI 中,一個類型爲 0 的共享文件代表的是一個普通的舊的共享文件。當然還有其它的共享文件,最常見的就是管理級共享文件(如C$)。前述腳本能夠在分別保留其它共享文件(如管理級共享文件)的同時,停止共享普通文件夾。如果你要停止所有的共享文件,你只要不將 Where 語句包含在查詢語句裏即可:

Set colShares = objWMIService.ExecQuery("Select * from Win32_Share")

注意: 那麼共享權限呢?如上文說到的,我們將會在以後的專欄中討論。

任務15:檢查 Windows 版本

安裝了 Service Pack 1 意味着什麼?如果你運行的是 Windows XP,那麼說明你緊跟時代步伐,但是如果你使用的是 Windows 2000 的話,就說明你已經落伍了。(Windows 2000現在已經發展到 Service Pack 4 了)。這說明,如果你不知道計算機運行的是什麼 Windows 版本的話,腳本返回的某些信息是沒有意義的。這裏就有一段腳本說明這一點:

strComputer = "."
Set objWMIService = GetObject("winmgmts:/" & strComputer &
"/root/cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
    ("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
    Wscript.Echo objOperatingSystem.Caption, objOperatingSystem.Version
Next

任務16:檢查 Office 宏的安全性

Microsoft Office 讓用戶自己決定如何運行嵌入文件中的宏。你可以選擇:

&#8226; 高。只允許運行來自受信任來源的宏。所有其它經過簽署的和未經簽署的宏都將被禁用。

&#8226; 中。你可以選擇是否運行可能不安全的宏。

&#8226; 低。允許運行所有宏。


在將宏安全性設置爲高的情況下,你可以在其它時間中阻止自動運行的宏(當你打開一個文檔或者運行某個程序的時候自動運行的那些宏)對你的計算機做些不好的事情。毫無疑問,一開始就將 Office 設置成爲高安全性是個不錯的主意,如果能夠經常檢查高安全性是否還在運行將會更好。

檢查宏安全性級別可能會有點靈活,因爲指向你所要更改的註冊值可能會因爲你安裝的 Office 版本的不同而相差很大。我們沒有精力來討論如何判斷 Office 的版本(提示:使用 WMI 組的Win32_Product)然後決定合適的註冊表路徑,但是至少這裏有一段能夠從 Outlook 2000 中檢索出宏安全級別的腳本。你應該能夠輕易地根據你的需要和所安裝的 Office 版本來改進這段腳本:

Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
Set objReg=GetObject("winmgmts:/" & strComputer &
"/root/default:StdRegProv")
strKeyPath = "Software/Microsoft/Office.0/Outlook/Security"
strValueName = "Level"
objReg.GetDWORDValue HKEY_CURRENT_USER, strKeyPath, strValueName,
dwValue
If dwValue = 3 Then
    Wscript.Echo "Outlook macro security is set to high."
ElseIf dwValue = 2 Then
    Wscript.Echo "Outlook macro security is set to medium."
Else
    Wscript.Echo "Outlook macro security is set to low."
End If    

上述這段腳本是用來檢測 Outlook 的宏安全性級別的。那麼,如果你想要檢測 Word、Excel、PowerPoint 或者 Access的宏安全級別的時候該怎麼辦?好吧,你只需要根據需要更改註冊表路徑即可:

strKeyPath = "Software/Microsoft/Office.0/Word/Security"
strKeyPath = "Software/Microsoft/Office.0/Excel/Security"
strKeyPath = "Software/Microsoft/Office.0/PowerPoint/Security"
strKeyPath = "Software/Microsoft/Office.0/Access/Security"

任務17:檢查 IE 安全區域

爲了保護用戶不受惡意網站的攻擊,Internet Explorer 使用安全區域來管理在你訪問某個網站時可能完成或無法完成的行爲(比如運行腳本、安裝 ActiveX 控件等等)。在默認設置下,這些安全區域提供不同的安全級別:你可以在本地內部網絡區域執行在受限網站區域中不能執行的程序(比如運行腳本)。

如果你想要了解更多有關安全區域的情況,我們建議你閱讀Internet Explorer 增強安全性設置白皮書(此白皮書是針對 Windows 2003 編寫的,但是其中的內容對於其它 Windows 版本同樣適用。)在這裏,我們有一段能夠報告本地內部網絡區域(區域1)安全級別的腳本:

Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
Set objReg=GetObject("winmgmts:/" & strComputer &
"/root/default:StdRegProv")
strKeyPath = "Software/Microsoft/Windows/CurrentVersion/Internet
Settings/Zones"
strValueName = "CurrentLevel"
objReg.GetDWORDValue HKEY_CURRENT_USER,strKeyPath,strValueName,dwValue
Select Case dwValue
    Case 73728
        Wscript.Echo "The security zone is set to high security."
    Case 69632
        Wscript.Echo "The security zone is set to medium security."
    Case 66816
        Wscript.Echo "The security zone is set to medium-low security."
    Case 65536
        Wscript.Echo "The security zone is set to low security."
    Case Else
        Wscript.Echo "The security zone is set to custom security."
End Select

你也可以通過此段腳本檢索有關受信任站點(區域2)、Internet(區域3)以及受限制站點(區域4)的安全信息。只需要相應更改註冊表路徑:

Software/Microsoft/Windows/CurrentVersion/Internet Settings/Zones
Software/Microsoft/Windows/CurrentVersion/Internet Settings/Zones
Software/Microsoft/Windows/CurrentVersion/Internet Settings/Zones

在絕大多數情況下,這個方法能夠向你提供所需的信息。唯一會碰到的問題是用戶是否已經更改了安全區域的一項或者多項設置。在那樣的情況下,安全級別將會被報告爲"用戶自定義",但是你就無從知道這個新的用戶自定義的安全級別是比原來的默認級別更加嚴格還是更加寬鬆。這也就是腳本再次派上用場的地方:你可以使用一段腳本來決定(或者配置)各個安全區域的安全設置。有關這方面的更多信息,請參閱Internet Explorer 增強安全性設置白皮書或者擦亮你的眼睛看看 Tweakomatic。(不,這不是拼寫錯誤。我們真的將要發佈一款名叫Tweakomatic的東西。你一定要相信我們遲早會這麼做的。)

任務18:檢查 Outlook 安全區域

Microsoft Outlook 同樣使用 Internet Explorer 的安全區域來決定是否運行來自於 HTML 格式信息的腳本和活動內容。要避免在計算機上運行嵌入了 HTML 信息的腳本,你需要做兩件事情:

&#8226; 確保在 Internet Explorer 安全區域內運行腳本的功能已經被禁用(特別是在受限制的站點區域內)。

&#8226; 確保 Outlook 使用那個安全區域


Outlook 安全區域記錄在註冊表中;同樣,指向那個註冊表值的確切路徑取決於你在計算機上安裝的 Office 版本。如果你使用 Office 2000,你可以使用以下腳本來決定 Outlook 的安全區域:

Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
Set objReg=GetObject("winmgmts:/" & strComputer &
"/root/default:StdRegProv")
strKeyPath = "Software/Microsoft/Office.0/Outlook/Options/General"
strValueName = "Security Zone"
objReg.GetDWORDValue HKEY_CURRENT_USER,strKeyPath,strValueName,dwValue
Select Case dwValue
    Case 4
        Wscript.Echo _
            "Outlook is using settings from the Restricted Sites zone."
    Case 3
        Wscript.Echo "Outlook is using settings from the Internet
zone."
    Case 2
        Wscript.Echo "Outlook is using settings from the Trusted Sites
zone."
    Case 1
        Wscript.Echo "Outlook is using settings from the Local Intranet
zone."
    Case Else
        Wscript.Echo "The Outlook security zone could not be
determined."
End Select

在絕大多數計算機上,受限制的站點區域有最嚴格的安全限制。正因爲如此,你可能會更進一步來爲所有用戶配置 Outlook 設置,以保證 Outlook 在 HTML 安全上使用受限制的站點。這裏正好是一段實現以上功能的腳本:

Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
Set objReg=GetObject("winmgmts:/" & strComputer &
"/root/default:StdRegProv")
strKeyPath = "Software/Microsoft/Office.0/Outlook/Options/General"
strValueName = "Security Zone"
dwValue = 4
objReg.SetDWORDValue HKEY_CURRENT_USER, strKeyPath, strValueName, dwValue

返回頁首
最後的思考
這裏我們想再次強調一點:如果 Security Analyzer 能夠符合你的需求,那麼你就沒有必要再寫那些和 Security Analyzer 實現同樣功能的腳本。(Scripting Guys 絕對堅持認爲你不必去做你完全沒有必要做的事情。)但是從另外一方面來說,Security Analyzer 只能夠實現它編寫設計的功能是它的一個侷限性。之所以會如此是因爲你覺得還有其他一些很重要的安全檢查,而這些檢查是 Security Analyzer 所不能做到的。例如,也許你想確定一下所有用戶是否都使用受密碼保護的屏保程序。Security Analyzer 能夠做到嗎?不能,但是你卻可以通過編寫一段很簡單的腳本來實現:

Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
Set objReg =GetObject("winmgmts:/" & strComputer &
"/root/default:StdRegProv")
strKeyPath = "Control Panel/Desktop"
ValueName = "ScreenSaverIsSecure"
objReg.GetStringValue HKEY_CURRENT_USER, strKeyPath, ValueName,
strValue
If strValue = "1" Then
    Wscript.Echo "The screen saver is password protected."
Else
    Wscript.Echo "The screen saver is not password protected."
End If

然後,當然了,你也可以再進一步對屏保程序進行密碼保護:

Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
Set objReg =GetObject("winmgmts:/" & strComputer &
"/root/default:StdRegProv")
strKeyPath = "Control Panel/Desktop"
ValueName = "ScreenSaverIsSecure"
strValue = "1"
objReg.SetStringValue HKEY_CURRENT_USER, strKeyPath, ValueName,
strValue

所以,也許你使用 Security Analyzer 來完成某些任務同時使用腳本來完成其它一些任務。問題的重點在於,你不應該用非此即彼的主張來看待安全問題:不是使用 Security Analyzer 就是通過編寫腳本。相反,無論使用哪個都能起到很好的效果。畢竟,腳本通常用來輔助已經使用的工具而不是完全取代這些工具。選擇你應該乾的工作。

或者,至少隨便做一些能夠讓你的管家去做的事情。

你對欄目有什麼問題或意見嗎?請寫信到 [email protected]。找 Bentley
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章