iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0

Yes

#include <tunables/global>

# No template variables specified

# flags 參考 https://documentation.suse.com/sles/15-SP1/html/SLES-all/cha-apparmor-profiles.html#sec-apparmor-profiles-flags
profile my-docker flags=(attach_disconnected,mediate_deleted) {

  # ---- 1: include -------
  # 檔案位置在 /etc/apparmor.d 底下
  #include <abstractions/base>

  # ---- 2: capability ----
  
  # ---- 3: network -------
  
  # ---- 4: rlimit --------

  # ---- 5: file ---------- 

}
  • 接著跟之前差不多的方式,透過 apparmor_parser 載入,觀察結果後,再執行容器時帶入設定。
sudo mkdir -p /etc/apparmor.d/containers/ ;
sudo mv my-docker /etc/apparmor.d/containers/ ;
sudo apparmor_parser -r -W /etc/apparmor.d/containers/my-docker ;

# 這邊會顯示有一個 profiles 叫做 my-docker
sudo aa-status ; 

# 此時會發現所有的檔案都無法讀寫
docker run --rm -it --security-opt "apparmor=my-docker" aeifkz/my-ubuntu:v1.0 bash ; 

# 會發現能力上的不足
apt update ; 
#include <tunables/global>

# No template variables specified

profile my-docker flags=(attach_disconnected,mediate_deleted) {

  # ---- 1: include -------
  #include <abstractions/base>

  # ---- 2: capability ----

  
  # ---- 3: network -------

  # ---- 4: rlimit --------

  # ---- 5: file ----------
  #開放所有檔案的存取
  file , 
}
  • 然後套用到 AppArmor 中測試一下指令 apt update
sudo apparmor_parser -r -W /etc/apparmor.d/containers/my-docker ;

# 現在有檔案的讀取權限
docker run --rm -it --security-opt "apparmor=my-docker" aeifkz/my-ubuntu:v1.0 bash ; 

# 但依然發現能力上的不足
apt update ; 

# 透過 capsh 來看一下目前的 CAP 狀態,觀察 Current: 這個欄位
capsh --print ;
  • 接著開放所有類型的 CAP,反正這部分本來就是由外部來控制的,以及開放網路能力。
#include <tunables/global>

# No template variables specified

profile my-docker flags=(attach_disconnected,mediate_deleted) {

  # ---- 1: include -------
  #include <abstractions/base>

  # ---- 2: capability ----
  capability,
  
  # ---- 3: network -------
  network,

  # ---- 4: rlimit --------

  # ---- 5: file ----------
  #開放所有檔案的存取
  file , 
}
  • 最終測試 apt update 指令,終於正常運行了
sudo apparmor_parser -r -W /etc/apparmor.d/containers/my-docker ;

# 現在有檔案的讀取權限
docker run --rm -it --security-opt "apparmor=my-docker" aeifkz/my-ubuntu:v1.0 bash ; 

# 有沒有很敢動,終於有勇氣繼續惹
apt update ; 
  • 接著假設今天需要針對一些檔案設定黑名單,使用的設計參考如下 :
#include <tunables/global>

# No template variables specified

profile my-docker flags=(attach_disconnected,mediate_deleted) {

  # ---- 1: include -------
  #include <abstractions/base>

  # ---- 2: capability ----
  capability,
  
  # ---- 3: network -------
  network,

  # ---- 4: rlimit --------

  # ---- 5: file ----------
  #開放所有檔案的存取
  file , 

  # 假設我們禁止 /tmp、/tools 資料夾的讀取及寫入
  deny /tmp/** rw , 
  deny /tools/** rw , 

  # 假設我們禁止用 cat 讀取檔案
  deny /usr/bin/cat mrwklx , 
}
sudo apparmor_parser -r -W /etc/apparmor.d/containers/my-docker ;
docker run --rm -it --security-opt "apparmor=my-docker" aeifkz/my-ubuntu:v1.0 bash ; 

# 此時會發現所有檔案都可以讀寫,除了 /tmp 底下之外
echo aaa > aaa ;

# 測試 cat 指令及特性
cat aaa ; # 出現 Permission denied,試圖改資料夾名稱也沒救

# 對兩個資料夾進行寫入測試
touch /tmp/test ;
touch /tools/test ;

# 試著更名繞過
mv /tmp /tmp123 ;
mv /tools /tools_123 ;

# 在對資料夾做新增檔案試試
touch /tmp123/test ;

# 還原資料夾名稱
mv /tmp123 /tmp ;
touch /tmp/new_test ;
  • 透過上面的範例會發現當對空的資料夾進行禁止條件讀取跟寫入的時候可以被更名給繞過,這部分我也不知道原因,就只是剛好有測到而已,不過實務要限制一個空的資料夾的情境應該不會太多,就當作一個奇特的特性就好了(雖然說這個特性害我花了不少時間Debug)。/images/emoticon/emoticon17.gif

  • 至於要繞過限制 cat 的部分就比較特別一點,需要利用到shebang,可以參考如何繞過 AppArmor

echo '#!/bin/cat' > read_file.sh ;
chmod +x read_file.sh ;
./read_file.sh 檔案名稱 ;
  • 至於想知道 docker 套用了甚麼設定的話,可以參考這篇 Where is docker's apparmor profile? 以及這篇 Apparmor in Docker 還有 AppArmor security profiles for Docker 以及 moby/contrib/apparmor

  • docker-default profile Summary:

    • Access to all networking
    • No capability is defined (However, some capabilities will come from including basic base rules i.e. #include <abstractions/base> )
    • Writing to any /proc file is not allowed
    • Other subdirectories/files of /proc and /sys are denied read/write/lock/link/execute access
    • Mount is not allowed
    • Ptrace can only be run on a process that is confined by same apparmor profile
  • 最後我們一樣來探討 AppArmor 實質上提供了甚麼防護呢? 這部分列舉攻擊篇的手法來進行驗證。

攻擊手法 AppArmor 預設能否阻擋?
privileged + host pid N
--cap-add=ALL + host pid Y (作業8)
privileged N
(CVE-2022-0492) unshare + cgroup 特權逃逸手法 N
安裝 linux_module N
docker.sock 掛載 N
  • 從上表各位會覺得好像預設能阻擋的攻擊手法並不多,這是因為 apparmor 的設定檔案還是以黑名單為主,所以名單的設定會相對嚴謹。而且比較直覺可以限制的部分通常會是檔案系統上的讀寫限制,這部分在應對逃逸手法上就顯的相對乏力。但如果是預防網頁竄改這樣的攻擊,應該就會相對有利一些。/images/emoticon/emoticon37.gif

  • 但 AppArmor 的缺點在於很難建立出一個完整通用的預設白名單出來,因為除了 capability、network、file 之外,還有其他類型的資源開放例如 mount、pivot_root、ptrace、signal 等,再加上無法引入 docker-default 進行疊加的情況下,要做出白名單的確有些難度。

  • 作業8 : 我們都知道開啟特權容器會關閉 Seccomp、Apparmor 等相關機制,造成無法測試掛載 host pid 的逃逸手法,但假如給予今天給予容器所有的能力並掛載 host pid,到底是否能夠順利逃逸呢? 假如不行的話,驗證一下是不是 Apparmor 搞的鬼。/images/emoticon/emoticon33.gif

  • 今日總結 :

    • 本日回顧 :
      • 探討一下 AppArmor 的規則格式以及可以限制的資源,然後在說明如何套用到 docker 的容器上面,並且對空資料夾的寫入做了一個小測試,算是了解了一個小特性吧。最後再出作業練習建立host pid 的特權環境,去了解一下 AppArmor 的防護部分。
    • 次日預告 :
      • 終於結束了 AppArmor 的部分了,有沒有覺得放鬆了不少。但 AppArmor 只能作用在 Ubuntu 系列,而 CentOS 是對應到 SELinux,而且機制上來說更為複雜難用(我自己覺得啦QQ)。/images/emoticon/emoticon02.gif

上一篇
Day28 - 作業7 解答 - 熟悉 AppArmor 特性
下一篇
Day29 - 作業8 解答 - 測試 cap-add ALL 以及 host pid 的逃逸手法
系列文
怕痛的我把 Docker、K8s 攻擊、防禦、偵測力點滿就對了63
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言