实用指南:容器逃逸漏洞

news/2025/9/19 22:34:55/文章来源:https://www.cnblogs.com/lxjshuju/p/19101805

用途限制声明,本文仅用于网络安全工艺研究、教育与知识分享。文中涉及的渗透测试方式与工具,严禁用于未经授权的网络攻击、数据窃取或任何违法活动。任何因不当使用本文内容导致的法律后果,作者及发布平台不承担任何责任。渗透测试涉及复杂技术处理,可能对目标系统造成数据损坏、服务中断等风险。读者需充分评估技术能力与潜在后果,在合法合规前提下谨慎实践。

容器逃逸漏洞再linux上比较常见,容器化环境主要部署在linux上,这里来详细介绍容器逃逸漏洞。

root 权限)的一类高危漏洞。容器的安全依赖于 Linux 内核的隔离技术(Namespace、Cgroups、Capabilities 等),若这些机制被绕过或存在缺陷,就可能导致逃逸。就是容器逃逸漏洞是指攻击者利用容器化环境(如 Docker、Kubernetes、Containerd)的隔离机制缺陷、配置错误或底层内核漏洞,突破容器的资源隔离边界,获取宿主机(Host)的操作权限(通常

一、容器逃逸的核心分类

根据逃逸利用的核心路径,可分为 4 大类,每类包含典型漏洞案例和利用逻辑:

1. 利用容器隔离机制缺陷逃逸

容器的隔离依赖 Linux 内核的Namespace(命名空间) 和Cgroups(控制组),若这些机制存在设计缺陷或使用不当,攻击者可直接绕过隔离。

漏洞类型

典型案例

原理说明

影响场景

Namespace 逃逸

CVE-2022-0492(OverlayFS)

OverlayFS(容器常用存储驱动)的copy_up机制存在权限绕过,容器内可修改宿主机文件系统

Docker、Containerd 等使用 OverlayFS 的环境

Cgroups 权限滥用

Cgroups Release Agent 逃逸

攻击者依据修改 Cgroups 的release_agent(释放代理)路径,将其指向容器内的恶意脚本,当 Cgroups 触发释放时,宿主机以 root 执行该脚本

容器拥有CAP_SYS_ADMIN权限(非默认)

PID Namespace 逃逸

宿主机 PID 泄露 + 信号注入

若容器启动时未隔离 PID Namespace(--pid=host),容器内可看到宿主机所有进程,借助向宿主机 root 进程注入信号或代码逃逸

特权容器(Privileged)或 PID Namespace 配置错误

2. 利用 Linux 内核漏洞逃逸

容器运行在宿主机内核之上,若宿主机内核存在未修复的高危漏洞(如 UAF、权限绕过),攻击者可在容器内触发漏洞,突破内核隔离获取宿主机权限。这类漏洞本质是Linux 内核漏洞在容器环境的延伸,但容器环境会降低利用门槛(无需物理机 / 虚拟机访问)。

典型漏洞

内核模块

逃逸逻辑

CVE-2016-5195(Dirty COW)

内存子系统

容器内触发 COW 机制的竞争条件,修改宿主机的只读文件(如/etc/passwd),添加 root 用户

CVE-2021-41773(Apache HTTP Server)

内核 Netfilter

容器内通过恶意请求触发内核缓冲区溢出,执行宿主机内核态代码

CVE-2022-2588(Netfilter UAF)

内核 Netfilter

容器内构造特殊 Netfilter 规则,触发双重释放漏洞,获取宿主机 root 权限

3. 利用容器部署错误逃逸

这类逃逸并非依赖 “漏洞”,而是由于管理员 / 开发者对容器配备的安全选项忽略,导致隔离机制失效,是实际环境中最常见的逃逸场景。

配置错误类型

利用逻辑

典型处理示例

特权容器(Privileged)

启动容器时添加--privileged参数,容器会获得宿主机几乎所有 Capabilities 权限,可直接挂载宿主机文件系统(如/dev/sda1)

容器内执行:mount /dev/sda1 /mnt,直接修改宿主机/mnt/etc/passwd

宿主机目录挂载不当

将宿主机敏感目录(如/etc、/var/run/docker.sock)以rw(可写)权限挂载到容器内,攻击者可修改宿主机文件或控制 Docker 服务

挂载/var/run/docker.sock后,容器内通过docker run启动新特权容器,挂载宿主机根目录

Capabilities 权限过度授予

容器默认仅保留基础 Capabilities(如CAP_NET_RAW),若额外授予CAP_SYS_ADMIN(框架管理权限),攻击者可利用该权限创建宿主机级别的命名空间或修改内核参数

容器内执行:mount -t proc proc /host/proc,读取宿主机进程信息并注入代码

容器镜像应用 root 用户

容器默认以 root 用户运行(非默认,但常见配置),若结合其他缺陷(如档案挂载),可直接处理宿主机文件

镜像中内置恶意脚本,挂载宿主机/root目录后修改~/.bashrc,宿主机 root 登录时触发

4. 利用容器 runtime 漏洞逃逸

容器 runtime(如 RunC、Containerd)是管理容器生命周期的核心组件,若 runtime 本身存在漏洞,攻击者可依据容器内操作篡改 runtime 逻辑,建立逃逸。

典型漏洞

影响组件

逃逸逻辑

CVE-2019-5736(RunC)

RunC

容器内进程可利用/proc/self/exe(指向宿主机的runc二进制)修改runc文件,当宿主机执行runc exec等命令时,触发恶意代码执行

CVE-2023-28840(Containerd)

Containerd

Containerd 的cri组件处理镜像时存在路径遍历,攻击者可利用恶意镜像将资料写入宿主机任意路径(如/etc/cron.d),触发定时任务执行

CVE-2022-24769(Docker Desktop)

Docker Desktop(Windows/macOS)

Windows/macOS 下的 Docker Desktop 存在权限绕过,容器内可访问宿主机的 Windows 文件系统(如C:盘),修改系统配置

二、如何判断容器环境是否存在逃逸风险?

除了 “内核漏洞”(需依赖漏洞扫描工具),其他类型的逃逸风险可依据容器内自查和宿主机检测两步判断,操作门槛低且效果直接:

1. 容器内自查:判断当前容器是否存在逃逸条件

在容器内执行以下命令,检查是否存在配备缺陷或隔离失效:

检查项

执行命令

风险判断标准

1. 是否为特权容器

grep -E '^CapEff:' /proc/self/status 或 capsh --print

若输出涵盖0000003fffffffff(全 Capabilities),或capsh表现Current: = cap_setpcap,cap_setuid,cap_setgid,...(包含CAP_SYS_ADMIN等高危权限),则为特权容器

2. 宿主机目录挂载情况

mount 或 cat /proc/mounts

若存在挂载/var/run/docker.sock、/etc、/proc/sys、/dev/sda1(宿主机磁盘)等路径,且权限为rw(可写),则存在风险

3. PID Namespace 隔离

ps aux 或 ls /proc

若能看到宿主机进程(如systemd、sshd,PID 通常 < 1000),则 PID Namespace 未隔离(--pid=host配备)

4. Cgroups 调整

ls /sys/fs/cgroup/ 或 cat /sys/fs/cgroup/cpu/release_agent

若release_agent路径可修改(非/bin/true),或 Cgroups 目录权限为w(可写),则存在release_agent逃逸风险

5. runtime 版本漏洞

docker version(容器内若有 docker 客户端)或 cat /proc/1/comm(查看 runtime)

若 RunC 版本 < 1.0.0-rc93(CVE-2019-5736)、Containerd 版本 < 1.6.18(CVE-2023-28840),则存在 runtime 漏洞

2. 宿主机检测:排查整体容器环境的逃逸风险

在宿主机上执行以下操作,发现全局风险配置:

检测目标

执行命令

风险判断标准

1. 特权容器列表

docker ps --format '{{.ID}} {{.Names}} {{.Ports}}' --filter "privileged=true"

输出非空则存在特权容器,需重点排查

2. 危险挂载容器

`docker inspect --format '{{.Id}} {{.Mounts}}' $(docker ps -q)

grep -E '/var/run/docker.sock

/etc

/dev/sda'`

输出非空则存在宿主机敏感目录挂载的容器

3. 内核漏洞排查

uname -r(查看内核版本) + 漏洞数据库匹配

对比 CVE 数据库(如CVE Details),若内核版本包含未修复的高危漏洞(如 CVE-2022-0492、CVE-2021-41773),则存在风险

4. runtime 版本检查

runc -v 或 containerd -v

若版本低于安全版本(RunC ≥1.0.0-rc93,Containerd ≥1.6.18),需立即更新

三、容器逃逸的防御核心

禁用特权容器:除非绝对必要,否则不运用--privileged参数启动容器;若需部分权限,通过--cap-add仅授予最小必要的 Capabilities(如仅授予CAP_NET_BIND_SERVICE而非CAP_SYS_ADMIN)。

谨慎挂载宿主机目录:避免挂载/var/run/docker.sock、/etc、/proc/sys等敏感路径;若必须挂载,使用ro(只读)权限(如-v /host/data:/container/data:ro)。

及时更新组件:定期更新宿主机内核(修复内核漏洞)、容器 runtime(RunC/Containerd)、Docker/Kubernetes 版本(修复配置缺陷和 runtime 漏洞)。

使用非 root 用户运行容器:在 Dockerfile 中通过USER指令指定普通用户,或启动容器时添加--user参数(如docker run --user 1000:1000 ubuntu),降低容器内用户权限。

部署安全监控工具:使用 Falco、Aqua Security 等工具监控容器异常行为(如容器内挂载宿主机磁盘、修改/etc/passwd、执行mount命令),及时告警逃逸尝试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/908130.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实用指南:容器逃逸漏洞

实用指南:容器逃逸漏洞pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &qu…

深入解析:卷对卷(Roll-to-Roll,R2R)技术的应用领域和技术进展

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

深入解析:卷对卷(Roll-to-Roll,R2R)技术的应用领域和技术进展

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

三种方式处理SpringBoot全局异常

在SpringBoot开发web项目时,异常处理是必不可少的一部分。在应用中,异常可能出现在任何地方,例如在控制层,服务层,数据访问层等等。如果不对异常进行处理可能会导致应用崩溃或者出现未知的错误。因此对于异常的处…

解题记录说是 | P3695 CYaRon!语

小模拟link 起因 闲的没事找模拟做,发现这个部分分的档次很多,而且好想挺好做,就做了。 是分着部分分做的,而且完全就是那种苦(封装各种实现)尽甘(飞速写完 ihu hor while)来的感觉,很爽的。 code goes first…

分享一个极度精简的绿色的 五笔输入法

这个输入法是本人修改过的 柚子输入法,极度精简,绿色无需安装,释放之后即可使用. 功能说明请看 压缩包的说明文件. 通过网盘分享的文件:youziIME2025-9-19.rar 链接: 百度网盘 如果需要修改功能,你需要懂一点Auto…

[GDKOI2023 提高组] 游戏 题解

一种比较简短的写法: 拉出直径,再在直径的每一个点上跑一下最长链,为 $ mx_i$ 这里设三点的路径交点为 \(rt\)。 假设 \(rt \rightarrow u,v,w\) 的距离为 \(dis1,dis2,dis3\) 。 容易知道 \(dis1 = (x+y-z)/2,dis2…

CSP-J/S 2025 游记

突然发现今年忘记写游记了…… [2025.6.30,2025.8.1) 中考。 [2025.8.1,2025.8.31] 暑假集训 15 天,一天比赛一天专题。早上 8:00 到机房训到 12:00 然后和高三抢饭,下午 14:00-17:00 继续搞,晚上 19:00-22:00。只有…

2025.9.19 计数dp小记

[CQOI2011] 放棋子 本题有一个性质,棋子间互不关联,又因为数据范围小,很容易 \(dp\) 记 \(f_{p,i,j}\) 表示考虑前 \(p\) 种颜色,放了 \(i\) 行 \(j\) 列的方案数 则枚举 \(p\) 放了几行几列,有 \[f_{p,i,j} = \s…

实用指南:AI推理范式:从CoT到ReAct再到ToT的进化之路

实用指南:AI推理范式:从CoT到ReAct再到ToT的进化之路pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&q…

sign up - Gon

如果注册github时出现 Unable to verify your captcha response. Please visit https://docs.github.com/articles/troubleshooting-connectivity-problems/#troubleshooting-the-captcha for troubleshooting informa…

ctfshow web入门 信息搜集

有些题目会了就没写了,只记录一下自己不会写的题目,不过信息搜集还是很重要的ctfshow web3(自带网络工具包查看数据)查看源码什么也没有扫目录也什么都没有只能说信息收集能力还欠佳, 我们可以先尝试使用浏览器自带…

完整教程:数据结构:单链表的应用(力扣算法题)第二章

完整教程:数据结构:单链表的应用(力扣算法题)第二章pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&…

CF2039E Shohag Loves Inversions

CF2039E Shohag Loves Inversions 题意: 给你一个数列,初始数列为 $ a = [0, 1] $ ,现在重复进行以下操作若干次:将当前数组中逆序对个数 \(k\) 插入当前数组中任意一个位置,包括开头或者结尾。其中 \(n\le 1e6\)…

深入解析:sqlite3的加解密全过程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

U522155 板垣 カノエ is WATCHING YOU std

U522155 板垣 カノエ is WATCHING YOU #include<bits/stdc++.h> #define int long long #define add(a,b) to[++ tot] = b,nxt[tot] = h[a],h[a] = tot #define con putchar_unlocked( ) #define ent putchar_u…

ctfshow web

ctfshow里面免费的web题不写白不写ctf.show_红包题第二弹1打开题目显示这样 看看源码有无提示可以看到提示了cmd参数,那我们就随便传点东西看看会有什么回显又是代码审计,可以看到大小写字母过滤后只有小写p可以使用…

代码随想录算法训练营第三天 | leetcode 203 707 206

203移除链表元素 注意事项:java语言的访问链表和数据用的是".",空指针是小写的null。在删除链表时先对表头进行判断避免表头是null和表头元素是要删除的元素,下面进行循环寻找时要注意判断指针的下一个指针…

Codeforces Round 1051 (Div. 2) A~D2

A. All Lengths Subtraction 思维。 每次选择长度为 \(k(k \in [1,n])\) 的区间减 \(1\),那么第一个首选的就是 \(a_i = n\) 的 位置,然后维护 \(n\) 所在的区间,检查 \(n-k+1\) 是否在其两边,有的话就扩大区间,否…

【F#学习】数组:Array

Array 在F#中, 一个数组(Array)包含0个或多个元素,长度固定,但内容可以改变。元素需要具有相同的类型。 // 声明一个数组。注意看清操作符是 [| 和 |] let empty = [| |] let emptyAlternative = Array.emptylet …