容器為何自動停止?
伺服器為何操作卡頓?
程式的神祕連線到底指向何處?
發現——自動停止的容器
某日發現部署在伺服器上的一個容器被停掉了,開始以為是同事誤操作停止或刪除了。
但登入伺服器重新啟動容器的時候發現一個奇怪的現象:容器啟動後幾秒鐘便會自動停止。
一般來說這種情況可能是容器本身有問題。
但是檢視容器日誌並未得到任何錯誤資訊,而且該容器映象已在其它伺服器穩定部署執行,應該不會有bug。
所以猜測是系統資源不足,例如磁碟、記憶體、CPU。
檢視磁碟剩餘量還比較多,但是在用top
命令檢視CPU和記憶體的時候發現了異常:某個程式CPU使用率達到了99%。

當然這種情況對於我們公司的伺服器來說也不是什麼特別驚奇的事,因為我們通常會在伺服器上執行一些計算任務,佔用大量CPU也是很正常的事情。
但由於這臺伺服器除了我幾乎沒有其他同事使用,而且程式命令列看不到,所以引起了我的懷疑。
驗證——異常不止一處
挖礦程式身份確認
如此高的CPU使用率,讓我想到的是最近流行的挖礦病毒。
通過netstat -anp
命令檢視該程式是否建立了外部網路連線。

果然建立一個連線,指向 5.196.26.96 這個IP地址。在 www.ipip.net/ip.html 查詢一下該IP地址,指向國外某地。
進一步驗證了我的猜測。因為國內的伺服器有嚴格的備案管理機制,所以很多攻擊者都會將伺服器部署到國外。

為了進一步確認,再次到威脅情報平臺進行查詢 x.threatbook.cn/ip/5.196.26… 。

平臺也給出了威脅警告,可以大膽的推定這就是一個挖礦程式。
當然如果想進一步確認,可以提取執行檔案的md5值到相關網站進行辨認。
挖礦程式從哪裡來?
挖礦程式一般都是由木馬下載指令碼然後執行,所以用history
命令檢查一下下載行為。

沒有找到可疑的下載,很可能黑客清除了操作記錄或者是通過別的途徑下載。
為了進一步排除可能有其它病毒程式作為守護程式定時啟動或者開機啟動挖礦程式,檢查一下crontab配置資訊。
也未找到新新增的可疑檔案,所以黑客應該並沒有設定定時任務。
同時也未找到可疑的開機啟動項配置。
可疑的映象與容器
到了這一步,線索中斷。只能換個角度思考了~
據管理員說平時這臺伺服器很少使用,而且使用的是強密碼,密碼洩露的可能性很小。
再結合我部署的容器停止時間進行分析,應該是在我部署完成後幾小時內伺服器被入侵的。
所以懷疑很可能和我的操作有關係。
在使用docker命令進行查詢的時候又發現了新的情況。
一些容器使用了未知映象(heybb/theimg2)或者使用了非官方的映象(zoolu/ubuntu)。
上docker hub上搜尋這些映象,都找不到Dockerfile,也無readme之類的說明。而且上傳時間都很新,但是下載量增長卻很快。
這就奇怪了,這種既無說明,命名也十分怪異的映象竟然會被多次下載,所以可以推斷就是黑客上傳的攜帶木馬的映象。
再利用docker inspect
命令檢視這些容器,發現該容器並沒有通過掛載目錄的方式寫入系統檔案,而是會執行一個 mac.sh 的指令碼檔案。

用cat
命令檢視該檔案,只有一行命令

顯然這是在挖門羅幣。
小結
現在發現不止一個黑客入侵了伺服器,有的黑客部署了挖礦容器,有的黑客部署了挖礦程式並刪除了記錄。
處理——清除程式,關閉漏洞
首要任務當然是清除挖礦程式和容器,以及對應的執行檔案和映象。
當然這只是治標不治本的方法。
要從根本上解決問題需要進行溯源分析,避免伺服器再次被入侵。
結合以上線索以及個人經驗分析,很可能利用Docker的漏洞進行入侵的。
我在部署容器的時候啟動 Docker remote API 服務,很可能這個服務暴露到了公網上,立即在瀏覽器中輸入伺服器IP地址和對應埠,果然可以訪問!
原來伺服器運營商並沒有提供預設的防火牆服務,機器上的埠是直接暴露在公網上的。
黑客入侵的途徑也基本上可以猜測了,通過 Docker remote API 伺服器操作容器,將帶有挖礦程式的容器部署到伺服器上。
或者將挖礦程式通過目錄掛載的方式拷貝到伺服器上,以某種方式觸發並執行。
要修復這個漏洞也很簡單,停止對外暴露服務。
建議
網路安全其實是一個很重要的課題,但是開發人員很多時候都缺乏對其足夠重視。
針對這次事件,總結了幾個經驗:
除了一些 web 服務(http/https),不要使用預設埠。
黑客的入侵操作一般都是自動化的、批量的。
操作是使用埠掃描工具,對特定的預設埠掃描。
比如本例中肯定是掃描到本伺服器的 2375 埠(2375是Docker remote API的預設埠)之後進行攻擊的。
這個原理其實有點像打電話詐騙,用一些很低階的騙術把容易受騙的人群篩選出來。
所以我們平常在編寫程式時儘量避免使用預設埠。
不要通過繫結 0.0.0.0 的方式暴露本不需要對外提供訪問的服務。
之前在啟動 Docker remote API 服務時監聽 0.0.0.0 IP,是因為看到很多網上教程都是如此配置,但其實存在了很大的安全隱患。(把事情做好和把事情做完區別真的很大!)
其實該服務在使用中並不需要提供給外網,實際上只要監聽子網IP就夠了。比如 127.0.0.1、 172.17.0.1。
儘可能多的考慮非正常情況
在開發的時候我們除了考慮程式正常的輸入輸出之外,還需要假設一些特殊的情況來進行測試。
下面是開發者和黑客的思維方式區別:
開發者:A -> 程式 -> B
黑客:S -> 程式 -> ?
複製程式碼
開發者考慮的是保證輸入A,就可以得到B。黑客很多時候會輸入開發者未考慮的S,從而發現bug或漏洞。
使用防火牆限制埠訪問。
網路服務,防火牆很重要。
這次的入侵和雲伺服器廠商都會自帶防火牆的思維定勢有關係。
通過證照驗證訪問者的身份。
對於需要提供對外訪問的服務,使用身份驗證也是一種有效避免攻擊的手段。
例如Docker就支援TLS證照來驗證服務端和客戶端的身份。
總結
排查入侵木馬的過程很像扮演一個偵探,通過犯罪現場的蛛絲馬跡找到凶手以及行凶手法。
還好當初在發現問題的時候並沒有馬上採取重灌系統這種簡單粗暴的方式解決問題,不然漏洞依舊存在,伺服器依然會被攻擊。
關於更多更權威網路安全的知識可以參考《OWASP TOP10 2017》,裡面有最常見的10類漏洞以及防禦措施。
像本文中的Docker遠端未授權漏洞以及類似的redis未授權漏洞都屬於 OWASP TOP 10 中的漏洞。
原文連結:tech.gtxlab.com/docker-api-…
作者資訊:朱德龍,人和未來高階前端工程師。