簡介

Linux Kernel 加入了一個叫做非特權使用者命名空間(unprivileged user namespaces)的安全功能,目的是要提升應用程式的隔離能力跟 sandboxing 的效果。這個機制讓沒有特權的使用者可以在一個受限的環境裡拿到管理權限,跟主機系統的權限分開。 1, 2 這個功能最大的好處就是能更安全地建立跟管理容器(containers)跟沙箱(sandboxes) 1, 3 。 不過,引進非特權使用者命名空間也增加了 Kernel 的潛在攻擊面(attack surface)。 1, 3 從過去的例子來看,這些命名空間已經被用來利用 Kernel 的各種漏洞。 4, 5

Kernel 防線失守?Ubuntu 命名空間的三大繞過技法解析 | 資訊安全新聞

意識到這些風險,有些作業系統採取了積極的態度來降低問題。有一個方法就是在使用非特權使用者命名空間上設限。例如,某個作業系統在 23.10 版開始引進這種限制,到了 24.04 版就設成預設開啟。 4, 6 這個做法用了一個安全模組來選擇性地控制這些命名空間的建立跟使用。 4, 7 這跟很多其他 Linux 發行版預設的行為不一樣,一般來說非特權使用者在命名空間裡有更大的能力,這顯示出一個專注於提升系統安全性的努力,試圖限制跟無限制使用命名空間相關的攻擊路徑。 4, 5, 8

這份報告詳細分析了安全研究員找到的三種繞過這些非特權使用者命名空間限制的方法。 1, 3 分析會深入探討每個繞過背後的技術原理,探討它們可能帶來的安全影響,還會聊聊可以採取的防禦措施。焦點會嚴格放在這些繞過的技術面。

試圖限制非特權使用者命名空間是一個重視安全的決定,跟很多 Linux 發行版的常見做法不同。 4, 8 這動作顯示出他們知道無限制的使用者命名空間可能被用來攻擊 Kernel 。透過設下這些限制,目標是降低非特權使用者利用 Kernel 漏洞的可能性,這些漏洞通常需要更高的權限才能在隔離環境中觸發。

非特權使用者命名空間基礎

使用者命名空間是 Linux Kernel 的一個核心功能,提供了一個機制來隔離容器或沙箱應用程式跟底層主機系統之間的使用者跟群組識別碼(UIDs 和 GIDs)。 2, 9 在使用者命名空間裡,一個程序可以擁有跟主機上不同的獨特 UID 跟 GID 集合。 2 這種隔離是透過一個映射過程達成的,把命名空間跟主機系統之間的 UID 跟 GID 轉換過來。 2, 9

使用者命名空間帶來的安全好處很明顯。 2, 10 它們提供了一層額外的隔離,對執行不信任或可能被入侵的應用程式特別有價值。使用者命名空間也讓所謂的 rootless containers 變可能。在這種情況下,程序可以在容器裡以 root 使用者(UID 0)身份執行,但不需要主機系統上的實際 root 權限。如果容器被攻破,這大大降低了潛在的危害,因為攻擊者在主機上的權限還是有限的。另外,在多租戶環境(像是雲端平台)中,使用者命名空間能確保不同租戶之間的使用者 ID 是隔離的,避免一個租戶的被入侵容器影響到同一主機上的其他租戶。

雖然有這些好處,非特權使用者命名空間的靈活性和強大功能也帶來了安全風險。 1, 3 雖然設計上是為了加強沙箱功能,但它們無意中擴大了 Kernel 的攻擊面,暴露了更多可能被利用的介面。 1 歷史顯示,非特權使用者命名空間已經被牽涉進多種權限提升的攻擊鏈中,攻擊者用它們作為踏板來獲得更高層級的存取權。 4, 5

為了應對這些風險,某個作業系統選擇對非特權使用者命名空間設限。 4, 7 這是透過一個安全框架實現的,根據應用程式設定檔來選擇性地控制使用者命名空間的建立。 4, 7 這個決定的理由是要防止利用那些在非特權使用者能建立並操作完整權限使用者命名空間時可能被觸及的 Kernel 漏洞。 7 一個特定的 Kernel 參數 kernel.apparmor_restrict_unprivileged_userns 被引進來管理這個限制。 4 這種方法反映了在合法沙箱用途的命名空間實用性跟減輕它們可能帶來的安全風險之間尋求平衡的努力。 4, 5, 8

