安全性監控管理 ACL 的工具

Jesper M. Johansson

在 Windows 中,存取控制清單 (ACL) 可以讓您細微地控管使用者和處理程序使用如檔案和資料夾等資源的能力。ACL 的管理在保護使用者系統安全的作業中,是較為複雜的作業之一。幸好,有一些好用的公用程式

可協助自動化及簡化權限與 ACL 的相關作業。

大部分讀者都熟悉古老的 cacls.exe 工具,自從此工具第一次推出之後,每一個 Windows NT® 版本就少不了它。如果您在 Windows Vista™ 執行 cacls.exe,就會出現以下訊息:

Microsoft Windows [Version 6.0.5744]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.

C:\Windows\system32>cacls

 NOTE: Cacls is now deprecated, please use Icacls.

除了 Windows Vista 的 ACL 更新之外 (我在 TechNet Magazine 2007 年 6 月號已討論過;請參閱 technetmagazine.com/issues/ 2007/06),Microsoft 也更新了用來管理 ACL 的一些工具。有趣的是,在這些更新項目當中,最大的變更是命令列工具。

Icacls.exe 是 Windows Vista (以及舊版 Windows Server® 2003 Service Pack 2) 的新工具。它最後會取代 cacls.exe,您可能已發現,cacls.exe 從未完整更新以支援 Windows® 2000 所推出的更細微權限,使得這項更新大約逾期七年。

令人驚訝的是,雖然被淘汰了,cacls.exe 實際上還包含一些新功能。第一,它可察覺交叉點和符號連結,也知道要周遊它們。第二,它可以使用安全性描述定義語言 (Security Description Definition Language,SDDL) 字串來列印及設定 ACL。

不過,雖然 cacls.exe 有這些更新項目,但您真正想要的是 icacls.exe 提供的功能。

儲存及還原 ACL

過去這 10 年來,至少我一直希望有儲存 ACL 的能力,讓您可以在未來還原它。這是您可以對 ACL 執行的作業當中,最複雜的其中一項。除了某些特殊案例之外,其實很難回到您沒有摧毀 ACL 的原狀。不過,此功能非常有用。

在開始討論如何儲存或還原 ACL 之前,首先讓我們了解一下為何如此困難。假設您有一個包含當地大學生使用者資料的階層。您在 2 月 1 日儲存 ACL。在 4 月 17 日,您發現 ACL 有損毀的現象,因此從儲存的複本中進行還原。這項作業會有何複雜之處?

首先,新的一季是從 4 月 2 日開始。大約有 15% 的學生已畢業;因此,他們的目錄不復存在。於是,您的備份檔中會包含無效的 ACL。新的一季開始,所以也有一批新學生,這又是另一個 15 %。他們現在有 home 目錄,但備份檔中沒有 ACL。他們的 ACL 應該有什麼內容?當然,接下來您還有 70% 需要考慮,而他們已在這期間建立新檔案和資料夾,以及刪除其他的檔案和資料夾。您可以忽略已刪除的,但您要如何設定他們所建立的新資料夾?如果某一位學生在 3 月 4 日開始與朋友們共用某個資料夾,該怎麼辦?當您還原 ACL 時,是否會破壞它的設定?

許多人認為 ACL 的儲存及還原是一件簡單的作業,事實絕非如此。您在執行此作業時需要非常小心地處理。結果極有可能會導致一些未定義的行為。ACL 的還原絕對是最後不得已的選擇;因為自從您將它備份以來,時間越久,當您還原它時,就越有可能造成損壞。

如果您還是想要試試此功能,請在執行 icacls.exe 時使用 /save 參數:

icacls <target> /save acls.bin /t

這樣會將 ACL 儲存到一個叫做 acls.bin 的檔案。此檔案中的每一行將包含一個含有 ACL 的物件,且後面會有一行以 SDDL 指定 ACL 的內容。若使用 /t 參數,這個命令將對您指定的物件及其下的所有物件和容器進行操作。

這項儲存功能是一項受歡迎的工具箱項目,但它有一些缺點。例如,它只會儲存判別存取控制清單 (DACL),而不會儲存系統存取控制清單 (SACL)。事實上,如果有 SACL,它會儲存虛擬值來指出這一點,但它其實不會儲存 SACL 的任何部分。

