影响版本
Docker <= 18.06.1-ce-rc2
Docker cp
Docker cp命令能够将容器内的文件向宿主机复制,也能够实现宿主机文件向容器中复制。
1 | # 将容器中的文件复制到宿主机中 |
符号链接
类似于Windows中的快捷方式。符号链接的操作是透明的:对符号链接文件进行读写的程序会表现得直接对目标文件进行操作。
1 | # 将目标路径和指定的链接名或者路径进行绑定 |
源码及利用原理
1 | // Copyright 2012 The Go Authors. All rights reserved. |
Docker cp过程中FolllowSyslinkInScope方法会先检测路径合法存在,检测结束后evalSymlinkInScope方法对路径进行解析并执行后续文件复制操作。
整个复制过程不是一个原子操作,而路径检测和解析执行才分别是原子操作。在这个复制过程中如果攻击者在路径检测结束后将正常路径替换成一个恶意的符号链接,那么攻击者将能够对Docker cp的目的主机(可以是容器也可以是宿主机)任意路径的文件内容进行覆盖。
然而这里我也有个猜测,Docker cp相当于一个set-uid进程,于是它可以获得文件root权限进行文件内容覆盖。
漏洞场景和POC解读
漏洞场景:受害者在从容器中复制文件到宿主机
当漏洞触发时容器内的文件将被复制到宿主机中的任意一个目录(恶意符号链接所指定)
1 |
|
漏洞场景:受害者在从宿主机中复制文件到容器中
当漏洞触发时宿主机内的文件将被复制到宿主机中的任意一个目录(容器中恶意符号链接所指定)
1 |
|
POC解读
POC中使用一个无限循环将恶意符号链接与正常文件交换,根据目标文件内容可以判定我们是否竞争成功。
1 | /* |
漏洞复现
这里使用metarget靶场进行漏洞测试。
正常操作
将容器中的文件ex复制到宿主机中,FollowSymlinkInScope方法检查这个路径合法,evalSymlinksInScope方法对这个路径进行解析。执行的结果是将容器中的ex复制到宿主机的当前目录下。
恶意操作
将容器中的文件ex复制到宿主机中,FollowSymlinkInScope方法检查这个路径合法,在evalSymlinksInScope方法对这个路径进行解析之前将路径替换为恶意符号链接指向宿主机的/w00t_w00t_im_a_flag。执行的结果是将/w00t_w00t_im_a_flag文件复制到宿主机当前目录下。
运行run_read.sh,并通过grep查看是否写入成功。
非常夸张的是在竞争中获得root的主机访问权限<1%,但仍有机会竞争成功。
正常操作
要将宿主机的正常文件localpath复制到容器中,FollowSymlinkInScope方法检查这个路径合法,evalSymlinksInScope方法对这个路径进行解析。执行的结果是将宿主机的当前目录的localpath复制到容器中的/w00t_w00t_im_a_flag位置。
恶意操作
我们在容器中创建了一个指向宿主机根目录/的恶意符号链接,在进行FollowSymlinkInScope方法时,对正常文件localpath进行检查,但在evalSymlinksInScope方法中传入的路径为指向宿主机根目录/的恶意符号链接。执行的结果是将宿主机的当前目录的localpath复制到宿主机/w00t_w00t_im_a_flag位置。
运行run_write.sh
我们发现这很快就完成了竞争,
这是因为 Docker 内部有一个**”chrootarchive”概念**,其中存档是从 chroot 中提取的。然而,Docker 不会 chroot 到容器的”/“(这会使此漏洞无效),而是 chroot 到存档目标的父目录——这是攻击者控制的。结果,这实际上导致攻击更有可能成功(一旦 chroot 完成竞争,其余的攻击就保证成功)。
Author: Sally