容器安全管理


容器和虛擬機

容器和虛擬化都是系統虛擬化的實現技術,可以實現系統資源的共享。相較於虛擬機,容器技術是一種“輕量”的虛擬化方式,虛擬機通常在Hypervisor層實現對硬件資源的虛擬化,Hypervisor為虛擬機提供了虛擬的運行平台,管理虛擬機的操作系統運行,每個虛擬機都有自己的操作系統、系統庫以及應用。而容器並沒有Hypervisor 層,每個容器是和主機共享硬件資源及操作系統 ,容器技術在操作系統層面實現了對計算機系統資源的虛擬化,在操作系統中,通過對 CPU、內存和文件系統等資源的隔離、划分和控制,實現進程之間透明的資源使用。

容器的安全機制及缺陷

容器因其輕量,不受運行環境的依賴、能很好的支持CI/CD(持續集成和持續部署)等特性,在快速發展的信息時代也備受開發者青睞。不同於虛擬機可以創建完全隔離的環境並實現完全虛擬化,容器共享宿主機內核和資源,在隔離性上存在一定安全風險,例如虛擬機逃逸風險,會導致對其他容器甚至是宿主機造成威脅。

容器主要通過Linux 內核的Cgroup和Namespace兩大特性來實現資源限制和環境隔離。

  • Cgroups

Cgroups 是 control groups 的縮寫,是 Linux 內核提供的一種可以限制、記錄、隔離進程組(process groups)所使用的物理資源(如:cpu,memory,IO等等)的機制。

  • Namespace

Linux Namespace提供了一種內核級別隔離系統資源的方法,通過將系統的全局資源放在不同的Namespace中,來實現資源隔離的目的,提供了對 UTS、IPC、Mount、PID、Network、User 等的隔離機制,但Linux內核的namespace機制並不完善、不能實現完全的隔離:

- /proc、/sys等未完全隔離
- Top, free, iostat等命令展示的信息未隔離
- Root用戶未隔離
- /dev設備未隔離
- 內核模塊未隔離
- SELinux、time、syslog等所有現有Namespace之外的信息都未隔離

容器的安全風險面

  • 鏡像安全
  • 逃逸風險
  • 網絡風險
  • 拒絕服務風險
  • 生態安全

鏡像安全

鏡像是docker容器的靜態表現形式,鏡像的安全決定了容器運行時的安全,鏡像的風險面主要分為如下四類:

  • 鏡像漏洞:如果鏡像本來就存在cve、應用組件、語言包漏洞甚至是惡意上傳的后門鏡像等,開發者在從倉庫(如 :docker hub 、阿里雲等第三方鏡像倉庫)拉取鏡像進行開發時就會直接引入安全風險,增大了容器的風險面。
    針對容器鏡像的安全掃描工具有:trivy、clair、Anchore、Quay等,可以嵌入CI流水線、和鏡像倉庫集成,實現在開發階段就及時發現安全風險。
  • 鏡像倉庫:用於存儲容器鏡像的倉庫,安全風險主要包括倉庫本身的安全風險和鏡像拉取傳輸過程中的風險。
    倉庫本身的安全風險例如,將私有鏡像倉庫配置不當端口對外了、倉庫存在越權漏洞可以創建管理員(CVE-2019-16097:Harbor任意管理員注冊)。
    鏡像傳輸過程中風險包括,如何確保容器鏡像從鏡像倉庫到用戶端的完整性,不被中間人劫持、篡改。Docker已在其1.8版本后采用內容校驗機制解決中間人攻擊的問題,但非默認配置,需主動開啟(export DOCKER_CONTENT_TRUST = 1)。
  • dockerfile
    鏡像構建的方式通常有兩種:基於容器直接構建或基於dockerfile構建,基於dockerfile構建的鏡像是“透明”的,所有指令都可以追溯,其中的安全風險在於正確使用鏡像指令和敏感信息的處理:
    • 指令的正確選擇:在Dockerfile中沒有指定USER,Docker將默認以root用戶的身份運行該Dockerfile創建的容器,如果該容器遭到攻擊,那么宿主機的root訪問權限也可能會被獲取;若需引入外部文件,在 Dockerfile 中能用COPY 指令就不要使用ADD 指令,因為COPY 指令只是將文件從本地主機復制到容器文件系統,ADD 指令卻可以從遠程 URL 下載文件並執行諸如解壓縮等操作,這可能會帶來從 URL 添加惡意文件的風險。
    • 防止敏感信息泄露:如果在Dockerfile文件中存儲了固定密碼等敏感信息並對外進行發布,則可能導致數據泄露的風險。
    • 最小必要原則:在編寫指令時,只添加必要的應用和服務,ssh、telnet等高危服務若不使用就不必開啟。

