共用方式為


適用於驅動程式開發人員的 Windows 安全性模型

Windows 安全性模型是以安全性實體對象為基礎。 操作系統的每個元件都必須確保其負責的物件安全性。 因此,驅動程式必須保護其裝置和裝置對象的安全性。

本主題摘要說明 Windows 安全性模型如何套用至內核模式驅動程式。

Windows 安全性模型

Windows 安全性模型主要以個別物件許可權為基礎,具有少量的系統範圍許可權。 可以保護的物件包括,但不限於進程、線程、事件和其他同步處理物件,以及檔案、目錄和裝置。

針對每種物件類型,一般讀取、寫入和執行許可權對應到詳細的物件特定許可權。 例如,對於檔案和目錄,可能的許可權包括讀取或寫入檔案或目錄、讀取或寫入擴充檔案屬性的許可權、周遊目錄的許可權,以及寫入物件的安全性描述元的許可權。

安全性模型包含下列概念:

  • 安全性識別碼 (SID)
  • 存取權杖
  • 安全性描述元
  • 存取控制清單 (ACL)
  • 權限

安全性識別碼 (SID)

安全性標識碼 (SID,也稱為 主體)會識別使用者、群組或登入會話。 每個使用者都有唯一的 SID,這是操作系統在登入時擷取的。

SID 是由作業系統或網域伺服器等授權單位所發出。 某些 SID 是已知的,而且具有名稱和識別碼。 例如,SID S-1-1-0 會識別所有人(或 World)。

存取權杖

每個進程都有存取令牌。 存取令牌描述程式的完整安全性內容。 其中包含使用者的 SID、使用者所屬群組的 SID,以及登入工作階段的 SID,以及授與使用者的全系統許可權清單。

根據預設,每當進程線程與安全性實體對象互動時,系統就會使用進程的主要存取令牌。 不過,線程可以模擬客戶端帳戶。 當線程模擬時,除了它自己的主要令牌之外,還有模擬令牌。 模擬令牌描述線程正在模擬之用戶帳戶的安全性內容。 模擬在遠端過程調用 (RPC) 處理中特別常見。

描述線程或進程的受限制安全性內容的存取令牌稱為受限制的令牌。 受限制令牌中的 SID 只能設定為拒絕存取,不允許存取安全性實體物件。 此外,令牌可以描述一組有限的全系統許可權。 使用者的 SID 和身分識別保持不變,但使用者的訪問許可權會受到限制,而進程正在使用受限制的令牌。 CreateRestrictedToken 函式會建立受限制的令牌。

安全性描述元

每個具名 Windows 物件都有安全性描述元;某些未命名的物件也會這麼做。 安全性描述項描述物件及其 ACL 的擁有者和群組 SID。

對象的安全性描述元通常是由建立物件的函式所建立。 當驅動程式呼叫 IoCreateDeviceIoCreateDeviceSecure 例程來建立裝置物件時,系統會將安全性描述元套用至建立的裝置物件,並設定物件的 ACL。 針對大部分的裝置,ACL 會在裝置資訊 (INF) 檔案中指定。

如需核心驅動程式檔中的安全性描述項詳細資訊

存取控制清單

存取控制 清單 (ACL) 可對物件的存取進行更細緻的控制。 ACL 是每個物件之安全性描述元的一部分。

每個 ACL 都包含零個或多個 存取控制 專案 (ACE)。 接著,每個 ACE 都包含單一 SID,可識別使用者、群組或計算機,以及該 SID 遭到拒絕或允許的許可權清單。

裝置物件的 ACL

裝置物件的 ACL 可以用下列三種方式之一來設定:

  • 在預設的安全性描述元中設定其裝置類型。
  • RtlCreateSecurityDescriptor 函式以程式設計方式建立,並由 RtlSetDaclSecurityDescriptor 函式設定
  • 在裝置 INF 檔案或 IoCreateDeviceSecure 例程的呼叫中,於安全性描述元定義語言 (SDDL) 中指定。

所有驅動程式都應該使用 INF 檔案中的 SDDL 來指定其裝置物件的 ACL。

SDDL 是可延伸的描述語言,可讓元件以字串格式建立 ACL。 使用者模式和內核模式程序代碼都使用 SDDL。 下圖顯示裝置物件的SDDL字串格式。

此圖顯示裝置物件的SDDL字串格式。

Access 值會指定允許的存取類型。 SID 值會指定安全性識別碼,以決定 Access 值套用的物件(例如,使用者或群組)。

例如,下列 SDDL 字串允許系統 (SY) 存取所有專案,並允許其他人 (WD) 僅讀取存取:

“D:P(A;;GA;;;SY)(A;;GR;;;WD)”

