CVE-2022-0847 used to achieve container escape (overwrite any read-only files on host)
Slides (in Chinese) available [here](./slides-zh.pdf)
利用CVE-2022-0847 (Dirty Pipe) 实现容器逃逸（效果为覆写宿主机上任意只读文件）
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!
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](https://man7.org/linux/man-pages/man7/capabilities.7.html), 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!
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
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!