容器鏡像的脆弱性分析

  • 2019 年 12 月 11 日
  • 筆記

1.容器鏡像概述

鏡像是容器運行的基礎,容器服務引擎可以使用不同的鏡像啟動相應的容器實例。在容器實例出現異常後,能迅速通過刪除實例、啟動新的容器實例來恢復服務,這些靈活、敏捷的操作,均需要以容器鏡像作為支撐技術。

與虛擬機所用的系統鏡像不同,容器鏡像不僅沒有Linux系統內核,同時在格式上也有很大的區別。虛擬機鏡像是將一個完整的作業系統封裝成一個鏡像文件,而容器鏡像不是一個文件,是分層存儲的文件系統。

圖1 容器鏡像結構

上圖是Docker鏡像分層存儲的示意圖,從圖中可以看出,每個鏡像都是由一系列的「鏡像層」組成。當需要修改鏡像內的某個文件時,只會對最上方的讀寫層進行改動,不會覆蓋下層已有文件系統的內容。當提交這個修改生成新的鏡像時,保存的內容僅為最上層可讀寫文件系統中被更新過的文件,這樣就實現了在不同的容器鏡像間共享鏡像層的效果。

容器鏡像通常會通過鏡像倉庫(Registry)進行存儲和管理。根據Registry服務的提供者、鏡像存儲位置、訪問控制等因素,可以將其分為公共倉庫和私有倉庫。

因此,對於鏡像的來源,無非就是這兩種渠道:或者是通過公共的鏡像倉庫獲取,比如Docker官方的Docker Hub、或者是中國的網易163、中科大(USTC)、daocloud、阿里雲等;或者是用戶自己維護一個私有倉庫,比如採用Harbor,團隊所有成員將相關的鏡像上傳至私有倉庫,供其他成員使用。

對於開發者來說,公共倉庫獲取鏡像的便利性,使其成為很多開發者獲取鏡像的重要途徑。從Docker Hub顯示的數字來看,Nginx、Redis、Tomcat等常用應用的鏡像下載量,均在千萬以上的數量級。中國信通院2018年3月份發布的《開源治理白皮書》[1]中提到,截至2014年底,容器鏡像下載量高達1億,到2017年初,這一數量超過80億。

2.開源軟體風險分析

提及容器鏡像,不得不提的就是開源軟體,根據Gartner的調查顯示,99%的組織在其IT系統中使用了開源軟體,同時開源軟體在伺服器作業系統、雲計算、Web等領域都有比較廣泛的應用。而從Docker Hub中可以看到,幾乎所有常用的開源軟體,均可以在公共倉庫中找到相應的Docker鏡像,比如TensorFlow、Kafka、Pytorch、Zepplin等。

圖2 Docker Hub中的TensorFlow鏡像檢索

回到安全的角度來看,容器鏡像作為開源軟體使用的一個載體,要解決容器鏡像的安全問題,那麼開源軟體所面臨的安全風險,是必然要考慮的一個問題。

比如:(1)確認已經解決已知的安全漏洞(包括自研程式碼和引用的第三方程式碼),如軟體注入漏洞等。如仍然存在顯著漏洞,應予以修補,避免開放被使用後影響公眾安全;(2)確認開源程式碼和文檔中是否存在泄漏用戶隱私和商業秘密的情況;(3)確認是否泄漏了秘鑰、帳號、密碼、測試IP地址、埠、測試用例等敏感資訊;(4)確認是否包含挖礦程式、後門程式、病毒、木馬等惡意程式碼。

開源軟體存在的安全問題中,安全漏洞是一個重要的問題,根據NVD數據統計,截至2017年2月,全球開源軟體相關的已知安全漏洞已超過28000個。截至2017年2月,美國國土安全部累計檢測各種開源軟體7000多個,發現大量安全缺陷。系統資訊泄露、密碼管理、資源注入、跨站請求偽造、跨站腳本、HTTP消息頭注入、SQL注入、跨界訪問、命令注入、記憶體泄露等是開源軟體主要的安全風險。

圖3 開源軟體項目缺陷總數

開源軟體帶來的安全風險[2],近年來頻繁的被揭露出來。例如,2017年,Equifax指責開源Apache Struts被用於網路攻擊,導致了1.43億條記錄的泄露。同一年,Black Duck Software的研究人員通過對企業中1,000種常用應用程式的審計發現,96%的企業使用開源軟體,60%以上包含由於這些組件造成的安全漏洞。一些被發現的漏洞已存在超過了四年之久。

2017年11月,Uber發布聲明,承認2016年曾遭黑客攻擊並導致數據大規模泄露。根據這份聲明,兩名黑客通過第三方雲服務對Uber實施了攻擊,獲取了5700萬名用戶數據,包括司機的姓名和駕照號碼,用戶的姓名、郵箱和手機號。調查發現,Uber數據泄露的原因竟然是工程師將解鎖資料庫的安全密鑰存儲在GitHub的一個可以公開訪問的頁面。