頭檔 wdmsec.h 也包含一組適用於裝置物件的預先定義 SDDL 字串。 例如,頭檔會定義SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX,如下所示:

"D:P(A;;GA;;;SY)(A;;GRGWGX;;;BA)(A;;GRGWGX;;;WD)(A;;GRGWGX;;;RC)"

此字串的第一個區段可讓核心和作業系統 (SY) 完全控制裝置。 第二個區段可讓內建 管理員 istrators 群組 (BA) 中的任何人存取整個裝置,但不允許變更 ACL。 第三個區段允許每個人 (WD) 讀取或寫入裝置,而第四個區段會將相同的許可權授與不受信任的程式代碼 (RC)。 驅動程式可以使用預先定義的字串,就像是或裝置物件特定字串的模型一樣。

堆疊中的所有裝置物件都應該具有相同的 ACL。 變更堆疊中一個裝置物件上的 ACL 會變更整個裝置堆疊上的 ACL。

不過,將新的裝置物件新增至堆疊並不會變更任何 ACL、新裝置物件的 ACL 或堆疊中任何現有裝置物件的 ACL。 當驅動程式建立新的裝置物件並將其附加至堆疊頂端時,驅動程式應該從下一個較低的驅動程序複製 DeviceObject.Characteristics 字段,將堆疊的 ACL 複製到新的裝置物件。

IoCreateDeviceSecure 例程支援使用 WD 和 SY 等預先定義 SD 的 SDDL 字串子集。 使用者模式 API 和 INF 檔案支援完整的 SDDL 語法。

使用 ACL 的安全性檢查

當進程要求存取物件時,安全性檢查會將物件的 ACL 與呼叫端存取令牌中的 SID 進行比較。

系統會以嚴格的由上至下的順序比較 ACE,並在第一個相關相符專案上停止。 因此,建立 ACL 時,您應該一律將拒絕 ACE 置於對應的授與 ACE 之上。 下列範例顯示比較的繼續方式。

範例 1:比較 ACL 與存取令牌

範例 1 顯示系統如何比較 ACL 與呼叫端進程的存取令牌。 假設呼叫端想要開啟具有下表所示 ACL 的檔案。

範例檔案 ACL

權限 SID 存取
允許 會計 寫入、刪除
允許 Sales 附加
拒絕 法務 附加、寫入、刪除
允許 每個人 參閱

此 ACL 有四個 ACE,特別適用於會計、銷售、法律及所有人群組。

接下來,假設要求程式的存取令牌包含一個使用者和三個群組的 SID,順序如下:

使用者吉姆 (S-1-5-21...)

組會計 (S-1-5-22...)

群組法律 (S-1-5-23...)

群組所有人 (S-1-1-0)

比較檔案 ACL 與存取令牌時,系統會先在檔案的 ACL 中尋找使用者 Jim 的 ACE。 [無] 隨即出現,因此接下來會尋找會計群組的 ACE。 如上表所示,會計群組的 ACE 會顯示為檔案 ACL 中的第一個專案,因此 Jim 的程式會被授與寫入或刪除檔案的許可權,而比較會停止。 如果法律群組的 ACE 改為在 ACL 中會計群組的 ACE 之前,進程將會遭到拒絕寫入、附加和刪除檔案的存取權。

範例 2:比較 ACL 與受限制的令牌

系統會比較 ACL 與受限制令牌的方式,與比較未受限制之令牌中的令牌相同。 不過,受限制令牌中的拒絕 SID 只能比對 ACL 中的拒絕 ACE。

範例 2 顯示系統如何比較檔案的 ACL 與受限制的令牌。 假設檔案與上表所示的 ACL 相同。 不過,在此範例中,進程具有包含下列 SID 的受限制令牌:

使用者吉姆 (S-1-5-21...)否認

組會計 (S-1-5-22...)否認

群組法律 (S-1-5-23...)否認

群組所有人 (S-1-1-0)

檔案的 ACL 不會列出 Jim 的 SID,因此系統會繼續進行會計群組 SID。 雖然檔案的 ACL 具有會計群組的 ACE,但此 ACE 允許存取;因此,它不符合進程受限制令牌中的 SID,這會拒絕存取。 因此,系統會繼續進行法律群組 SID。 檔案的 ACL 包含法律群組拒絕存取的 ACE,因此進程無法寫入、附加或刪除檔案。

權限

許可權可讓使用者在本機計算機上執行系統相關作業,例如載入驅動程式、變更時間或關閉系統。

許可權與訪問許可權不同,因為它們會套用至系統相關的工作和資源,而不是物件,而且因為許可權是由系統管理員指派給使用者或群組,而不是由操作系統指派。

