0x01 簡介
該未授權訪問漏洞是因為docker remote api可以執行docker命令,從官方文檔可以看出,該接口是目的是取代docker 命令界面,通過url操作docker。
Docker remote Api未授權訪問的攻擊原理與之前的Redis未授權訪問漏洞大同小異,都是通過向運行該應用的服務器寫文件,從而拿到服務器的權限。
docker swarm是docker下的分布化應用的本地集群,在開放2375監聽集群容器時,會調用這個api
當某個主機開放了2375端口時,就要注意了!
url輸入ip:2375/version
就會列出基本信息,和docker version命令效果一樣。
同樣,url為ip:2375/v1.23/containers/json
會列出容器信息,和docker ps -a效果一樣。
0x02 漏洞復現
通過docker客戶端遠程執行目標服務器容器命令:
1 列出所有鏡像:
docker -H tcp://*.*.*.*:2375 images
2 列出所用容器
docker -H tcp://*.*.*.*:2375 ps -a
3 進入容器兩種方法:
3.1 進入已有的容器
start 啟動一個已經停止的容器
attach 連接一個已經停止的容器
當然這個容器默認entrypoint
必須是/bin/bash
,關於這點可以在json里看到,還有掛載,后面提權會用到,這個也可以在json文件里看到。
3.2 開啟新容器
新運行一個容器並將entrypoint
設置為/bin/bash
,掛載點設置為服務器的根目錄掛載至/mnt
目錄下
注意:
docker run
只在第一次運行時使用,將鏡像放到容器中,以后再次啟動這個容器時,只需要使用命令docker start
即可。
docker run
相當於執行了兩步操作:將鏡像放入容器中(docker create),然后將容器啟動,使之變成運行時容器(docker start)。
wooyun上lijiejie是因為docker client版本不一致調用api去create重構一個容器,並在attach、start后捕獲到輸出
0x03 服務器提權的幾種方法
1 寫入SSH公鑰
啟動一個容器,掛載宿主機的/root/
目錄,之后將攻擊者的ssh公鑰~/.ssh/id_rsa.pub
的內容寫到入宿主機的/root/.ssh/authorized_keys
文件中,之后就可以用root賬戶直接登錄了。
(1)本地獲取ssh公鑰
(2)將公鑰復制到被攻擊者的/root/.ssh/authorized_keys文件中
(3)ssh連接遠程服務器
2 寫入crontab反彈Shell
啟動一個容器,掛載宿主機的/etc/目錄,之后將反彈shell的腳本寫入到/etc/crontab
中,攻擊機nc -vv -l -p Port
會得到一個反彈的shell
攻擊機上:
目標機上:
3 寫入其他的cron中
也可以掛載var/spool/cron/
目錄,將反彈shell的腳本寫入到/var/spool/cron/root
(centos系統)或/var/spool/cron/crontabs/root
(ubuntu系統)
0x04 安全隱患
也許有運維同學覺得這是因為監聽在了外網,所以攻擊者才有機會攻擊,如果我不監聽在外網就沒有安全隱患了,其實監聽在內網也有以下安全隱患:
(1)外網攻擊者可以通過WEB應用的SSRF漏洞,間接地攻擊內網中的這些未授權的Docker remote api服務;
(2)方便已經攻入內網的攻擊者擴大攻擊范圍;
(3)可能會被內部別有用心的人攻擊,然后竊取敏感數據。
0x05 安全加固
在不必需的情況下,不要啟用docker的remote api服務,如果必須使用的話,可以采用如下的加固方式:
1 設置ACL,僅允許信任的來源IP連接;
2 設置TLS認證,官方的文檔為Protect the Docker daemon socket
客戶端與服務器端通訊的證書生成后,可以通過以下命令啟動docker daemon:
docker -d --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H=tcp://10.10.10.10:2375 -H unix:///var/run/docker.sock
客戶端連接時需要設置以下環境變量
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=~/.docker
export DOCKER_HOST=tcp://10.10.10.10:2375
export DOCKER_API_VERSION=1.12