通過SSRF漏洞攻擊Docker遠程API獲取伺服器Root許可權
嚴正聲明:本文僅限於技術討論與分享,嚴禁用於非法途徑。
前言
這幾天筆者在做關於自動化部署Docker鏡像方面的項目,從而接觸到了Docker的API,而Docker的API也可以通過TCP連接的形式來進行訪問。從一個安全愛好者的角度出發,是否可以利用Docker的遠程API來實現提權等一系列的操作?查找了各種資料之後,最後筆者探索到了一條通過SSRF漏洞來攻擊Docker遠程API,從而獲得遠程主機的root許可權的攻擊思路,通過這篇文章來分享一下整個過程及其防範的方法。
1. Docker遠程API介紹
Docker遠程API是Docker團隊為了方便用戶遠程管理Docker而提供的一套API介面。在默認的情況下,Docker Daemon運行於Unix Socket上,通常為unix:///var/run/docker.sock。
當需要遠程管理Docker伺服器或者是創建Docker集群時,可能需要開啟Docker的遠程API。在Ubuntu上的一種開啟方法如下:
編輯文件,修改ExecStart一行:
之後再重啟docker:
然後就可以利用Docker客戶端或者任意http客戶端訪問Docker服務,例如:
可以看到Docker提供的API實質上是一個RSTful形式的http介面,具體的文檔可以從Docker的官網獲取:Engine API V1.24。
這裡列出幾個重要的介面:
列出所有的容器:
列出所有鏡像:
創建並運行容器:
到了這裡,我們可以看到如果開放了Docker遠程API,我們便可以使用RESTful介面來實現一系列Docker容器操作。
2. 利用docker容器提權
有些朋友可能會問了:Docker容器內部是一個與主機隔離的虛擬化環境,怎樣才能利用Docker容器獲取主機控制權?這裡就涉及到Docker運行時的用戶許可權了。Docker Daemon運行時是以root用戶運行,因而具有極高的許可權:
那麼怎樣通過Docker Daemon最終獲得伺服器的root許可權?這裡我們可以利用Docker掛載宿主機文件的功能,直接掛載高許可權目錄,從而在容器內部獲取宿主機的控制許可權。
這裡有一個黑魔法:
運行後的輸出如下:
退出Docker,查看宿主機/root/目錄:
我們可以看到成功在/root文件夾寫入了一個文件。
上面那條命令 主要的作用是:從 Docker Hub上面下載我們指定的鏡像,然後運行。參數 -v 將容器外部的目錄/掛載到容器內部 /hostOS,並且使用-i和-t 參數進入容器的shell。而這個鏡像rootplease在容器內部執行了一個腳本,主要內容便是chroot到/hostOS中。這樣我們便通過讀寫宿主機的任意文件實現了獲取宿主機的最高許可權。這個鏡像的源碼可以在 Github上獲取。
3. 通過SSRF完成攻擊
這裡我們的伺服器端環境如下:
在PHP中經常出現,導致SSRF漏洞的代碼實現:
PHP中通常使用libcurl來實現http請求,這裡可以看到$_GET["url"]可控,從而可以請求任意站點,構成了SSRF漏洞。
但是有讀者有可能會問:Docker的API有很大一部分是需要post的,那麼怎樣才能發送post封包?
此時祭出我們的大殺器——gopher協議。Gopher協議是http協議出現之前互聯網上常用的一個協議,現在已經慢慢淡出歷史。Gopher協議可以做很多事情,特別是在SSRF中能夠發揮很多重要作用。利用此協議可以攻擊內網的FTP、Telnet、Redis、Memcache,也可以進行 GET、POST 請求。這無疑極大拓寬了SSRF的攻擊面。
到了這裡,我們就可以通過gopher協議來訪問內網開放的Docker API從而實現攻擊。我們可以先嘗試獲取所有的鏡像:
構造一個特殊的Docker鏡像,並將之上傳到DockerHub:
exploit.sh的寫法:
這裡的docker鏡像已經上傳到了DockerHub。
之後可以先構造合適的post封包:
這個post封包的目標是讓遠程主機從DockerHub下載我們需要的鏡像。構造gopher格式為:
通過SSRF的點觸發即可在遠程伺服器下載我們的鏡像:
之後再創建容器:
將封包包裝為gopher的形式:
這裡我們再最後多加了一些%0d%0a從而讓連接能夠斷開。然後利用之前的SSRF的地方請求這個url,可以獲得創建的容器ID:
獲取ID後再post相應的使容器運行封包:
伺服器端nc埠3456,構造gopher格式的url候再次發送封包:
可以看到伺服器端成功返回shell,且已成功掛載宿主機根目錄到/hostOS下。
這樣我們便通過SSRF與Docker未授權API完成了一次攻擊,並且獲取了宿主機的root許可權!
除了反彈shell的方法,我們也可以藉助寫crontab的方法來獲得最後的shell,這裡便不再贅述。
4. 如何防範
在非必需的情況下,不要啟用Docker的遠程API服務,如果必須使用的話,可以採用如下的加固方式:
設置ACL,僅允許信任的來源IP連接;
設置TLS認證,官方的文檔為Protect the Docker daemon socket。
客戶端與伺服器端通訊的證書生成後,可以通過以下命令啟動Docker Daemon:
客戶端連接時需要設置以下環境變數:
這樣就可以避免未授權的Docker API被遠程利用。
5. 總結
未授權的Docker遠程API存在極大的風險,當結合SSRF漏洞時可以作為滲透測試擴展供給面的工具,最後獲得root shell,因此在做開發時應該嚴格防範。最後總結一下我們的攻擊思路:
※高級加密標準分析
※Google Play上的AndroidFoulGoal.A間諜軟體分析
TAG:瘋貓網路 |