每個進程的存取令牌都包含授與給進程的許可權清單。 使用之前,必須特別啟用許可權。 如需許可權的詳細資訊,請參閱 核心驅動程式檔中的許可權

Windows 安全性模型案例:建立檔案

每當進程建立檔案或物件的句柄時,系統就會使用 Windows 安全性模型中所述的安全性建構。

下圖顯示當使用者模式進程嘗試建立檔案時所觸發的安全性相關動作。

當使用者模式進程嘗試建立檔案時,說明安全性相關動作的流程圖。

上圖顯示當使用者模式應用程式呼叫 CreateFile 函式時,系統如何回應。 下列附註指的是圖中的圓圈數位:

  1. 使用者模式應用程式會呼叫 CreateFile 函式,並傳遞有效的 Microsoft Win32 檔名。
  2. 使用者模式Kernel32.dll將要求傳遞至 Ntdll.dll,將 Win32 名稱轉換為 Microsoft Windows NT 檔名。
  3. Ntdll.dll使用 Windows 檔名呼叫 NtCreateFile 函式。 在Ntoskrnl.exe內,I/O 管理員會處理 NtCreateFile
  4. I/O 管理員會將要求重新封裝到物件管理員呼叫中。
  5. 物件管理員會解析符號連結,並確保使用者具有檔案建立路徑的周遊許可權。 如需詳細資訊,請參閱 物件管理員中的安全性檢查。
  6. 物件管理員會呼叫系統元件,該元件擁有與要求相關聯的基礎物件類型。 對於檔案建立要求,此元件是擁有裝置物件的 I/O 管理員。
  7. I/O 管理員會根據使用者的存取令牌檢查裝置對象的安全性描述元,以確保使用者具有裝置的必要存取權。 如需詳細資訊,請參閱 I/O 管理員中的安全性檢查。
  8. 如果用戶進程具有必要的存取權,I/O 管理員會建立句柄,並將IRP_MJ_CREATE要求傳送給裝置或文件系統的驅動程式。
  9. 驅動程式會視需要執行其他安全性檢查。 例如,如果要求指定裝置命名空間中的物件,驅動程式必須確定呼叫端具有必要的訪問許可權。 如需詳細資訊,請參閱 驅動程式中的安全性檢查。

物件管理員中的安全性檢查

檢查訪問許可權的責任屬於可執行這類檢查的最高層級元件。 如果物件管理員可以驗證呼叫者的訪問許可權,則會這麼做。 如果沒有,物件管理員會將要求傳遞給負責基礎物件類型的元件。 如果可以,該元件接著會驗證存取權;如果無法,它會將要求傳遞至仍然較低的元件,例如驅動程式。

物件管理員會檢查 ACL 是否有簡單的物件類型,例如事件和 Mutex 鎖定。 對於具有命名空間的物件,類型擁有者會執行安全性檢查。 例如,I/O 管理員會被視為裝置對象和檔案對象的類型擁有者。 如果物件管理員在剖析名稱時找到裝置物件或檔案對象的名稱,則會將名稱交給 I/O 管理員,如上述檔案建立案例所示。 I/O 管理員接著會檢查訪問許可權,如果可以的話。 如果名稱指定裝置命名空間中的物件,則 I/O 管理員會關閉裝置的名稱(或檔案系統)驅動程式,而該驅動程式負責驗證要求的存取權。

I/O 管理員中的安全性檢查

當 I/O 管理員建立句柄時,它會根據進程存取令牌檢查對象的許可權,然後將授與給使用者的許可權連同句柄一起儲存。 當稍後的 I/O 要求到達時,I/O 管理員會檢查與句柄相關聯的許可權,以確保進程有權執行要求的 I/O 作業。 例如,如果進程稍後要求寫入作業,I/O 管理員會檢查與句柄相關聯的許可權,以確保呼叫端具有物件的寫入許可權。

如果句柄重複,則可以從複本中移除許可權,但無法新增至該複本。

當 I/O 管理員建立物件時,它會將一般 Win32 存取模式轉換為物件特定的許可權。 例如,下列許可權適用於檔案和目錄:

Win32 存取模式 物件特定許可權
GENERIC_READ ReadData
GENERIC_WRITE WriteData
GENERIC_EXECUTE ReadAttributes
GENERIC_ALL 全部

若要建立檔案,進程必須具有目標路徑中父目錄的周遊許可權。 例如,若要建立 \Device\CDROM0\Directory\File.txt,進程必須有權周遊 \Device、\Device\CDROM0 和 \Device\CDROM0\Directory。 I/O 管理員只會檢查這些目錄的周遊許可權。