這個系統使用的安全框架透過針對每個應用程式強制執行安全政策來運作。 4, 7 這些政策在設定檔中定義,指定給受限應用程式的能力和存取權限。透過控制哪些應用程式可以建立非特權使用者命名空間,系統目標是減少整體攻擊面並限制權限提升的潛力。使用者命名空間的好處跟它們作為攻擊媒介的潛力之間的緊張關係,凸顯了作業系統安全的核心挑戰:如何提供強大功能同時把相關風險降到最低。這個系統採取的方法顯示出透過選擇性控制機制來應對這個挑戰的努力。

繞過方法一技術分析:利用 aa-exec

aa-exec 是系統上的一個工具,讓非特權使用者能在指定的安全設定檔下執行程式。 4, 6 這個功能原本是想提供一種方式,讓應用程式用比使用者預設更嚴格的權限來跑,增強安全性,限制被入侵應用程式的潛在影響。不過,有些預設的安全設定檔,例如為沙箱環境(像網頁瀏覽器或容器執行環境)設計的那些,被設定成允許建立完整能力的命名空間。 4, 6 這些設定檔可能是為了讓這些應用程式正常運作所需的隔離功能而設的。

第一個找到的繞過方法利用了系統的這個特性。一個本地非特權攻擊者可以用 aa-exec 工具把執行環境轉到這些寬鬆的安全設定檔之一。 3, 6 一旦在這樣的設定檔下操作,攻擊者就能用 unshare 指令加上 --user 選項。 3, 6 unshare 是個標準 Linux 工具,用來建立新的命名空間, --user 選項特別要求建立一個新的使用者命名空間。 11, 12 因為攻擊者是在允許這麼做的安全設定檔環境下跑,這動作會成功建立一個使用者命名空間,攻擊者在裡面擁有完整的管理能力。 3, 4, 6

很重要的是要了解這個繞過不會直接給予主機系統外的 root 權限。 4, 5 但攻擊者現在能在命名空間裡執行通常需要管理權限的動作,例如掛載檔案系統或操作使用者跟群組 ID。這個有特權的環境接著可以用來試著利用需要這種能力的 Kernel 漏洞。 4, 5

針對這個特定繞過的建議防禦措施是啟用 Kernel 參數 kernel.apparmor_restrict_unprivileged_unconfined 3, 4, 6 當這個設定啟用時,它會阻止非特權且未受限的程序用 aa-exec 切換到較寬鬆、可能允許建立高權限使用者命名空間的安全設定檔。 3, 6, 7 這個措施有效阻斷了繞過的第一步,限制攻擊者進入必要的寬鬆執行環境的能力。

這個繞過的存在突顯了設計細緻安全政策的挑戰。雖然寬鬆的設定檔可能是為了某些沙箱應用程式的特定功能而設,但它們可能無意中被用來繞過更廣泛的系統級安全限制。這強調了仔細審查跟限制預設安全設定檔給予的能力的重要性,以防意外的權限提升情況。

繞過方法二技術分析:利用 busybox

busybox 是一個廣泛使用的工具,預設裝在這個作業系統的伺服器跟桌面版本上。 3, 4 它是一個單一執行檔,提供了許多常見 Unix 工具的集合,給各種系統管理任務提供了一個小巧又多功能的工具組。值得注意的是,跟 busybox 執行檔相關的預設安全設定檔也允許建立完整能力的命名空間。 3, 4 這可能是因為 busybox 提供的某些工具可能合法需要建立跟操作命名空間的能力來完成特定功能。

