由PolicyKit和DirtyPipe漏洞淺談安全操作系統的意義
1、前言
從去年爆出來的PolKit(CVE-2021-4034)漏洞和今年年初爆出來的DirtyPipe(CVE-2022-0847),能夠對Linux操作系統帶來十分嚴重的安全威脅。其中,PolKit漏洞是由于軟件層的錯誤代碼編寫導致的,而DirtyPipe則是由于高內核版本中對于Pipe管道的錯誤初始化而導致漏洞的產生。
惡意用戶均可以通過這兩個漏洞進行提權,從而實現對操作系統的入侵和破壞。
本文從剖析PolKit和DirtyPipe這兩個漏洞入手,從操作系統的安全防御視角,闡述安全操作系統中的安全組件或者安全模塊如何緩解和阻止漏洞利用產生的負面效果。
2、漏洞簡介
2.1 PolKit漏洞
PolKit名稱的全稱為PolicyKit,是運行在類Unix操作系統上的軟件包,主流的Linux操作系統--Ubuntu、Debian、Fedora、CentOS等,都默認裝有此軟件包。
PolKit漏洞源于PolicyKit包中的pkexec工具,pkexec程序是一個類sudo可執行程序,具有root級的SUID權限,此程序允許普通用戶以其他用戶的身份執行命令。
由于pkexec基本在所有的Linux系統上都有安裝,而且此漏洞存在已久,并且恰巧pkexec具有SUID權限,導致此漏洞對Linux系統的安全產生了很大的威脅。
PolKit漏洞形成的原因為pkexec程序沒有對選項為空的情形進行判斷,而直接便對argv[1]選項變量進行賦值,導致越界對環境變量進行了賦值,從而利用構建不安全的環境變量實現對漏洞的提權。如下圖1所示:

圖1 pkexec漏洞利用流程
在pkexec中構造出不安全的環境變量后,在程序清除掉環境變量前,需要盡快對其進行利用,所以目前很多POC代碼都選擇構建使用GCONV_PATH環境變量,此變量由iconv_open調用,允許指定使用第三方動態庫,而恰巧在環境變量被清除前,pkexec程便調用了iconv_open函數,惡意代碼庫中的惡意代碼便被觸發執行。
2.2 DirtyPipe漏洞
DirtyPipe漏洞是于今年3月初公開披露的內核級漏洞,對操作系統會產生極大的安全威脅。其影響范圍為高于5.8的內核版本,由于5.16.11、5.15.25、以及5.10.102的內核版本都進行了修復,所以相應內核版本只要高于以上三個內核版本就沒有影響。
顧名思義,DirtyPipe漏洞意指這次漏洞是由于pipe管道引起的,這次漏洞是由其發現者無意在使用splice系統調用接口來處理管道數據時發現的。splice系統調用用于在兩個文件中移動數據,其中一個文件文件需要指定為管道文件,其優勢是直接在內核層中進行內存數據移動,可以實現用戶層的“零拷貝”,提高數據傳輸性能,此機制在web中使用較多。
由于新創建的管道緩沖區結構中的“flags”成員變量在內核中的copy_page_to_iter_pipe函數和push_pipe函數中缺乏正確的初始化,從而導致漏洞的發生。由于PIPE_BUF_FLAG_CAN_MERGE標志設置不正確,而且此標志控制寫入管道緩沖區的合并操作,因此允許寫入拼接到管道中的現有頁面,使得只讀文件的數據會被pipe緩沖區中的數據覆蓋。非特權本地用戶可以使用此漏洞寫入到只讀文件的頁面緩存中的后備頁面,一旦數據刷新,后備頁面的內容便寫入到磁盤上,由此達到提升惡意用戶系統權限的目的。
使用此漏洞可以讓普通用戶對其只有讀權限的文件進行寫入,由此產生的負面影響不僅僅是可以越權對系統敏感文件進行篡改--比如passwd文件(shadow文件無法篡改,因為普通用戶沒有shadow文件的讀權限),而且可以對具有SUID權限的程序進行篡改,在程序的代碼段寫入篡改后的惡意代碼。但是由于此漏洞屬于后備頁面緩沖區的覆蓋寫,所以無法改變代碼段的大小。
由此可知,Dirtypipe漏洞主要在以下方面存在安全威脅:
1. 篡改具有只讀權限的文件內容;2. 篡改系統中具有SUID的可執行程序,從而提權。
而且,由于發生漏洞的地方直接從緩沖區后備頁面寫入數據到塊設備層,VFS層上的權限控制機制起不到任何作用,從而使得權限檢測失效,像SELinux安全控制模塊也無法緩解此種類型的漏洞,所以普通操作系統現有的安全控制機制無法阻止此種漏洞的利用。
3、安全操作系統的防護手段
3.1 安全操作系統概述
大家也許對“安全操作系統”這個字眼很疑惑,“安全操作系統”特指什么樣的操作系統?
從操作系統的通用安全需求角度講,安全操作系統需要通過安全要素和安全模型解決操作系統中主體對客體的安全訪問問題,包括用戶登錄、用戶管理、文件和設備訪問、資源控制、進程管理、網絡通信等。
從安全功能角度講,安全操作系統指的是在通用操作系統的基礎上,加強了身份鑒別、自主訪問控制、安全審計等功能,增加了安全標記、強制訪問控制、可信路徑等安全功能,能對所管理的數據與資源提供適當的保護級、有效地控制硬件與軟件功能的操作系統。
從測評角度講,一個操作系統能夠稱得上“安全操作系統”,其自身需要滿足指定的限定條件,其對安全技術和功能的部署實施需要滿足特定的測試標準和依據,需要通過權威機構的測評。所以,依據測評標準來講,安全操作系統需要滿足國際的CC EAL以及我國的操作系統等級保護等安全標準,并經過相應測評。
從操作系統的整體安全體系結構講,安全操作系統需要滿足操作系統的整體性安全需求,從底向上在操作系統的多層級、多維度上構建安全防護功能,同時建立安全和可信邊界。操作系統是一種復雜的軟件系統,其融合了各種軟件功能,從桌面操作系統、服務器操作系統、移動智能操作系統、嵌入式操作系統等分類上即可知其有多復雜,這么復雜的系統單單從單層級或者單維度來構建安全顯然無法有效解決安全問題。操作系統的復雜性使得操作系統暴露給攻擊者很多的攻擊面--比如軟件攻擊、硬件設備攻擊、固件攻擊等,為了有效對操作系統進行安全防護,需要在多層次、多維度上構建安全,形成操作系統的整體安全防護體系。