I/O 管理員會在剖析檔名時檢查周遊許可權。 如果檔名是符號連結,I/O 管理員會將其解析為完整路徑,然後從根目錄開始檢查周遊許可權。 例如,假設符號連結 \DosDevices\D 對應至 Windows NT 裝置名稱 \Device\CDROM0。 進程必須具有 \Device 目錄的周遊許可權。

如需詳細資訊,請參閱 物件句柄物件安全性

驅動程式中的安全性檢查

操作系統核心會將每個驅動程式視為具有其本身命名空間的文件系統。 因此,當呼叫端嘗試在裝置命名空間中建立物件時,I/O 管理員會檢查進程是否具有路徑中目錄的周遊許可權。

使用 WDM 驅動程式時,除非已建立指定FILE_DEVICE_SECURE_OPEN的 Device Object,否則 I/O 管理員不會對命名空間執行安全性檢查。 未設定FILE_DEVICE_SECURE_OPEN時,驅動程式會負責確保其命名空間的安全性。 如需詳細資訊,請參閱 控制裝置命名空間存取 和保護 裝置物件

針對WDF驅動程式,一律會設定FILE_DEVICE_SECURE_OPEN旗標,以便在允許應用程式存取裝置命名空間內的任何名稱之前,先檢查裝置的安全性描述項。 如需詳細資訊,請參閱 控制 KMDF 驅動程式中的裝置存取。

Windows 安全性界限

驅動程式會彼此通訊,以及與不同許可權等級的使用者模式呼叫者通訊,可視為跨越信任界限。 信任界限是任何從較低許可權進程進入較高特殊許可權進程的程式代碼執行路徑。

許可權等級的差異越高,界限就越有趣,攻擊者想要對目標驅動程式或進程執行許可權提升攻擊等攻擊。

建立威脅模型的一部分是檢查安全性界限,並尋找未預期的路徑。 如需詳細資訊,請參閱 驅動程序的威脅模型化。

跨越信任界限的任何數據都是不受信任的,而且必須經過驗證。

此圖顯示三個核心驅動程式,以及兩個應用程式,一個在應用程式容器中,另一個是使用系統管理員許可權執行的應用程式。 紅線表示範例信任界限。

圖表描述具有三個核心驅動程式的驅動程式攻擊面、應用程式容器中的應用程式,以及具有系統管理員許可權的應用程式。

由於應用程式容器可以提供額外的條件約束,而且未在系統管理層級執行,因為信任界限位於應用程式容器(非常低許可權進程)和核心驅動程式之間,因此路徑 (1) 是提升攻擊的風險較高。

路徑 (2) 是風險較低的路徑,因為應用程式是以系統管理員許可權執行,並直接呼叫核心驅動程式。 管理員 在系統上已經是相當高的許可權,因此從系統管理員到核心的攻擊面就不像攻擊者感興趣的目標,但仍是值得注意的信任界限。

Path (3) 是程式代碼執行路徑的範例,其跨越多個信任界限,如果未建立威脅模型,可能會遺漏這些界限。 在此範例中,驅動程式 1 與驅動程式 3 之間有信任界限,因為驅動程式 1 會從使用者模式應用程式取得輸入,並將它直接傳遞至驅動程式 3。

從使用者模式進入驅動程式的所有輸入都是不受信任的,而且應該經過驗證。 來自其他驅動程式的輸入也可能不受信任,取決於先前的驅動程式是否只是簡單的傳遞(例如驅動程式 1 從應用程式 1 收到數據,驅動程式 1 未對數據進行任何驗證,而只是將它轉送至驅動程式 3)。 請務必藉由建立完整的威脅模型,識別所有受攻擊面和信任界限,並驗證跨越它們的所有數據。

Windows 安全性 模型 建議

  • 在呼叫 IoCreateDeviceSecure 例程時設定強式預設 ACL。
  • 為每個裝置在 INF 檔案中指定 ACL。 這些 ACL 可以在必要時鬆散緊密的預設 ACL。
  • 設定FILE_DEVICE_SECURE_OPEN特性,將裝置物件安全性設定套用至裝置命名空間。
  • 請勿定義允許FILE_ANY_ACCESS的 IOCTL,除非無法惡意利用這類存取。
  • 使用 IoValidateDeviceIoControlAccess 例程來強化允許FILE_ANY_ACCESS的現有 IOCTLS 安全性。
  • 建立威脅模型來檢查安全性界限,並尋找未預期的路徑。 如需詳細資訊,請參閱 驅動程序的威脅模型化。
  • 如需其他驅動程式安全性建議,請參閱 驅動程式安全性檢查清單

另請參閱

保護裝置物件

驅動程式安全性檢查清單