利用CVE-2022-0847 (Dirty Pipe) 实现容器逃逸(效果为覆写宿主机上任意只读文件)
中文汇报PPT在这里
如果内核存在 CVE-2022-0847 漏洞,攻击者可以覆写只读文件(非持久化!更多细节请访问 https://dirtypipe.cm4all.com/ )。然而,容器只能访问容器内的文件。幸运的是,当拥有 CAP_DAC_READ_SEARCH 能力时,攻击者就可以覆写宿主机上的文件了!
正如 https://dirtypipe.cm4all.com/ 所解释的,要覆写只读文件,我们需要通过 splice() 将其送入管道。要使用 splice(),我们必须先用 O_RDONLY 标志打开目标文件,以获得一个文件描述符。
这时我想到了 CAP_DAC_READ_SEARCH。根据 Linux 手册,当拥有 CAP_DAC_READ_SEARCH 时,容器内的攻击者可以:
借助 CAP_DAC_READ_SEARCH 能力,我们可以在宿主机文件系统中搜索,并使用 open_by_handle_at(2) 从容器内以只读方式打开宿主机上的任意文件,从而获得其文件描述符(更多细节请访问 http://stealth.openwall.net/xSports/shocker.c )。
既然我们已经获得了宿主机上目标文件的文件描述符,当然就可以使用 splice() 将目标文件内容送入管道,然后覆写它!
cp /etc/password . # back up /etc/password
gcc dp.c -o dp
docker run --rm -it -v $(pwd):/exp --cap-add=CAP_DAC_READ_SEARCH ubuntu
/exp/dp /etc/passwd 1 ootz: # overwrite /etc/password on host from offset 1
/etc/dp /etc/passwd # dump /etc/passwd on host
首先,以 root 用户在宿主机上创建一个只读文件 /home/vagrant/flag.txt,其内容为 hello world:

然后,启动一个拥有 CAP_DAC_READ_SEARCH 能力的容器,先尝试转储宿主机上的 /home/vagrant/flag.txt,得到 hello world:

接着尝试从偏移量 1 开始用内容 abcdefghij 覆写目标文件:

再次转储目标文件,现在内容变成了 habcdefghij!退出容器并在宿主机上检查 /home/vagrant/flag.txt,其内容为 habcdefghij。

没错,我们刚刚从容器内覆写了宿主机上的一个文件!