第二個找到的繞過方法利用了 busybox 的這個寬鬆預設安全設定檔。一個本地非特權攻擊者只要用 busybox 指令執行一個 shell 就行。 3, 4 一旦跑起了 busybox shell,攻擊者就能在這個 shell 裡直接用 unshare 指令加上 --user 選項。 3, 4 因為 busybox 程序已經在允許建立完整能力使用者命名空間的安全設定檔下跑,執行 unshare 會成功。結果是建立了一個新的使用者命名空間,攻擊者再次在這個隔離環境中獲得完整管理權限。 3, 4

跟第一個繞過方法類似,這不會提供主機系統的 root 存取權限。但攻擊者能利用命名空間內的能力,來可能利用需要提升權限的 Kernel 漏洞。 3, 4 這個繞過特別簡單,因為它依賴一個隨手可得的工具跟已經設定為寬鬆的預設安全設定檔。

針對這個繞過的建議防禦措施是,如果系統不需要透過 busybox 建立使用者命名空間的功能,就停用 busybox 的廣泛安全設定檔。 6, 7 這可以透過調整安全政策達成,要嘛移除 busybox 建立使用者命名空間的權限,要嘛如果認為 busybox 不需要這種功能,就完全停用設定檔。這個措施會防止攻擊者直接利用 busybox 建立有特權的使用者命名空間。

這個繞過的存在突顯了強大系統工具預設安全設定檔的風險。即使某些工具的功能可能合法需要提升權限或建立命名空間的能力,一個過於寬鬆的設定檔如果沒被仔細檢查跟限制,可能無意中開啟安全漏洞。這強調了深度防禦(security-in-depth)方法的重要性,對所有系統元件,包括預設工具,都應該套用最小權限原則(principle of least privilege)。

繞過方法三技術分析:利用 LD_PRELOAD

第三個找到的繞過方法利用了動態連結過程中的 LD_PRELOAD 環境變數功能。 3, 4 在 Linux 系統上執行程式時,動態連結器負責載入程式依賴的必要共享函式庫。 LD_PRELOAD 環境變數讓使用者能指定一堆共享函式庫,在其他函式庫(包括標準系統函式庫)之前先載入程序的記憶體中。 13, 14 這個機制常被用來除錯或用自訂實作覆蓋現有函式庫中的特定函數。

這個繞過的運作方式如下:一個本地非特權攻擊者可以打造一個特製的惡意共享函式庫。 3, 4 這個函式庫包含的程式碼在載入時會建立一個有完整管理能力的使用者命名空間。攻擊者接著把 LD_PRELOAD 環境變數設成指向這個惡意函式庫的路徑。 3, 4 最後,攻擊者執行一個有安全設定檔允許建立使用者命名空間的程式。 3, 4 在這個情境中提到的特定應用程式是作業系統桌面版常見的檔案管理員。 4, 7 這個應用程式可能有個寬鬆的安全設定檔,為了啟用某些使用者相關的功能,這些功能可能依賴使用者命名空間。

當目標程式(例如檔案管理員)啟動時,動態連結器會先把 LD_PRELOAD 指定的共享函式庫載入程序的記憶體中。 14 如果惡意函式庫設計成在載入時執行程式碼(例如在建構函數內),它就能接著建立有特權的使用者命名空間。 3, 4 這是在目標程式已經被其安全設定檔允許建立使用者命名空間的環境下發生的。因此,攻擊者達成了建立完整能力使用者命名空間的目標,繞過了預期的限制。 3, 4

針對這個繞過的建議防禦措施是停用像前面提到的檔案管理員這種可能允許使用者命名空間建立的應用程式的廣泛安全設定檔。 6, 7 透過讓安全設定檔更嚴格並防止應用程式建立使用者命名空間,即使預載了惡意函式庫,這個繞過也會失效。這突顯了確保即使是可能合法使用使用者命名空間的應用程式,也不應被賦予過於廣泛、可被像 LD_PRELOAD 這種技術濫用的權限的重要性。

這個繞過方法展示了一個常見的攻擊途徑,利用動態連結機制來把惡意程式碼注入執行中的程序。它依賴一個有寬鬆安全設定檔的應用程式這點,突顯了不同安全功能之間的相互關聯性。一個功能的設定弱點(安全設定檔)可以跟另一個功能(透過 LD_PRELOAD 的動態連結)結合起來,繞過預期的安全限制。

