Share
## https://sploitus.com/exploit?id=E4C46A03-D265-51D4-AF1A-A576FA76B6B3
# CVE-2022-0847
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) 实现容器逃逸(效果为覆写宿主机上任意只读文件)

中文汇报PPT在[这里](./slides-zh.pdf)

## 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](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! 

## Usage
```bash
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`:
![](images/touch.png)

Then, start a container with capability `CAP_DAC_READ_SEARCH`, first try to dump `/home/vagrant/flag.txt` on host, we get `hello world`:
![](images/dump.png)

then try to overwrite target file from offset 1 with content `abcdefghij`:
![](images/write.png)

dump target file again, now the content is `habcdefghij`! Exit container and check `/home/vagrant/flag.txt` on host, its content is `habcdefghij`.
![](images/dump-1.png)

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

## Credits
+ https://dirtypipe.cm4all.com/
+ http://stealth.openwall.net/xSports/shocker.c