此外,儲存 ACL 的方式會產生有趣的問題。在您喜愛的文字編輯器中開啟已儲存的 ACL 之前,請記住:

切勿編輯已儲存的 ACL!

如果您在文字編輯器中開啟包含已儲存 ACL 的檔案,會發現它看起來像是 Unicode (UTF-16) 格式的文字檔。事實也差不多。這可能會讓您以為可以編輯它,並從文字編輯器進行儲存。請不要這麼做!

如果您在文字編輯器中開啟包含已儲存 ACL 的檔案,然後儲存它,您將無法從該檔案還原 ACL。畢竟,它並非完全是 Unicode 文字檔。此種檔案的開頭必須是 2 位元組 0xfffe。如果您以文字編輯器 (例如記事本) 儲存該檔案,就會將該旗標放到檔案的前 2 個位元組中。不過,icacls.exe 工具會預期 ACL 資料的開頭,會從該檔案的位元組 0 開始。因此,工具將無法剖析檔案中的 ACL,因為它預期前兩個位元組是字串的一部分,其中應該指定要操作的物件。於是您的備份檔將變得無法使用。

Microsoft 知道這個問題,但由於它直到 Windows Vista 在 Beta 週期很晚的時候才獲得通報,因此,這項缺點未在發行之前加以解決。目前,我們不知道這何時可以解決,甚至是否會解決。因此,現在最好的建議就是不要編輯已儲存的 ACL。如果您需要這麼做,請將檔案另存為 .bin 檔,並使用十六進位編輯器,例如您喜愛的開發環境。

使用 /save 參數儲存 ACL 之後,您就可以使用含有 /restore 參數的 icacls.exe 來還原它。最簡單的 restore 命令語法如下:

icacls <directory> /restore acls.bin

還原程序不會對檔案進行操作。若要了解,請看 [圖 1] 顯示的命令順序。此處我將 icacls.exe 指向一個檔案,來建立儲存檔。然後我試著以 /restore 替代 /save 來還原它。結果失敗,因為 restore 命令只能對目錄進行操作。它應該修改的檔案已指定在 acls.bin 檔中。若要還原 ACL,我必須指向目錄而非檔案。這就是我在上一個命令中執行的動作,我指定 "." 作為要操作的物件。

Figure 1 儲存及還原 ACL

C:\Users\Jesper>icacls test.txt /save acls.bin
processed file: test.txt
Successfully processed 1 files; Failed processing 0 files

C:\Users\Jesper>icacls test.txt /restore acls.bin
test.txt\test.txt: The system cannot find the path specified
Successfully processed 0 files; Failed processing 1 files

C:\Users\Jesper>icacls . /restore acls.bin
processed file: .\test.txt
Successfully processed 1 files; Failed processing 0 files

另請注意,restore 命令必須以更高的權限執行!您可以從命令提示中以低階系統管理員或甚至標準使用者的身分來執行 save 命令,只要您有讀取 ACL 的權限即可。不過,若要還原 ACL,您需要有完整的系統管理員權仗。

替換 SID

icacls.exe 另一項非常有用的功能,就是能夠以一位使用者的權限,來取代另一位使用者的權限。方法是在還原期間使用 /substitute 參數。替代參數的文件上說它需要 SID,但後來又解釋這實際上也可以是一般使用者名稱。因此,[圖 2] 所顯示的操作順序可行。

Figure 2 在還原期間替換 SID

C:\Users\Jesper>icacls test.txt
test.txt VistaRC2-Test\foo:(R,W)
    VistaRC2-Test\Jesper:(I)(F)
    NT AUTHORITY\SYSTEM:(I)(F)
    BUILTIN\Administrators:(I)(F)

Successfully processed 1 files; Failed processing 0 files

C:\Users\Jesper>icacls test.txt /save acls.bin
processed file: test.txt
Successfully processed 1 files; Failed processing 0 files

C:\Users\Jesper>icacls. /substitute foo bar /restore acls.bin
processed file: .\test.txt
Successfully processed 1 files; Failed processing 0 files

C:\Users\Jesper>icacls test.txt
test.txt VistaRC2-Test\bar:(R,W)
    VistaRC2-Test\Jesper:(I)(F)
    NT AUTHORITY\SYSTEM:(I)(F)
    BUILTIN\Administrators:(I)(F)