三種繞過方法的比較分析

這三種繞過方法有個共同結果:它們都讓一個本地非特權攻擊者能在命名空間內建立有完整管理能力的命名空間,有效繞過對這種動作的預期限制。此外,這三個方法都利用了安全設定檔的存在,這些設定檔直接或間接允許建立這些有特權的命名空間。

不過,每個繞過的機制跟前提條件差異很大,如下表總結:

特性 透過 aa-exec 繞過 透過 busybox 繞過 透過 LD_PRELOAD 繞過
機制 利用 aa-exec 進入寬鬆的安全設定檔 利用 busybox 的寬鬆預設安全設定檔 透過 LD_PRELOAD 將惡意函式庫注入程序
工具/公用程式 aa-exec , unshare busybox , unshare LD_PRELOAD , unshare (在注入的函式庫內)
前提條件 存在寬鬆的安全設定檔 busybox 的預設安裝與寬鬆設定檔 能建立共享函式庫並設定環境變數,目標應用程式的寬鬆安全設定檔
複雜度 中等 中等到高(需要共享函式庫知識)
防禦措施 啟用 kernel.apparmor_restrict_unprivileged_unconfined 停用 busybox 的廣泛安全設定檔 停用易受攻擊應用程式的廣泛安全設定檔

aa-exec 的繞過需要攻擊者辨識並利用一個給予必要權限的特定安全設定檔,這需要對系統安全設定有些了解。相比之下, busybox 繞過相對簡單,因為它依賴一個廣泛可用的預設工具跟預設寬鬆設定檔。 LD_PRELOAD 方法雖然在注入函式庫內能執行的動作上更有彈性,但需要更高的技術知識來打造惡意共享函式庫並了解動態連結過程,還依賴一個有合適安全設定檔的執行中應用程式。

這三種不同繞過的存在,分別針對系統安全機制的不同方式(安全設定檔執行、預設工具權限、動態連結),突顯了建立強健安全限制的固有複雜性,特別是處理像使用者命名空間這種強大 Kernel 功能跟設計來管理它們的安全框架時。這表明最初實作這些限制時,可能沒完全考慮到非特權使用者可能透過的所有途徑來獲得建立完整能力使用者命名空間的能力。

繞過的安全影響

這些繞過的主要安全影響是繞過了作業系統針對非特權使用者命名空間誤用設定的強化措施。 1, 6 成功使用這些方法中的任一個,本地沒有管理權限的攻擊者就能建立一個使用者命名空間,在裡面擁有完整管理能力,包括在該隔離環境中相當於 root 使用者的權限。 4, 5 這點特別重要,因為原本的限制就是為了防止命名空間內的這種權限提升。

雖然攻擊者不會直接拿到命名空間外主機系統的 root 存取權,但命名空間內獲得的能力可能非常危險。 4, 5 攻擊者能利用這些能力,例如 CAP_SYS_ADMIN ,來可能利用需要管理權限才能觸發的 Linux Kernel 漏洞。 1, 4 例如,某些 Kernel 漏洞可能需要掛載特定檔案系統或操作 Kernel 參數的能力,這些動作通常限制給有特權的使用者,但在完整能力的命名空間內變成可能。

雖然在建立的命名空間內濫用資源是個潛在問題,但更直接且重大的風險是權限提升到主機系統或利用其他可能導致更廣泛系統危害的 Kernel 漏洞。 3, 6 即使這些繞過單獨不會讓系統完全被控制,它們大大擴展了非特權使用者的攻擊面。結合其他漏洞或設定錯誤時,建立有特權使用者命名空間的能力可能是一個更複雜攻擊鏈中的關鍵步驟,目標是達成完整系統存取。 3, 6

因此,這些繞過的安全影響相當重大。它們有效否定了透過非特權使用者命名空間防止 Kernel 漏洞被利用的預期保護。這使得實作建議的防禦措施變得必要,以恢復受影響系統的預期安全狀態。

防禦策略及其成效