3.鏡像脆弱性分析

對於容器鏡像的安全性來說,開源軟體的安全風險僅僅是容器鏡像脆弱性的一個子集。下面本文將詳細介紹容器鏡像所面臨的脆弱性問題。

1鏡像來源

3.1.1 公共鏡像的安全威脅

從用戶角度來看,容器鏡像在獲取途徑上,我們將其分為「從公共倉庫獲取」以及「從私有倉庫獲取」兩種,那麼對於從公共倉庫獲取的鏡像,最重要的兩個脆弱性問題:一方面是鏡像中軟體的安全漏洞問題;另一方面是鏡像內的挖礦程式、後門程式、病毒、木馬等惡意程式。

容器的鏡像,從某種意義上來看,其實就是系統軟體或者是應用軟體的一種交付形式,那麼從安全的角度來看,軟體漏洞將是給軟體帶來安全風險的最直接也是最重要因素,因此討論容器鏡像的安全,首要考慮的因素就是鏡像中軟體漏洞的管理。

有關研究報告[3]顯示,Docker Hub中超過30%的官方鏡像包含高危漏洞,接近70%的鏡像有著高危或中危漏洞。

筆者從Docker Hub中選擇評價和下載量較高的10個鏡像,對其最新版本(latest)採用Clair工具進行了掃描分析。從結果可以看出,如此高頻率使用的鏡像,絕大多數均存在高危漏洞,有的鏡像高危漏洞數量甚至達到數十個之多。

圖4 Docker Hub中部分鏡像漏洞情況統計

當然,筆者這裡對於公共倉庫中鏡像的漏洞統計,只是採用開源的工具,直接對鏡像的漏洞進行了一個簡單的掃描分析。對於這樣的結果,並不代表公共倉庫的鏡像真的就危險到不可以使用。當然也不能排除掃描工具在漏洞處理上存在的一些問題。

由於公共倉庫是對所有用戶開放的,任何用戶都可以從倉庫中獲取現有的容器鏡像,當然也可以將自己製作的鏡像上傳至公共倉庫,供其它用戶使用。如果有黑客在製作鏡像時植入木馬、後門等惡意軟體,並將惡意鏡像上傳至Docker Hub等公共倉庫,那麼用戶的容器環境從一開始就已經不安全了,後續更沒有什麼安全可言。

比如Docker對鏡像不安全的處理管道,Docker支援三種壓縮演算法,分別是gzip、bzip2、xz。gzip和bzip2使用Go的標準庫,所以相對安全;xz由於沒有使用原生的Go去實現,又由於其使用由C編寫的XZ Utils開源項目,所以存在C程式惡意寫入的可能,一旦被寫入會導致執行任意程式碼漏洞,而只要有一個漏洞,執行docker pull拉取鏡像時就有可能導致整個系統淪陷。

2018年6月,就有安全廠商發現17個受到感染的Docker容器鏡像[4],鏡像中包含了可用於挖掘加密貨幣的程式,更危險的是,這些鏡像的下載次數已經高達500萬次。

對於特定某文件,一般可以使用殺毒軟體進行掃描以確定該文件是否安全,但是目前的殺毒軟體並沒有能夠很好支援鏡像的掃描。用戶想確認下載的鏡像是否安全,只能仔細檢查下載的源是否有後門(比如運行鏡像,然後在裡面安裝殺毒軟體掃描),並且確認請求指向官方源。

3.1.2 私有鏡像的安全威脅

對於私有倉庫中的鏡像,通常是用戶自己製作上傳生成的,那麼其脆弱性一方面包括軟體程式碼本身的脆弱性,另一方就是配置的風險。

軟體程式碼的脆弱性,不僅需要在開發過程中儘可能遵循SDL(安全開發生命周期),在開發完成後,同樣需要進行程式碼審計、滲透測試等安全檢查,保證應用的鏡像在生成之前,已經解決所有已知的程式碼漏洞。

在製作鏡像的過程中,鏡像內是否包含了帳號密碼等資訊、是否包含了秘鑰文件資訊、是否暴露其它敏感資訊、是否運行了禁止運行的命令等問題,在鏡像入庫之前,也是要重點進行檢測的。

另外,用戶在使用容器的時候,很自然地會和虛擬機進行類比,比如怎麼進入容器內進行調試、sshd怎麼配置等。要正確的使用容器,一定要有容器化的思維,正確的認識容器。特別是在微服務體系中,容器的本質就是一個或少數進程以及運行進程所需要的各種依賴,即運行時環境的最小集。因此,在鏡像製作過程,一定要儘可能的只運行必要的服務,只暴露出必要的埠。

如果在容器中運行了SSH、TELNET等服務,不僅不會增加該微服務的功能,反而會帶來一系列的安全威脅以及增加安全運維的複雜度。比如SSH服務的訪問策略和安全合規性管理、各種容器的秘鑰以及密碼管理、SSH服務安全升級等。

2鏡像傳輸