逃逸風險

容器逃逸攻擊指的是容器利用漏洞,“逃逸”出了其自身所擁有的權限,實現了對宿主機和宿主機上其他容器的訪問。

  • Linux內核漏洞:CVE-2016-5195 Dirty Cow (臟牛漏洞)
    該漏洞是Linux內核的內存子系統在處理寫時拷貝(Copy-on-Write)時存在條件競爭漏洞,導致可以破壞私有只讀內存映射,黑客可以獲取低權限的本地用戶后,利用此漏洞獲取其他只讀內存映射的寫權限,進一步獲取root權限。
    Linux Kernel版本不低於2.6.22 的所有 Linux 系統(從 2007 年發布 2.6.22 版本開始,直到2016年10月18日為止,這中間發行的所有 Linux 系統都受影響),可自查Linux內核版本 uname -a

    exp:git clone https://github.com/gbonacini/CVE-2016-5195.git

  • docker軟件漏洞
    a. Shocker攻擊
    通過調用open_by_handle_at函數(能夠讀取文件的函數)對宿主機文件系統進行暴力掃描,以獲取宿主機的目標文件內容。由於Docker1.0之前版本對容器能力(Capability)使用黑名單策略進行管理,並沒有限制CAP_DAC_READ_SEARCH能力,賦予了shocker.c程序調用open_by_handle_at函數的能力,導致容器逃逸的發生。
    洞影響版本:Docker版本< 1.0, 存在於 Docker 1.0 之前的絕大多數版本。
    exp:https://github.com/gabrtv/shocker

    b. runC容器逃逸 CVE-2019-5736
    runc:一個基於OCI (Open Container Initiative)標准的輕量級工具,用於創建和運行容器。
    漏洞允許惡意容器(以最少的用戶交互)覆蓋host上的runc文件,從而在host上以root權限執行任意代碼。所有使用到runc的容器服務和產品(如Docker、Kubernetes等)均受漏洞影響。
    環境安裝:curl https://gist.githubusercontent.com/thinkycx/e2c9090f035d7b09156077903d6afa51/raw -o install.sh && bash install.sh
    POC: git clone https://github.com/Frichetten/CVE-2019-5736-PoC

    c.dcker cp命令逃逸 CVE-2019-14271
    當docker使用cp命令(實現容器和宿主機的文件拷貝)時,會調用在宿主機命名空間中的docker-tar,加載位於容器中的libnss_.so庫,當容器被攻擊者控制或存在惡意鏡像時,攻擊者可以通過替換libnss_.so庫為惡意代碼並將其注入到docker-tar中,實現docker逃逸、獲得宿主機權限。

    docker-tar的原理是chroot到容器中,歸檔其中請求的文件及目錄,然后將生成的tar文件傳回Docker守護進程,該進 
    程負責將文件提取到宿主機上的目標目錄中。
    docker-tar的原理其實是使用了chroot,其實就是設置了一個根目錄,將要請求的文件與目錄放到這個根目錄中去,生成一個tar文件,然后再將這個tar文件交給docker的守護進程,由守護進程將文件復制到目標文件夾中去。
    
  • 配置不當導致逃逸

    • Docker Remote API 未授權訪問
      Docker Remote API可以實現對容器的遠程系統命令控制,相當於在dcoker界面執行指令;攻擊者利用該未授權漏洞API能遠程控制docker容器,實現容器逃逸、進而危害到宿主機,被廣泛用於挖礦、蠕蟲病毒等。
      復現環境 https://github.com/vulhub/vulhub/tree/master/docker/unauthorized-rce

    • docker.sock 掛載到容器內部
      是Docker守護進程(Docker daemon)默認監聽的Unix域套接字(Unix domain socket),容器中的進程可以通過它與Docker守護進程進行通信,當其被掛載在容器內時,攻擊者可利用 docker.sock 和docker deamon 通信,運行一個高權限的惡意容器,進而實現逃逸。

    • docker 高危啟動參數
      a. privileged 特權模式
      當docker用特權模式啟動時 ----privileged ,相當於放開了容器和宿主機對 Network,PID,IPC namespace命名空間的限制,攻擊者可通過--volume 將宿主機根目錄掛載進容器中,直接實現逃逸。

      b. 敏感目錄掛載
      例如將宿主機root目錄掛載至容器,寫入ssh密鑰后獲得宿主機權限
      docker run -itd -v /root:/root ubuntu:18.04 /bin/bash

      c. 相關啟動參數的安全問題
      docker通過linux namespace實現 主機名、用戶權限、文件系統、網絡、進程號、進程間通訊等資源的隔離,當啟動時如果給予容器的權限過高就可能導致逃逸發生。

