iT邦幫忙

2023 iThome 鐵人賽

0

Yes

  • 概念部分可以參考趨勢科技的 使用 Distroless 技巧來縮小容器映像並提升雲端資安,其中提到 Distroless 是一種的鏡像檔案,其中只包含應用程式本身以及應用程式執行時所需要的元件,並不包含套件管理員、指令列介面或其他程式。藉由這樣的方式可以減少駭客拿到容器的控制權後做更進一步利用。

  • 鏡像的編譯部分可以參考 GoogleContainerTools/distroless,新增一個 Dockerfile 針對之前用的鏡像檔案做一個 distroless 鏡像出來,其中第一個容器只是為了編譯執行程式,而第二個容器則是為了部署用。在 python 這種不做編譯的方式看起來是沒甚麼必要,但是其他編譯式語言就會有所差別。

    FROM python:3-slim AS build-env
    COPY /tools /app
    WORKDIR /app
    
    FROM gcr.io/distroless/python3
    COPY --from=build-env /app /app
    WORKDIR /app
    CMD ["reverse_server.py"]
    
    docker build --no-cache --tag aeifkz/my-ubuntu:distroless . ;
    docker run --rm -p 30089:30089 --name distroless aeifkz/my-ubuntu:distroless ;
    
    docker exec -it distroless sh ;
    
    # 會發現甚麼常用的指令都沒有,極度難用
    ls ;
    
  • 到底要如何排除這個窘境呢? 參考 How to use and build your own distroless images 可以知道透過安裝 cdebug 指令並透過 cdebug exec -it [container name] 進行偵錯,但這種方式需要有宿主機的控制權才能夠執行。這個工具的原理則可以參考 Docker: How To Debug Distroless And Slim Containers,主要是啟動一個偵錯,並於容器啟動時掛載偵錯對象的 pid 及 network,然後利用/proc/1/root 這個小技巧存取到掛載 pid 所在的檔案目錄,接著在容器內對偵錯對象新增一個 symbolic links,然後 export $PATH 資料,最後再用 chroot 切換跟目錄。

    # 列出現有容器資訊,先看一下要偵錯對象的 CONTAINER ID 
    docker ps ;
    
    container_id="[CONTAINER ID]" 
    
    # 開啟一個偵錯容器,並於啟動時掛載偵錯對象的 pid 及 network
    # musl from Alpine (statically compiled)
    docker run --rm -it --name debugger --pid container:$container_id --network container:$container_id busybox:musl sh ;
    
    ln -s /proc/$$/root/bin /proc/1/root/.cdebug ;
    # 以下是從 cdebug 的容器抄來的
    export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/.cdebug ;
    chroot /proc/1/root sh ;
    
    # 完美執行 ls
    ls ;
    
  • 雖然這招對一般的 distroless 容器用起來沒甚麼問題,但是如果該容器是用 read-only 啟動的話就真的沒轍了。其他參考資料 : 當遇到 Distroless Container 除錯要什麼沒什麼該怎麼辦? 你的好朋友 kubectl debug

  • 那究竟 distroless 能夠防禦多少種攻擊呢? 如果不把相關使用指令運送進去容器的情況下來做個分析。以下是測試指令,內容參考 The difference between Docker ENTRYPOINT and CMD :

    docker run --rm -it --entrypoint=sh --name distroless aeifkz/my-ubuntu:distroless ;
    
攻擊手法 distroless 能否阻擋?
privileged + host pid Y (找不到 nsenter)
--cap-add=ALL + host pid Y (找不到 nsenter)
privileged Y (找不到 mount、chroot)
(CVE-2022-0492) unshare + cgroup 特權逃逸手法 Y (找不到 unshare)
安裝 linux_module Y (找不到 insmod)
docker.sock 掛載 Y (GLIBC not found)
  • 作業12 : 透過以下指令建立容器,透過 nc 連到目標容器後,想辦法利用這次學習到的特性取得其他容器的 flag 檔案資訊。

    docker run -d -it --rm --name flag aeifkz/my-ubuntu:v1.0 bash ;
    
    #意思產生一個 flag 檔案
    echo "ZmxhZ3toYWNrZXIgaGF0ZSBEaXN0cm9sZXNzfQo=" | base64 -d > flag.txt ;
    docker cp flag.txt flag:/ ;
    rm flag.txt ; 
    
    docker run -d --rm --name target -p 30089:30089 --pid container:flag aeifkz/my-ubuntu:v1.0 ;
    
    # 開始解題
    docker exec -it target bash ;
    
  • 今日總結 :

    • 本日回顧 :
      • 主要介紹了甚麼是 Distroless Image,演示了如何編譯及偵錯,也順便了解他難用之處。藉著這次機會多學會了如何透過容器掛載 pid 去讀取底下的檔案系統,算是多了一個小知識點。另外經過測試在正常情況下 Distroless Image 可以防禦之前介紹過的攻擊,那是否要套用就要評估應用程式部屬上去之後是否能夠正常運行。
    • 次日預告 :
      • 接著要針對容器鏡像進行安全檢測,畢竟之前有提過容器鏡像本身就是一個檔案系統,那這個檔案系統會不會包含一些已知的漏洞的元件也是一個值得注意的點。掃描上有甚麼差異,解析上有甚麼差異就是下次要討論的重點。

上一篇
Day 38 - (防禦) Container Sandboxing 技術 - gVisor 介紹
下一篇
Day 39 - 作業12解答 - 驗證 /proc/pid/root 特性
系列文
怕痛的我把 Docker、K8s 攻擊、防禦、偵測力點滿就對了63
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言