Successfully processed 1 files; Failed processing 0 files

誠如您所看到的,最後我還是使用以前的相同 ACL,但原先用來指定 foo 的權限的 ACE,現在則改用來指定 bar 的權限。

變更擁有者

數年來,chown 一直是 UNIX 系統上的主要工具之一。Windows 原本沒有內建可變更物件擁有者的方式。後來在 Resource Kit 中出現了 setowner 工具。然後,我們在 Windows NT 4.0 中有了 takeown.exe 工具,但此公用程式只能讓您取得擁有權,除非您有其他人的密碼,否則不能授與擁有權給其他人。現在 icacls.exe 已內建可以讓您設定物件擁有者的功能,只要您有權限對其設定擁有者:

C:\>icacls c:\test /setowner foo
processed file: c:\test
Successfully processed 1 files; Failed processing 0 files

遺憾的是,icacls.exe 不能顯示物件的擁有者。您無法從命令列看到物件的擁有者是誰。不僅如此,如果您儲存物件的 ACL,它不會儲存物件的擁有者。

icacls.exe 中還含有一個問題,亦即它不會呼叫 SeTakeOwnershipPrivilege 來變更擁有者。根據 ACL,如果您有變更物件擁有者的權限,則 icacls.exe 的運作就沒有問題。不過,如果您是系統管理員,而根據物件的 ACL,您並沒有變更擁有者的權限,則您將無法使用 icacls.exe 這麼做,這是因為上述已知問題的緣故。在此情況下,您需要使用 takeown.exe 工具,它會呼叫 SeTakeOwnershipPrivilege,但只能將擁有者變更為您的帳戶或系統管理員群組,而非任意帳戶:

C:\>takeown /f c:\test

SUCCESS: The file (or folder): “c:\test” now owned by user “JJ-VistaRTMTst\Jesper”.

當然,也請注意,可從 Microsoft 下載中心下載的 subinacl 工具,也有 setowner 參數。在許多情況下,Subinacl 的運作方式實際上比 icacls 更容易了解,但使用起來較為複雜。

尋找特定使用者的檔案

Icacls 有另一項好用的功能:它可以尋找特定使用者擁有權限的檔案。例如:

C:\windows\system32>icacls “c:\program files” /findsid jesper /t

SID Found: c:\program files\Passgen\
passgen.exe.
Successfully processed 1808 files; Failed processing 0 files

如果您想要知道某一位使用者可以存取的所有項目,這將很有幫助。

重設及變更 ACL

如果 ACL 受損或毀壞,icacls.exe 有辦法將它重設為繼承其父代。這對於 2006 年秋天發生的 zero-day 安全性問題可以有很大的幫助。用來解決 Windows 元件發生這個問題的方法之一,是拒絕物件的 Everyone 存取權。這個部分聽起來很簡單,但要使用 Windows XP 和 Windows Server 2003 的內建工具來移除該存取控制項目 (Access Control Entry,ACE) 幾乎不可能。不過,若換做在 Windows Vista 中,您只需要執行下列命令:

C:\windows\system32>icacls “c:\program files\passgen\passgen.exe” /reset

processed file: c:\program files\passgen\passgen.exe
Successfully processed 1 files; Failed processing 0 files

當然,Icacls.exe 可以執行所有標準的 grant/deny/remove 作業。這份清單中唯一真正的新項目是 remove。使用此參數,您就可以針對特定使用者,從特定物件或階層中移除所有容許 ACE 的權限、所有拒絕 ACE 的權限,或兩者。[圖 3] 顯示一些不同的 grant、remove 和 deny 作業的範例。

Figure 3 Grant、deny 及 remove 作業

C:\>icacls c:\test /grant foo:(F)
processed file: c:\test

Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test
c:\test JJ-VistaRTMTst\foo:(F)
    BUILTIN\Administrators:(I)(F)
    BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)

Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test /remove:g foo
processed file: c:\test
Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test
c:\test BUILTIN\Administrators:(I)(F)
    BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)

Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test /deny foo:(F)
processed file: c:\test
Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test
c:\test JJ-VistaRTMTst\foo:(N)
    BUILTIN\Administrators:(I)(F)
    BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)

Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test /remove:d foo
processed file: c:\test
Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test
c:\test BUILTIN\Administrators:(I)(F)
    BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)

Successfully processed 1 files; Failed processing 0 files

