基於eBPF的容器逃逸行為偵測機制研究與實作
前情提要: 這篇是我的資安研究報告,內容原本是做成docx檔案,現在為了放上blog才轉成.md
,若有沒正確轉成markdown語法而造成版面跑掉的話請多包涵:D
一、緒論
隨著容器化技術(Containerization)在各領域的廣泛應用,系統資源的管理與部署效率大幅提升。Docker、containerd 等容器平台讓應用程式在不同環境中快速部署、隔離運行並高效擴展。然而,這種虛擬化程度較低的隔離機制也帶來潛在風險——一旦攻擊者突破容器限制,可能對宿主機(Host Machine)造成嚴重威脅。
傳統上,作業系統透過 namespace 和 cgroup 機制來隔離容器與主機資源。然而,若容器被賦予過多權限(例如 –privileged),將獲得近似宿主機的能力,可能導致容器逃逸(Container Escape)攻擊。攻擊者可從受限容器中控制宿主機,取得 root 權限、存取 /etc/passwd 等敏感檔案,甚至橫向移動攻擊其他容器。
為應對這些安全威脅,eBPF(Extended Berkeley Packet Filter) 自 2014 年引入以來,憑藉其高效性與安全性,已成為容器安全監控的熱門技術。它允許使用者撰寫微型程式並安全地掛載到內核的特定 hook 點(如 syscall、kprobe),在不中斷系統運作的情況下即時監控與攔截系統行為。
報告目的:
- 探討 eBPF 如何應用於容器逃逸偵測。
- 建構實驗環境,模擬典型的容器逃逸行為。
- 使用 eBPF 偵測並聚焦於模擬簡單的 chroot 和 mount 逃逸場景。
- 驗證攻擊是否成功並能被有效捕捉,評估該偵測方法的實用性與可行性。
二、eBPF 技術背景
eBPF(Extended Berkeley Packet Filter)最初設計於1992年的BPF (Berkeley Packet Filter),用於在內核空間過濾封包,提升網路封包處理效率,傳統BPF的功能有限,僅能處理簡單的封包邏輯,而eBPF作為其延伸版本,自linux kernel 3.18以來大幅擴展能力,成為一個能在內核安全執行自訂邏輯的沙箱虛擬機。
eBPF最大的特性是: 「無需修改內核原始碼,即可即時插入內核程式邏輯」,這使它成為理想的內核觀察者,
具備以下優勢:
- 動態載入、不需重啟系統: eBPF 程式可以動態載入至特定 hook 點,例如syscall、tracing、perf event、網路等,無需修改或重編譯核心。
- 安全性設計: 所有eBPF程式都會經過內核verifier去做驗證,保證其不會進入無限迴圈、不會越界訪問、不會導致系統崩潰,因此執行於內核空間,還是有極高的安全性。
- 效能開銷低: 相比傳統syscall hooking或其他內核模組,eBPF有更低的效能損耗,適合長時間、低干擾地執行監控任務。
- 語言支援強大: eBPF 程式通常以C或Rust撰寫,Python和Go用於使用者空間的編譯、載入和資料處理。
eBPF 的關鍵組件:
- BPF程式(eBPF Program): 使用者撰寫的微型邏輯程式,會被掛載到指定的 hook 點。
- BPF Map: 內核與使用者空間共用的資料結構,可用來交換資料,如記錄事件、累積計數、傳遞訊息。
- 使用者空間Loader: 負責編譯、驗證並載入eBPF程式,常見工具如 bcc、bpftrace、libbpf。
- tracing 與 kprobe/kretprobe: eBPF可以附掛於 kernel function的進入點(kprobe)或離開點(kretprobe),實現行為追蹤。
在資訊安全的應用:
- 惡意程式偵測: 利用eBPF追蹤異常系統呼叫,如可疑的 file I/O、網路連線或權限提升。
- 容器行為監控: 追蹤容器中執行的 syscall,辨識是否有異常逃逸操作。
- RASP(Runtime Application Self Protection): RASP可利用eBPF 監控應用程式運行時的系統呼叫,動態檢測異常行為,如未授權的檔案訪問。
本次報告透過bcc工具集撰寫eBPF程式,監控容器中是否有進行chroot或 mount系統呼叫,藉此識別潛在逃逸行為。
三、容器逃逸技術概論
1. 容器逃逸的背景
容器化技術(如:Docker)為開發領域帶來極大的便捷性,尤其在資源隔離、快速部署與應用擴展方面表現突出,不過,這與虛擬機(VM)不同,容器的隔離機制較為輕量,容器和宿主機共享相同的操作系統核心(kernel),代表若容器內部的應用程序或攻擊者能突破容器內的安全限制,就有可能對宿主機或其他容器造成威脅,這種攻擊方式被稱為「容器逃逸(Container Escape)」。
容器逃逸指的是攻擊者從一個容器內部,繞過容器的隔離機制,進而取得宿主機的控制權或對其他容器造成影響。容器逃逸通常涉及利用容器的配置錯誤、漏洞或過度授權的權限進行攻擊。
2. 容器逃逸的典型手段
容器逃逸的攻擊手段多種多樣,常見的手段包括:
- 利用容器權限過高: 若容器以 –privileged 模式運行,將擁有接近宿主機的操作權限,攻擊者可以繞過容器隔離。
- 漏洞利用: 攻擊者可透過容器中運行的應用程式或內核漏洞,利用已知漏洞發起攻擊,如: CVE-2019-5736 (runc 漏洞)。
- 修改容器配置或掛載點: 攻擊者可通過篡改容器中的掛載點(例如 /proc、/sys 目錄),直接訪問宿主機的敏感檔案系統。
- 利用 chroot或 mount系統呼叫: 若容器內部的應用程式能夠調用 chroot或 mount系統呼叫,便能將根目錄或其他檔案系統映射到宿主機,從而實現逃逸。
容器逃逸行為的攻擊架構流程圖。(使用mermaid繪製)
3. 本報告的容器逃逸案例
本報告使用兩種系統呼叫作為容器逃逸的核心攻擊手段:
- chroot系統呼叫: chroot是一種將進程根目錄更改為指定目錄的操作。攻擊者通過使用 chroot可以將容器中的根目錄映射到宿主機的某一位置,從而使容器內部的進程能夠直接訪問宿主機的檔案系統。若容器有足夠權限執行 chroot,將會導致容器逃逸。
- mount系統呼叫: mount呼叫用於將外部檔案系統掛載到指定目錄。如果攻擊者能夠在容器中執行 mount操作並將宿主機的檔案系統掛載到容器中,就能夠繞過容器的隔離機制,直接進到宿主機的檔案系統,進而實現逃逸。
4. 逃逸的風險與影響
成功的容器逃逸攻擊不僅意味著攻擊者能夠繞過容器的隔離,還可能帶來嚴重的安全問題,具體影響包括:
- 取得宿主機控制權: 攻擊者可以利用容器逃逸攻擊獲得宿主機的 root權限,進而執行任意命令或改動系統設置。
- 跨容器攻擊: 一旦攻擊者成功逃逸容器,便能夠對其他容器進行橫向移動,破壞整個容器環境中的應用。
- 資料竊取與損壞: 攻擊者可讀取或修改宿主機上的敏感資料,甚至可能破壞整體系統。
5. 容器逃逸防禦
為了防範容器逃逸,企業與開發者需遵循最佳安全實踐,包括但不限於:
- 限制容器權限: 避免容器以 –privileged 模式運行,並確保容器內的應用程序不具備過多的操作系統權限。
- 使用最新的內核版本: 定期更新內核及容器平台、修補已知漏洞、加強容器配置的安全性。
- 強化系統呼叫過濾: 透過eBPF等技術,對關鍵系統呼叫(如 mount、chroot)進行監控與過濾,及時發現異常行為。
對關鍵系統呼叫(如 mount、chroot)進行監控架構圖。(使用mermaid繪製)
四、實驗環境與配置
以下內容可搭配個人實際demo影片: https://www.youtube.com/watch?v=K-QwDysbjXU
1. 環境架構總覽
本次實驗以一Ubuntu虛擬機架構進行,VM同時作為監控端(eBPF 偵測機制所在)與繞過端(發動容器逃逸行為)。
- 虛擬機作業系統: Ubuntu22.04 LTS(宿主機)、Linux 6.8.0-59-generic
- 容器映像檔: ubuntu: 22.04 (攻擊容器)
- 容器管理工具: Docker version 28.1.1
- eBPF 工具鏈: BCC(BPF Compiler Collection)
2. 系統前置安裝(Ubuntu宿主機執行)
以下操作皆於宿主機進行,用以安裝eBPF所需的套件及 Docker 環境:
1 | sudo apt-get update |
1 | sudo apt-get install -y docker.io bpfcc-tools python3-bpfcc linux-headers-$(uname -r) |
1 | sudo systemctl enable --now docker |
確認 BPF 工具能正常使用:
1 | ls /usr/share/bcc/tools/ |
3. 建立eBPF偵測程式(宿主機執行)
使用 BCC提供的 trace 工具,掛勾監控 syscall__mount和syscall__chroot,以即時偵測容器中可疑的系統呼叫:
1 | #!/usr/bin/python3 |
上面的程式碼,其中bpf_get_current_pid_tgid()要右移32位元是因為這條function是回傳 64 位元值,高32位元為 PID,低32位元為 TGID,需要右移32位元才可以提取PID。
監控時會在終端機輸出:
4. 建立攻擊容器(宿主機執行)
使用以下指令建立權限過高的容器,並將宿主機的檔案系統掛載到容器內:
1 | docker run -it--rm \ |
這段shell意思: 開啟一個可互動容器(-it)、移除容器結束後的殘留(–rm)、開啟 –privileged 權限、掛載整個 /(宿主機根目錄)至容器內的 /host。
(這個容器是簡化的場景,未來研究可嘗試無–privileged 的逃逸,相關補充可查詢CVE-2024-21626)
5. 在容器中發動逃逸攻擊(容器內部執行)
在容器內部執行下列指令以逃逸至宿主機的環境:
1 | chroot /host/bin/bash |
若成功進入宿主機根目錄,且可以直接將檔案寫入/root而不用再加上sudo,即代表逃逸成功。
同時,宿主機上開啟的 trace 命令應輸出 MOUNT與 CHROOT系統呼叫紀錄,可用作事後調查依據。
五、eBPF偵測原理
1. 為何選擇 eBPF ?
eBPF(extended Berkeley PacketFilter)原本是為高效處理封包過濾而生,但近年來演進成為一種「可安全在核心層執行使用者自定義程式」的通用技術,具備以下優點:
- 零撰寫核心模組風險: 透過verifier保證邏輯安全,不會導致Kernel crash。
- 即時性高: 直接嵌入在kernel執行流程中,無須上下文切換。
- 可掛鉤syscall: 可直接追蹤如mount、chroot等系統呼叫,為行為型偵測提供基礎。
- 支援tracepoint/kprobe/uprobe: 可追蹤核心或應用程式層的各種執行點。
2. 偵測原理概述
容器逃逸常仰賴對宿主機的掛載與chroot操作,eBPF可以在syscall層級偵測這些異常操作。
主要偵測目標:
- mount(): 將宿主機檔案系統掛載進容器。
- chroot(): 改變根目錄以達到逃逸目的。
核心偵測邏輯: - 觀察非預期的mount行為,尤其是對 / 或宿主機目錄的掛載。
- 判斷是否在容器中發生chroot,且目標為宿主機根目錄(例如: /host)。
- 搭配 PID 判斷是否來自runc或其他container runtime。
3. 輸出結果與意義
當我們在宿主機開啟上述eBPF偵測程式時,並從容器內部執行逃逸行為(chroot/host),輸出如下:
1 | b' runc:[2:INIT]-27112 [003] ...21 12818.624276: bpf_trace_printk: MOUNT by pid 27112\\n' |
runc: [2: INIT] 表示該系統呼叫發自 container 初始化進程。
pid 27112 則是可被後續手動比對或自動分析的依據。
一連串短時間內的 MOUNT→ CHROOT,表示容器進程試圖脫離原有檔案系統限制,為明顯的逃逸徵兆。
六、實驗結果與分析
1. 實驗設定回顧
本實驗於單一台Ubuntu22.04虛擬機進行,模擬如下場景:
- 宿主機安裝並執行eBPF偵測程式。
- 容器內部透過 –privileged 權限啟動後,執行掛載整個宿主機目錄(-v /: /host),再利用 chroot/host轉移執行環境至宿主機。
最後在容器內直接寫入/root,發現成功寫入/root/HACKED.txt且獲得宿主機root權限,證實逃逸成功。
2. eBPF偵測輸出分析
當容器內進行 mount與 chroot操作時,宿主機終端機立即輸出以下訊息:
1 | b' runc:[2:INIT]-27112 [003] ...21 12818.496559: bpf_trace_printk: MOUNT by pid 27112\\n' |
從輸出可以觀察出短時間內連續的 MOUNT行為,且來自同一PID,屬於典型逃逸特徵。
runc: [2: INIT] 表示該行為由 container runtime 所觸發,並非一般使用者 shell,風險更高。
透過 pid 27112 進一步交叉比對容器內外進程,可確定行為來源與目的。
3. 容器內部行為觀察
在容器中執行:
1 | chroot /host/bin/bash |
結果為真的寫入/root,表示當前shell已轉移至宿主機環境。
此時執行 ls /root等操作,皆會作用於宿主機的實體 /root目錄,若未做防護,攻擊者可直接竄改宿主機關鍵設定或寫入後門程式。
4. 安全分析與行為特徵彙整
行為 | 是否異常 | 說明 |
---|---|---|
掛載 / 或 /host | 是 | 表示容器嘗試讀取整個宿主機檔案系統 |
執行 chroot/host | 是 | 將容器內 shell 移至宿主機空間 |
使用者為 root | 需視情境 | 若容器內 root 對應宿主機 root為嚴重問題;若啟用user namespace,風險較低 |
若 PID 出現在 eBPF 輸出中,且與 runc 有關 | 是 | 多為自動化 escape 或惡意 runtime 行為 |
5. 成效總結
- eBPF 成功偵測容器內部異常的系統呼叫,實現了即時、低延遲的偵測效果。
- 在不改動 kernel 原始碼的前提下,完成行為型逃逸攻擊的準確攔截與記錄。
- 偵測邏輯簡單清晰,可進一步拓展至多種 container runtime 與複雜場景。
七、對策與建議
1. 限制容器權限: 避免使用 –privileged
本次容器能成功掛載宿主機根目錄並執行 chroot的主要原因,是 Docker 使用了 –privileged 參數。
該參數會賦予容器所有宿主機的 Linux capabilities(如 CAP_SYS_ADMIN),基本等同於 root。
建議做法:
- 除非必要,嚴禁使用 –privileged 啟動容器。
- 使用 Docker Capabilities 精細調控所需的權限,例如移除 SYS_ADMIN、SYS_CHROOT等敏感能力。
2. 文件系統掛載安全控管
攻擊中將 / 掛載至 /host,進一步配合 chroot進行空間轉移。
建議做法:
- 禁止容器掛載敏感路徑(例如宿主機的 / 或 /proc等)。
- 搭配 Seccomp 或 AppArmor 配置限制 mount() 等系統呼叫。
3. 使用eBPF持續監控敏感 syscall
本實驗展示了eBPF能有效監控 mount與 chroot系統呼叫,並記錄可疑行為。
相較於傳統 log 分析工具,eBPF 擁有以下優勢:
- 可即時追蹤內核層級活動,不需仰賴容器內部 agent。
- 可客製監控邏輯,精準匹配逃逸行為模式。
建議做法: - 常駐執行簡易eBPF探測模組,設定觸發條件與警報通知。
- 搭配 tracee、Tetragon 等開源框架建構eBPF安全監控系統。
4. 實作 Namespace 隔離強化
若容器逃逸行為未搭配完善的 namespace 隔離設計,容易成功竄改宿主系統。
建議做法:
- 啟用 user namespace,以確保容器內部 root權限對應到宿主非 rootUID。
- 使用 gVisor、Kata Containers 等加強隔離型 container runtime。
5. eBPF安全策略設計建議
偵測行為 | 建議策略 |
---|---|
mount() 呼叫 | 僅允許預先定義的 mount目的與來源 |
chroot() 呼叫 | 僅允許特定目錄或 UID 呼叫執行 |
PID 來自 runc | 加強審查 container runtime 初始化行為 |
容器 PID 與宿主機交叉 | 若 PID 同時出現在 container 與 host,可標記為異常 |
八、結論
本報告深入探討了使用eBPF偵測容器逃逸行為的可行性與實作細節,透過在單一台 Ubuntu22.04 虛擬機中進行的實驗,我們成功模擬出一個基於 –privileged權限與chroot()技術的容器逃逸案例,並證明eBPF可在不干擾系統運作的情況下,即時攔截與記錄高風險的系統呼叫(如 mount() 和 chroot()),該偵測方式具備低延遲、低開銷與高度靈活性,對於雲端原生環境中零信任架構的實現具有極高的實務價值。
從安全防禦角度來看,eBPF 並非單一解方,而是應當作一個可擴充的監控框架,與Docker權限控管、Namespace隔離、系統資源限制(如 Seccomp、AppArmor)等多層防禦機制整合。藉由持續性偵測與行為模式分析,eBPF 可有效從微觀層面補足傳統安全方案在容器場域中的不足之處。
最後,雖然本次實驗選擇使用較簡化的非CVE攻擊路徑,並僅以基本的 tracepoint 做偵測,但這也顯示出: 即使是初階的eBPF腳本與行為觀察,也能在實務中產生實質的安全防禦成效,未來可結合 ML 分析 eBPF 輸出的行為模式,實現自動化異常檢測。
此圖為此次報告完整架構圖,可以清楚看到chroot到宿主機的全過程 (使用mermaid繪製)
九、心得
這份的主題啟發來自最近跟著實驗室在做專題時,同一台伺服器上有許多docker容器,有的容器是已對外公開的網頁,有的是對外公開的API,那我要怎麼確保我自己開的docker不會去影響到其他學長姐的成果,所以我就從這個角度往資安方向去做衍生,最一開始想的是: 我有可能可以從我的docker裡面去影響到全域的環境變數嗎? 還真的被我找到一篇2019年的漏洞,不過它可以直接造成RCE就是了,CVE編號: CVE-2019-5736,主要是在講二進位檔案會造成RCE,詳細邏輯不詳談,但事實是可以做得到的。
再來就是去年的CVE-2024-8695、CVE-2024-8696、CVE-2024-21626,這三篇基本上都是容器逃逸的實際漏洞,也因此這份報告選用chroot 和 mount 作為模擬場景,而這些CVE邏輯跟這份報告所做的差不多,只是需要多加一些bypass的地方需要更深入研究,如果有空想要復現的話就把–privileged拿掉,不要讓docker容器權限這麼高,再實際去exploit-db找腳本試,應該也是個蠻好玩的復現(個人覺得這總比apache好玩多了xd),這次最困難的地方大概是釐清一些eBPF的基本機制和環境吧,繞過的邏輯順了以後其實沒有太難,基本上有一大半的時間都在調整環境,一下子linux headers版本衝突,一下子docker環境不符合,一下子又抓不到bcc位置,中途還想說再不行我就鬼轉題目來研究了,不過好險最後一步一步的調整就成功復現了!
十、部分參考資料
GitHub:
https://github.com/iovisor/bcc,
https://github.com/aquasecurity/tracee,
https://github.com/pathtofile/bad-bpf,
Linux中基於eBPF的惡意利用與檢測機制: https://kknews.cc/zh-tw/n/gx6j5y9.html
分享一些eBPF技术相关的PDF: https://www.cnxct.com/ebpf-slide-pdf-share/#ftoc-heading-3
复现基于eBPF实现的Docker逃逸: https://drivertom.blogspot.com/2022/01/ebpfdocker.html
黑客利用 Linux eBPF 持续传播恶意软件: https://www.anquanke.com/post/id/302837
DEFCON: https://defcon.org/html/defcon-29/dc-29-speakers.html#path
Day04 - (攻擊) 容器逃逸手法 nsenter: https://ithelp.ithome.com.tw/m/articles/10316981
eBPF linux運行時惡意利用: https://v.qq.com/txp/iframe/player.html?vid=e33246j5zi5
datadog的eBPF安全检测机制分析: https://mp.weixin.qq.com/s/SAPz4Z1m2gVtQWzt68u6eg