/CVE-2022-0847-Container-Escape

CVE-2022-0847 used to achieve container escape 利用CVE-2022-0847 (Dirty Pipe) 实现容器逃逸

Primary LanguageCMIT LicenseMIT

CVE-2022-0847

CVE-2022-0847 used to achieve container escape (overwrite any read-only files on host)

Slides (in Chinese) available here

利用CVE-2022-0847 (Dirty Pipe) 实现容器逃逸(效果为覆写宿主机上任意只读文件)

中文汇报PPT在这里

Introduction

If the kernel is vulnerable to CVE-2022-0847, the attacker can overwrite read-only files (Non-persistent! Visit https://dirtypipe.cm4all.com/ for more details). However, container can only access files inside container. Fortunately, when given CAP_DAC_READ_SEARCH, attacker can now overwrite files on host!

Explanation

As https://dirtypipe.cm4all.com/ explains, to overwrite a read-only file, we should splice() it to pipe. To use splice(), we must first open target file with O_RDONLY flag to get a file descriptor.

That's when CAP_DAC_READ_SEARCH came into my mind. According to Linux manual, when given CAP_DAC_READ_SEARCH, attacker inside container can:

  • Bypass file read permission checks and directory read and execute permission checks
  • invoke open_by_handle_at(2)

With capability CAP_DAC_READ_SEARCH, we can search host filesystem and use open_by_handle_at(2) to read-only open any files on host from container, getting its file descriptor (Visit http://stealth.openwall.net/xSports/shocker.c for more details).

Now that we've got file descriptor of target file on host, we can of course use splice() to send target file content to pipe, and then overwrite it!

Usage

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

Example

First, create a read-only file /home/vagrant/flag.txt by root user on host, content of which is hello world:

Then, start a container with capability CAP_DAC_READ_SEARCH, first try to dump /home/vagrant/flag.txt on host, we get hello world:

then try to overwrite target file from offset 1 with content abcdefghij:

dump target file again, now the content is habcdefghij! Exit container and check /home/vagrant/flag.txt on host, its content is habcdefghij.

Yes, we just overwrote a file on host from container!

Credits