如果您想要對特定群組或使用者開啟物件的存取權,則只移除拒絕 ACE 的功能將很有幫助。

設定整合層級

Icacls.exe 也有顯示及設定完整性層級的功能。Windows Vista 支援對物件加上完整性標籤。Icacls.exe 正是用來執行此功能的命令列工具:

C:\>icacls c:\test /setintegritylevel high

processed file: c:\test
Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test
c:\test BUILTIN\Administrators:(I)(F)
    BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
    Mandatory Label\High Mandatory Level:(NW)

Successfully processed 1 files; Failed processing 0 files

請注意,唯有當物件有明確設定完整性標籤時,icacls.exe 才會顯示完整性標籤。大部分檔案並沒有設定,因此您通常看不到此標籤。

最後,icacls.exe 可確認物件是否有標準 ACL。如前所述,有協力廠商的工具會在 ACL 中以錯誤的順序放置 ACE。Icacls.exe 可驗證及修正這類型的問題,如下所示:

C:\>icacls c:\test /verify
processed file: c:\test

Successfully processed 1 files; Failed processing 0 files

ACL UI

ACL UI 或 ACL 使用者介面,從 Windows XP 之後已經做了一點修改。[圖 4][圖 5] 分別顯示 Windows XP 和 Windows Vista 中的 ACL UI 對話方塊。

圖 4 Windows XP 中的 ACL UI 對話方塊

圖 4** Windows XP 中的 ACL UI 對話方塊 **

圖 5 Windows Vista 中的 ACL UI 對話方塊

圖 5** Windows Vista 中的 ACL UI 對話方塊 **

誠如您所看到的,此處有一些變更。第一,對話方塊最後很清楚地顯示您操作的物件,如果您一次處理數個物件,則這樣很有幫助。第二,底端有一些說明的超連結。不過,最明顯的變更是其中移除了 [新增] 和 [移除] 按鈕,並以 Windows Vista 中的使用者存取控制 (User Access Control,UAC) 支援中最常出現的 [編輯] 按鈕取代之。您可以從按鈕的護罩中看出,啟動此對話方塊的使用者沒有權限可編輯 ACL,因此,在編輯權限之前需要提高權限。請注意,如果您在 C: 磁碟機的根目錄中建立資料夾,並立即勾選其內容,則預設行為會不一樣。因為身為資料夾的擁有者,您有隱含權限可編輯 ACL,所以護罩會變不見。護罩象徵 COM Moniker,此機制是用來為某執行中程序的一部分啟動提高權限提示。如果您按一下 [編輯] 按鈕,會看到熟悉的提高權限對話方塊,如果您按一下提高權限對話方塊中的 [繼續],就會看到幾乎與您在 Windows XP 中按一下 [新增] 按鈕所看到的一模一樣的對話方塊。ACL UI 在許多地方都遵循這種雙對話方塊的概念;您要到提高權限時才會看到一個對話方塊,當您真的提高權限,您會看到如舊版 Windows 中熟悉的對話方塊。

如果您按一下 [進階] 按鈕,然後按一下 [稽核] 索引標籤,就會看到提高權限按鈕,如 [圖 6] 所示。您沒有提高權限就不能修改稽核內容,即使您對物件有完整控制權,且您是擁有者也一樣。那是因為修改物件 SACL 的能力是由 SE_SECURITY_NAME 權限管理,即 GUI 工具中所謂的管理稽核和安全記錄檔。根據預設,只有系統管理員擁有該權限。不過,在管理員核准模式下 (已啟用 UAC),會移除系統管理員的這個權限,因此,即使您是系統管理員,也需要提高權限。

圖 6 在 Windows Vista 中修改稽核設定時一律需要提高權限

圖 6** 在 Windows Vista 中修改稽核設定時一律需要提高權限 **

當您修改 ACL 時,關於提高權限需求的最後一個注意事項:所有這些陳述都以您未停用 UAC 為前提。如果您停用 UAC,則所有行為會回復到您在 Windows XP 看到的行為,唯一例外的是對話方塊看起來會不一樣。不過,假如您是以系統管理員的身分登入,則不需要提高權限,因為現在您的權杖內將隨時有 Administrators SID。

其他工具

