最近提交了一些關于 docker remote api 未授權訪問導致代碼泄露、獲取服務器root權限的漏洞,造成的影響都比較嚴重,比如
因為之前關注這一塊的人并不多,這個方法可以算是一個“新的姿勢”,本文對漏洞產生的原因和利用過程進行簡單的分析和說明,但因為時間和精力有限,可能會有錯誤,歡迎大家指出~
先介紹一些東西~
docker swarm
docker swarm 是一個將docker集群變成單一虛擬的docker host工具,使用標準的Docker API,能夠方便docker集群的管理和擴展,由docker官方提供,具體的大家可以看官網介紹。
漏洞發現的起因是,有一位同學在使用docker swarm的時候,發現了管理的docker 節點上會開放一個TCP端口2375,綁定在0.0.0.0上,http訪問會返回 404 page not found
,然后他研究了下,發現這是 Docker Remote API,可以執行docker命令,比如訪問 http://host:2375/containers/json
會返回服務器當前運行的 container列表,和在docker CLI上執行 docker ps
的效果一樣,其他操作比如創建/刪除container,拉取image等操作也都可以通過API調用完成,然后他就開始吐槽了,這尼瑪太不安全了。
然后我想了想 swarm是用來管理docker集群的,應該放在內網才對。問了之后發現,他是在公網上的幾臺機器上安裝swarm的,并且2375端口的訪問策略是開放的,所以可以直接訪問。
尼瑪這一想,問題來了:
因為這位同學剛好有其他事情要忙,沒時間擼,我之前也用過docker,所以我就繼續研究了,然后就走上了挖掘新姿勢的不歸路...
要查清楚是誰的鍋,首先要復現下問題,那么只有一種方法,照的文檔裝一遍docker swarm。
官網給出創建Docker Swarm集群的方法有:
這里使用官方推薦方法,系統使用ubuntu14.04,按照 Build a Swarm cluster for production 這篇文檔裝了一遍。
這里簡單描述下過程:
這里的第三點就是前面提到的暴露的docker端口,我們來看一下文檔中docker 節點具體執行的命令
sudo docker daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
-H參數指定docker daemon綁定在了 tcp://0.0.0.0:2375
上。
docker默認安裝的時候只會監聽在 unix:///var/run/docker.sock
,因此這里是端口暴露的原因所在。
那么能不能說這個是 docker swarm 的鍋呢?
我們來看一下文檔中的安裝環境
Prerequisites
An Amazon Web Services (AWS) account
Familiarity with AWS features and tools, such as:
Elastic Cloud (EC2) Dashboard
Virtual Private Cloud (VPC) Dashboard
VPC Security groups
Connecting to an EC2 instance using SSH
是在AWS VPC上,默認的訪問策略是
AWS uses a “security group” to allow specific types of network traffic on your VPC network. The default security group’s initial set of rules deny all inbound traffic, allow all outbound traffic, and allow all traffic between instances.
即禁止所有的外網端口訪問,文檔中之后的部分修改了策略允許22和80端口訪問,也就說在文檔的環境中,不會存在2375端口暴露的問題,且文檔中也提到了不要讓docker 的端口暴露在外,雖然沒有加字體加粗高亮~
For a production environment, you would apply more restrictive security measures. Do not leave Docker Engine ports unprotected.
然而即使高亮了也沒有軟用,首先是使用者并不一定有類似AWS的VPC環境,再者不是每個使用者都會認真的看文檔,所以最終的結論是,這鍋docker官方和使用者都得背,誰背的多就不好說了~
說如何利用之前,我們先整理下現在能做的事情
?執行docker命令,比如操作container、image等
那么如果當前運行的container,或者image內有代碼或者其他敏感信息,就可以繼續深入了,比如果殼和蜻蜓fm的漏洞,就是深入后的結果。
還有的話,可以做內網代理,進一步滲透。
到目前為止,我們能做的事情都是在docker的環境內,無法直接控制宿主機。
那么怎么才能控制宿主機呢?莫慌,分析下
docker是以root權限運行的,但docker執行命令只能在container內部,與宿主機是隔離的,即使是反彈一個shell,控制的也是container,除非有0day,不然是無法逃逸的到宿主機的~
那么只能從docker命令本身下手,腦洞開了下,想到docker 運行 container的時候,可以將本地文件或目錄作為volume掛載到container內,并且在container內部,這些文件和目錄是可以修改的。
root權限進程,并且能夠寫文件,是不是似曾相識?
這里的場景和前段時間的 redis + ssh 漏洞很相似,那么這里需要看一下服務器是否有ssh服務,如果有的話,那么直接把/root/.ssh目錄掛載到container內,比如/tmp/.ssh,然后修改/tmp/.ssh/authorized_keys 文件,把自己的public key寫進去,修改權限為600,然后就可以以root用戶登錄了。
注:有些服務器會配置不允許root用戶直接登錄,可以通過掛載 /etc/ssh/sshd_config 查看配置。這個時候,你換一個用戶目錄寫入就行,并且掛載修改 /etc/sudoers 文件,直接配置成免密碼,sudo切換root即可。
如果沒有運行ssh服務,那么也可以利用掛載寫crontab定時任務,比如ubuntu root用戶的crontab文件在 /var/spool/cron/crontabs/root,反彈一個shell~
這里利用方式可能還有很多種,大家可以開下腦洞想哈~
影響總結:攻擊者可以利用該漏洞執行docker命令,獲取敏感信息,并獲取服務器root權限
目前在公網上暴露的2375端口還有不少,測了一些基本都可以利用。
但docker swarm更多的情況是用在企業內部,雖然在內網,也不意味著絕對安全,當邊界被突破,就嘿嘿嘿了~
注:因為本小節內容是看了文檔后的個人理解,并且部分內容未進行實際驗證,可能會錯誤,僅供參考!
如果你的2375端口是暴露在公網的,那么最簡單的方式就是禁止外網訪問或者設置白名單,因為根據官網介紹,swarm本來就不應該在公網中使用。
以上方法僅僅防止了外網訪問,但如果本身已經在內網,對于已經擼進內網的攻擊者,端口仍然處于可以直接訪問的狀態,那么有沒一些防護方案呢?
為了找到答案,特意看了下docker swarm的文檔,Plan for Swarm in production 這篇文章提到了兩種方案
?然而在我對公網中使用TLS的docker remote api(使用2376端口)測試中發現,即使沒有證書,Docker CLI仍然可以正常訪問,這里我也拿docker python api寫了腳本,設置不驗證證書有效性,也同樣可以訪問。
因為這我沒有具體配置過TLS,只能根據以上測試結果推測,走TLS認證,只能防止MITM 攻擊,還是無法解決端口未授權訪問的問題。
For added security you can configure the ephemeral port rules to only allow connections from interfaces on known Swarm devices.
大概意思是只允許信任的swarm devices之間通信。
理想情況就是docker 節點的2375端口只允許swarm manager來訪問,但因為swarm manager可能會有多個,就需要配置多條規則,維護起來可能會具有一定復雜度,但只要swarm manager所在機器不被擼,就可以保證docker 節點的2375端口不被未授權訪問。當然,這里還需要結合TLS一起使用。
總結來說就是,不要將端口直接暴露在公網,內網中使用需要設置嚴格的訪問規則,并使用TLS。
如果你仔細閱讀了docker swarm的文檔,你就會發現除了2375端口,還有其他一些端口也存在相同的問題,這里就不一一的列出了。
本文主要說的是docker swarm,但是只要是會導致端口暴露的,都會存在問題,也許有一些使用者會因為某些原因,把端口配置成功公網訪問,或者有另一個"swarm"呢?
還有想說的是,一個新的東西出來,用戶和開發者更多關注的是其功能和便利性,而忽略了存在的安全性問題,之后還會有更多的 “docker remote api” 出現,誰將會是下一個呢?
最后還要感謝一下發現這個問題的同學(轉我10wb我就告訴你是誰),沒他也不會有這個漏洞~
黑客,絕對是黑客!
?
?
?