圖2 通用操作系統安全體系樣例
接下來,從操作系統防御角度,闡述安全操作系統中的安全組件是如何阻止或者緩解PolKit和DirtyPipe兩種類型的漏洞利用。
3.2 三權分立用戶管理模型
類UNIX操作系統中通常只有兩類用戶:超級用戶和普通用戶,超級用戶具有管理系統的全部權利。一旦用戶被攻破,將可能對系統造成極大的損害。三權分立機制把超級用戶的權限按照進行細分為三個管理員用戶:系統管理員、安全管理員和審計管理員。其中:
1. 系統管理員負責用戶管理、網絡管理等系統的日常管理工作;2. 安全管理員負責與安全配置、管理相關的工作,包括:角色創建與刪除、角色權限設置與修改、用戶角色設置與修改、文件安全屬性的修改以及智能卡的發放與管理等;3. 審計管理員負責安全審計工作。

圖3 三權分立用戶模型
在安全操作系統的三權分立用戶模型中,三個管理員用戶無法相互進行用戶身份切換,同時普通用戶向管理員用于的身份切換也是被禁止的,如下圖所示:

圖4 用戶切換模型
在安全操作系統上如果使用此種用戶切換模型,那么pkexec程序便無法運行,自然也就能夠保證惡意用戶無法利用PolKit漏洞。
此外,即使PolKit和DirtyPipe漏洞可以被利用,由于超級管理員的權限被細分以及三權管理用戶權限的隔離性,使得提權后的權限被縮小,無法獲取整個系統的管理權限。
所以,由此可知,三權分立模型對于像Polkit和DirtyPipe類型的漏洞還是具有一定的緩解能力。
3.3 基于角色的訪問控制模型
基于角色的訪問控制模型RBAC(Role-Based Access Control Model)基本思想是:將訪問權限分配給角色,用戶通過賦予不同的角色獲得角色所擁有的訪問權限。用戶與特定的一個或多個角色相關聯,角色與一個或多個操作相關聯。RBAC從控制主體的角度出發,根據管理中相對穩定的職權和責任劃分角色,將訪問權限與角色相聯系,這點是與傳統的自主訪問控制和強制訪問控制將權限直接授予用戶的方式不同;用戶分配合適的角色,讓用戶與訪問權限相聯系,角色成為訪問控制中用戶和權限之間的一座橋梁,從而實現了用戶訪問權限的分離,這種方式更便于授權管理、角色劃分、職責分離、目標分級和賦予最小權限,更好的保證了系統的安全。
安全操作系統基于RBAC模型將原Linux超級用戶(root)的特權分解成3個特權角色,初始安裝時,系統將它們缺省組合成三個特權集合(角色),即系統管理員(sysadm_r)、安全管理員(secadm_r)、審計管理員(auditadm_r),并分別賦于了三個不同用戶。當然,原則上可以根據需要任意組合其他角色,但必須使每一個角色,僅擁有完成其管理工作所需的最小特權。RBAC中用戶關聯角色,角色關聯操作進程,進程關聯對客體的操作權限,最終實現對用戶權限的控制,如圖所示:

圖5 用戶權限繼承關系
由圖5可知,每個用戶下執行的進程會繼承用戶對應的角色權限,對于利用PolKit和DirtyPipe漏洞提權的惡意用戶,其提權后的進程擁有的權限與惡意用戶的角色匹配,所以即使提權成功,也無法獲取管理員用戶權限,從而降低了漏洞利用產生的安全風險。
3.4 安全內核
在本文中講的安全內核是一個相對概念,因為真正的“安全內核”不僅需要保證其完整性和隔離性,還需要通過形式化驗證方法進行驗證。其中完整性和隔離性通過可信度量或者簽名驗簽方式以及CPU的特權域即可實現,但是如果要完全經過形式化方法進行驗證則是十分困難的,目前僅有SEL4經過了形式化驗證。
所以本文指的安全內核指的是只要滿足完整性和隔離性要求的系統內核子模塊,或者在前兩種條件達到的前提下,內核中的部分核心代碼通過半形式化或者形式化證明的系統內核。
安全內核包含以下安全功能:
1. 可信度量:負責對操作系統中的客體進行度量;2. 固件升級:對處理器、板卡等設備的固件進行升級;3. 安全執行環境:提供基于硬件隔離的安全運行環境,系統中的隱私服務或者核心應用可以運行其中;4. 內存加密:提供基于硬件級的內存加密手段,保護系統關鍵數據的機密性和隱私性。其中,可信度量提供的功能如下圖所示:

圖6 可信度量功能
可信度量功能負責對系統中的進程、文件、動態庫虛擬機、容器和驅動等進行完整性度量,防止這些客體在存儲或者運行時被篡改。
對進程運行時進行度量,可以有效阻止DirtyPipe漏洞利用,一旦通過DirtyPiepe漏洞篡改具有SUID的程序,則其完整性必然收到破壞,被篡改的進程運行時便會被可信度量模塊偵測并攔截。
對靜態的文件進行度量,可以有效阻止DirtyPipe漏洞利用,一旦通過DirtyPipe修改關鍵文件,便會被可信度量模塊偵測并阻止其修改。
對動態庫進行度量,可以有效阻止PolKit漏洞利用,一旦惡意程序為pkexec構造了第三方惡意代碼庫,在pkexec程序運行時,可信度量模塊便會檢測到第三代碼庫的加載,通過配置的策略可以阻止惡意代碼的執行。
3.5 安全審計功能
安全操作系統的安全審計就是對操作系統中涉及安全事件的活動進行記錄、檢查、審核或追溯。它的主要目的就是檢測非法用戶對計算機系統的入侵,顯示合法用戶的誤操作,并能及時發出安全警告以便讓管理員對入侵事件進行快速響應。審計作為一種事后追查的手段來保證系統的安全,它對涉及系統安全的操作做一個完整的記錄。審計為系統進行事故原因的查詢、定位,事故發生前的預測、報警以及事故發生之后的實時處理提供詳細、可靠的依據和支持,以備有違反系統安全規則的事件發生后能夠有效地追查事件發生的地點和過程以及責任人。
由此可見,安全審計對于操作系統的安全來說扮演著十分重要的角色,尤其是對于漏洞利用的檢測和及時響應十分奏效。對于PolKit和DirtyPipe的漏洞利用檢測來說,安全審計功能不僅支持對SUID進程的審計,同時支持對setuid、chroot和pivot_root等系統調用的審計,能夠檢測及追溯惡意用戶是否利用漏洞進行提權。同時,結合三權分立以及基于角色的訪問控制機制,使得安全審計只有具有審計管理員權限的角色進行訪問,阻止惡意用戶試圖刪除審計信息達到隱藏的目的。
4、結語
隨著信息化技術的持續發展,安全技術體系架構也在不斷迭代和演進,安全操作系統的“安全”不應只是一個“迷彩絢爛”的口號,而是能夠為客戶提供基礎安全服務以及持續增值的實用性體系架構。尤其是在漏洞利用方面,安全操作系統可以充分發揮內生的安全優勢,對漏洞利用起到阻止或緩解的作用。
參考文獻:
1.https://seclists.org/oss-sec/2022/q1/80
2.https://access.redhat.com/security/vulnerabilities/RHSB-2022-002
3.https://www.datadoghq.com/blog/dirty-pipe-vulnerability-overview-and-remediation/
4.《操作系統安全導論》卿斯漢 劉文清 劉海峰著