網絡安全風險

 - 橋接模式(bridge):在默認的bridge網絡模式下,docker主機上的容器都會使用docker0這個網關,容易造成ARP欺騙、端口嗅探等,建議是自行給容器分配網絡 或使用docker swarm、kubernetes等容器集群管理平台,創建集群間的overlay網絡。

  • 主機模式(host):host模式會有更好的網絡性能,因為其使用了主機的本地網絡堆棧,共享網絡命名空間(漏洞案例:host模式容器逃逸漏洞 cve-2020-15257);但此時 容器將共享主機的網絡堆棧,容器能看到主機的所有端口,使容器有了訪問主機本地系統服務的全部權限。

  • none模式:在這種模式下,Docker容器擁有自己的Network Namespace,但是,並不為Docker容器進行任何網絡配置。也就是說,這個Docker容器沒有網卡、IP、路由等信息。需要我們自己為Docker容器添加網卡、配置IP等。

  • container模式:這個模式指定新創建的容器和已經存在的一個容器共享一個Network Namespace,而不是和宿主機共享。新創建的容器不會創建自己的網卡,配置自己的IP,而是和一個指定的容器共享IP、端口范圍等。同樣,兩個容器除了網絡方面,其他的如文件系統、進程列表等還是隔離的,兩個容器進程通過lookback網卡通信。

拒絕服務攻擊

由於容器和宿主機共享內核資源,因此當存在資源爭搶時容易出現拒絕服務攻擊,例如計算資源、存儲資源、網絡資源等。

  • 計算資源
    主機內核正常情況下只能支持一定數量的進程,如果某個容器內的進程組新建過多進程,消耗了主機上的所有進程資源,那其他容器就沒有新資源來創建進程,甚至會危害到宿主機資源的正常使用,攻擊案例 如fork bomb ,可以通過限制容器資源使用降低相關風險,--kernel-memory=#M
Fork Bomb是一類典型的針對計算資源的拒絕服務攻擊手段,其可通過遞歸方式無限循環調用fork()系統函數快速創建大量進程。
  • 存儲資源
    docker通過mount命名空間實現文件系統隔離,但沒有對docker使用的AUFS文件系統做限制,導致容器可以通過無限寫入文件來打滿存儲空間,從而造成存儲資源的拒絕服務。

  • 網絡資源
    攻擊者使用大量的受控主機向被攻擊目標(容器)發送大量的網絡數據包,以占滿容器的網絡寬帶,並消耗容器主機的網絡數據處理能力,實現網絡資源的拒絕服務。

生態安全

docker的廣泛用於也促進了整個雲原生生態的發展,包括編排系統(常見的例如k8s)、微服務、devops(devsecops)等。

參考

《容器安全風險解決方法上/下篇》
《容器安全白皮書-綠盟2018》
https://blog.fundebug.com/2017/04/17/about-docker-sock/
https://yangrz.github.io/blog/2018/04/13/docker/
https://github.com/Kutim/docker-security
https://www.secrss.com/articles/2947
https://www.dosec.cn/dosecwp.pdf
https://www.jianshu.com/p/89b329626621
https://github.com/xxg1413/docker-security/blob/master/shocker/shocker-cn.md
https://www.cnblogs.com/xiaozi/p/13423853.html
https://dockerdocs.cn/engine/security/index.html#conclusions


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM