近日,SUSE安全研究人员Aleksa Sarai公开了一个编号为CVE-2018-15664的Docker高危漏洞,CVSS评分高达8.7。这个漏洞影响所有Docker发行版本——攻击者可以利用它逃逸出容器,读取甚至篡改宿主机或其他容器内的任意文件。Docker官方已经给出了临时缓解方案,并计划在下个版本中正式修复。

漏洞描述
这个漏洞的根源,出在FollowSymlinkInScope函数上——它触发了TOCTTOU(time-of-check-to-time-of-use)文件系统竞争条件缺陷。简单说,就是检查时间和使用时间之间存在一个空隙,被攻击者钻了空子。这段函数在Docker源码中间出现频率很高,最直接的暴露接口就是docker cp命令。
根据Sarai的描述,FollowSymlinkInScope原本的作用是解析容器内运行进程的文件路径。但攻击者可以利用校验完成和操作执行之间的那点间隙,将cp的目标文件偷梁换柱成一个符号链接,指向任意目标。这样一来,攻击者理论上就能以root身份访问宿主机或其他容器中的任何文件。
当然,这并不意味着人人都能轻易利用。根据官方说明,攻击者需要先拥有docker cp命令的使用权限,以及目标容器的访问权限。而且整个攻击窗口只有毫秒级——发生在文件解析完成到执行拷贝动作的那一瞬间。攻击难度不低,需要相当的专业背景,所以普通容器使用者不必过于恐慌。接下来我们看看修复进展。
修复措施
好在,“docker cp”命令是此次漏洞影响范围内唯一暴露的对外接口。Docker社区很快给出了临时方案:官方建议用户在使用docker cp之前先执行docker pause,等拷贝完成后再执行docker unpause。在下个月的正式版本中,这些暂停和恢复操作会被自动集成到cp命令流程里——通过冻结容器来阻断拷贝过程中对文件数据的篡改。
Sarai也指出了根本修复的思路:修改chrootarchive中的归档逻辑,改用root作为容器的rootfs(而不是父目录,因为父目录可能已被攻击者控制)。不过chrootarchive属于Docker底层源码,改动会波及如Tar/Untar等多个相关接口,所以至今还没有彻底修复。好消息是,目前已经有相关的补丁PR提交,相信社区很快会推出正式补丁。另外Sarai还提出了内核层面的修改方案——但这么底层的改动,短期内应该不会被用来修复这个漏洞。
短期如何防范
这个漏洞的攻击前提是攻击者拥有docker cp命令的使用权限。一般情况下,阿里云容器服务集群默认开启了基于RBAC的访问控制,非法用户无法获得容器内的cp权限。但对于那些可能通过其他途径获取cp权限的攻击者,建议从以下几点入手:
1)严格控制docker cp命令的使用范围
2)使用docker cp前后,手动执行docker pause和docker unpause
3)善用AppArmor等工具,限制容器内对宿主机敏感目录的访问权限,并开启相关审计日志