針對這些繞過的發現,安全研究員跟受影響的作業系統提出了幾個防禦策略。 3, 6 這些措施主要聚焦在收緊安全框架強制的安全政策,並限制非特權使用者利用現有寬鬆設定的能力。

一個關鍵防禦措施是啟用 Kernel 參數 kernel.apparmor_restrict_unprivileged_unconfined=1 3, 6 這個設定用於阻止 aa-exec 繞過,方法是禁止非特權且未受限的程序使用 aa-exec 工具切換到更寬鬆的安全設定檔。 3, 6 透過限制進入允許使用者命名空間建立的環境,這措施有效中和了第一個繞過方法。不過要注意的是,這個防禦措施可能不是受影響系統上的預設啟用狀態。 3, 6

另一個重要策略是停用像 busybox 這種工具跟檔案管理員這類應用程式的廣泛安全設定檔,這些設定檔允許建立使用者命名空間。 3, 6 這直接處理了第二跟第三個繞過方法。透過移除或限制這些設定檔給予的權限,攻擊者無法再直接利用這些應用程式建立有特權的使用者命名空間。但管理員在實作這個防禦措施時要小心,因為這可能影響依賴使用者命名空間執行特定任務的應用程式的合法功能。 7 在這種情況下,可能需要更具體且嚴格控制的安全設定檔。

對於像檔案管理員這種使用依賴命名空間的沙箱工具(例如 bwrap )的應用程式,更細緻的方法是專門為 bwrap 定義並套用更嚴格的安全設定檔。 3, 6 這讓應用程式能保留與使用者命名空間相關的預期功能,同時限制這些命名空間內允許的操作範圍,降低被濫用的潛力。

另外,建議使用 aa-status 工具來辨識系統上其他可能有風險的安全設定檔,這些設定檔可能無意中允許非特權使用者命名空間的建立。 3, 6 一旦辨識出來,這些設定檔應該被仔細審查,如果它們的寬鬆性質不是必要的或可能被類似繞過利用,就該停用。

受影響作業系統的開發者也表示,他們正在積極增強安全框架,以進一步減輕與非特權使用者命名空間相關的風險。 3, 6 這包括開發新功能跟收緊現有規則,以減少攻擊面並處理這些繞過暴露的限制。這些改進預計會透過作業系統支援版本的提供更新。 3, 6

建議的防禦措施集體目標是強化非特權使用者命名空間限制預期的安全邊界。透過聚焦在管理應用程式行為的安全政策,並限制非特權使用者進入允許有特權命名空間建立的執行環境,這些措施對維持系統的完整性跟安全性至關重要。主要回應涉及調整安全框架這點表明,最初限制使用者命名空間的方法高度依賴這個框架,而找到的繞過揭示了預設或常用設定的弱點。

結論

總結來說,這份報告提供了三種不同繞過方法的技術分析,這些方法讓本地非特權攻擊者能在特定作業系統中繞過對建立有完整管理能力使用者命名空間的預期限制。第一個方法利用 aa-exec 工具進入寬鬆的安全設定檔,第二個利用 busybox 的寬鬆預設安全設定檔,第三個利用 LD_PRELOAD 環境變數把惡意函式庫注入有寬鬆安全設定檔的程序。

這些繞過的安全影響很重大,因為它們讓非特權使用者能在命名空間內獲得類似 root 的權限,接著可用來利用需要提升能力的 Kernel 漏洞。雖然這些繞過不會直接給予主機系統的 root 存取權,但它們削弱了預期的安全強化,增加了權限提升跟更廣泛系統危害的潛力。

為了減輕這些風險,提出了幾個策略,包括啟用特定 Kernel 參數來限制 aa-exec 的使用,停用像 busybox 這種工具跟檔案管理員這類應用程式的廣泛安全設定檔,以及為沙箱工具採用更具體的安全設定檔。此外,持續增強安全框架的努力顯示出承諾要處理這些繞過暴露的限制,並加強作業系統對非特權使用者命名空間的整體安全狀態。實作這些建議的防禦措施對確保預期安全限制的有效性跟保護系統免於潛在利用至關重要。