容器鏡像在下載和上傳時需保證完整性和秘密性,以下建議有助於抵禦如中間人攻擊等威脅:

(1)數字簽名。上傳者主動給要上傳的鏡像簽名,下載者獲取鏡像時先驗證簽名再使用,防止其被惡意篡改。

(2)用戶訪問控制。敏感系統和部署工具(註冊中心、編排工具等)應該具備有效地限制和監控用戶訪問許可權的機制。

(3)儘可能使用支援HTTPS的鏡像倉庫。為避免引入可疑鏡像,用戶謹慎使用–insecure-registry選項連接來源不可靠的HTTP鏡像倉庫。

4. 鏡像脆弱性評估示例

當前,針對容器鏡像的脆弱性問題,一些容器安全的廠商以及開源項目,均提供了相應的檢測能力,下表[5]中對幾個常見的掃描工具從功能、開源等幾個方面進行了對比分析。

對於鏡像的脆弱性檢測,其中涉及到幾個核心的環節。檢測工具需要獲取當前的所有漏洞資訊,通常會從主流的漏洞平台獲取,比如NVD。

獲取待檢測鏡像,並針對鏡像的每一層進行解析,獲取到鏡像中所有的軟體包以及對應的版本資訊。

這樣,根據軟體包的版本資訊以及漏洞庫資訊,就可以對容器鏡像內的應用軟體進行CVE的檢測了。

在對容器鏡像進行解析的時候,不僅可以獲取到相應軟體包的版本資訊,同時還能精確的分析到鏡像內的所有文件。這樣假如存在「/etc/ssh/ssh_host_dsa_key」、「/home/user/.ssh/id_rsa」這樣的敏感秘鑰資訊,可以對其進行告警。

下面,我們使用Clair(latest)針對Ubuntu 14.04進行掃描測試,並嘗試進行漏洞修復。

首先對Ubuntu:14.04鏡像進行掃描(clairctl analyze registry.securityapp.store/library/ubuntu:14.04 –log-level Debug),掃描過程如下圖所示。

經過逐層的分析,掃描結果如下圖。

使用clairctl將所報漏洞以報表(html格式)的形式輸出(clairctl report -l registry.securityapp.store/library/ubuntu:14.04 –log-level debug),過程如下圖所示。

使用docker cp(docker cp fda246b5625c:/reports/html/analysis-registry.securityapp.store-library-ubuntu-14.04.html /tmp/)將html文件輸出至本地後,用瀏覽器打開報表。

由上圖可以看出,報告中已經將高、中、低以及可忽略的漏洞友好的分類顯示出來,其中高危漏洞1個,中危漏洞50個,低危漏洞78個,可忽略漏洞24個。此處我們將高危漏洞找出,具體漏洞如下圖所示。

點擊漏洞鏈接可知目前官方的Ubuntu 14.04 LTS(Trusty Tahr)已發布了release版本2.19-0ubuntu6.14,修復了此漏洞。

接下來,我們將含有漏洞的鏡像運行為容器(docker run -dt –name ubuntu-test-clair registry.securityapp.store/library/ubuntu:14.04),並且進入容器內部(docker exec -it 9bcf21a481d0 /bin/bash),過濾查看容器內含有漏洞的軟體包資訊,看到漏洞版本號為2.19-0ubuntu6.13。

然後對這兩個軟體包進行升級,待升級成功後,再次查看包的版本資訊,已升級為最新版本2.19-0ubuntu6.14,如下圖所示。

將這個容器打包為一個新的鏡像(docker commit 9bcf21a481d0 ubuntu-fixed-clair),並上傳是鏡像倉庫(docker tag ubuntu-fixed-clair:latest registry.securityapp.store/test/ubuntu-fixed-clair:latest,docker push registry.securityapp.store/test/ubuntu-fixed-clair:latest)。

通過Clair掃描這個漏洞修復後的鏡像(clairctl analyze -l registry.securityapp.store/test/ubuntu-fixed-clair:latest –log-level debug),掃描結果如下圖所示。

從掃描結果可以看出,之前含有高危漏洞的Ubuntu 14.04鏡像經過手動修復漏洞並重新打包為新的鏡像後,之前的高危漏洞已不存在。

參考文獻:

[1] 開源治理白皮書(2018), http://www.caict.ac.cn/kxyj/qwfb/ztbg/201804/P020180323313495961952.pdf

[2] 2018 Open Source Security and Risk Analysis, https://www.synopsys.com/content/dam/synopsys/sig-assets/reports/2018-ossra.pdf

[3] Over 30% of Official Images in Docker Hub Contain High Priority Security Vulnerabilities, https://www.banyanops.com/blog/analyzing-docker-hub/

[4] Tainted, crypto-mining containers pulled from Docker Hub, https://techcrunch.com/2018/06/15/tainted-crypto-mining-containers-pulled-from-docker-hub/

[5] https://www.meetup.com/Cloud-Native-days-china/events/251975991/