Icacls.exe 是一個非常有用的工具,是比 cacls.exe 更好的改良品,但它仍有一些缺點。或許其中最值得注意的,就是它無法管理非檔案和非目錄之任何物件的存取權。相較於 Windows XP,Windows Vista 對其他物件的 ACL 做了一些稀疏的變更,但有時候您還是需要管理服務、登錄機碼、甚至 Active Directory® 物件的 ACL。

如果您是命令列慣用者,就需要 subinacl.exe 來執行此動作。Subinacl.exe 包含在支援工具中,您也可以經由下載取得。

不過,我必須警告您,subinacl.exe 並不容易使用。事實上,它有時候簡直就很遲鈍。不過 subinad.exe 是管理存取控制的一個超強工具。每一位系統管理員都需要此工具。

登錄 ACL

登錄 ACL 和檔案系統 ACL 一樣,都有所變更。不過,這些變更的範圍遠小於檔案系統的變更。與舊版 Windows 最明顯的差別在於,由於 Power Users 已經廢棄不用,所以幾乎所有 Power User ACE 都不見了。Power Users 不應該比任何其他使用者擁有更大的權限。它是證實 ACL 真的很複雜的證明,雖然 Power Users 的所有 ACE 並非都真的消失了。只是其中很不巧地漏掉了一些。

當您在登錄中查閱 ACL 時,會在一些地方看到一個叫做 RESTRICTED 之 SID 的 ACE。這並不是 Windows Vista 的新項目,而是一般人不太了解卻很有趣的一個 SID。RESTRICTED SID 代表呈現限制的權杖之程序。限制的權杖是使用 CreateRestrictedToken API 的特殊功能所建立的。此權杖有一個或多個限制 SID,亦即使用於個別存取檢查中的 SID。假設我們有一個以限制的權杖執行之程序。如果該程序嘗試以 RESTRICTED SID 的 ACE 存取物件,則 Windows 實際上會執行兩項存取檢查。第一項是正常存取檢查。第二項的作用與第一項一樣,但只對權杖中的限制 SID 執行。兩項存取檢查都必須通過才行。

目前,有數個 ACL 都使用 RESTRICTED SID,尤其是在登錄上。[圖 7] 顯示此種 ACL 的螢幕擷取畫面。

圖 7 登錄 ACL 在許多地方都包含 RESTRICTED 的 ACL

圖 7** 登錄 ACL 在許多地方都包含 RESTRICTED 的 ACL **

目前只有少數程序會利用限制的權杖之功能,尤其是在限制 SID 方面。會這麼做的程序範例為主控 Windows 防火牆、基本篩選引擎及診斷原則服務的服務程序。它也使用寫入限制的權杖。根據我的發現,目前 Windows Vista 中只有九個服務有在使用 RESTRICTED 和寫入限制的權杖。

就像在舊版的 Windows 中一樣,登錄權限的最佳作法就是要非常小心地處理。除非是在迫切需要且很細微的情況下,否則請勿修改登錄中的權限。由於登錄的修改涉及整個繼承模型和作業敏感度,如果您不小心修改登錄中的 ACL,很可能會造成嚴重失敗的後果。

結論

就像大部分 Windows 版本一樣,Windows Vista 在存取控制上也有一些細微的變更。不過,和其他最近幾個版本不同的事,其中是由許多次要變更的累積,而造成行為上的大幅改變。UAC 尤其需要多項變更,例如完整性標籤和對 ACL UI 的修改。此外,這也是歷史上首次的 ACL 大掃除。

在許多方面,Windows 上的預設 ACL 在 Windows Vista 中實際上是變得更簡單,這是前所未見的。不過,就像舊版一樣,您應該小心處理存取控制,必須事先有徹底的了解。尤其是涉及新版的 OS 時更是如此。希望使用本文概述的工具,您可以在探索 ACL 時輕鬆許多。

Jesper M. Johansson 是負責軟體安全性問題的首席安全性工程師,也是 TechNet Magazine 的特約編輯之一。他擁有 MIS 博士學位,在電腦安全性領域有 20 年以上的經驗。本專欄是改編自 Roger Grimes 和 Jesper Johansson 所寫的新書 Windows Vista Security:Securing Vista Against Malicious Attacks (Wiley,2007)。

© 2008 Microsoft Corporation and CMP Media, LLC. 保留所有權利;未經允許,嚴禁部分或全部複製.