
CVE-2022-0847, используемый для побега из контейнера. Эксплуатация CVE-2022-0847 (Dirty Pipe) для осуществления побега из контейнера.
CVE-2022-0847 используется для побега из контейнера (перезапись любых файлов, доступных только для чтения, на хосте)
Слайды (на китайском) доступны здесь
Использование CVE-2022-0847 (Dirty Pipe) для осуществления побега из контейнера (эффект — перезапись любых файлов, доступных только для чтения, на хосте)
PPT доклада на китайском доступен здесь
Если ядро уязвимо к CVE-2022-0847, атакующий может перезаписывать файлы, доступные только для чтения (Непостоянно! Посетите https://dirtypipe.cm4all.com/ для подробностей). Однако контейнер может получить доступ только к файлам внутри контейнера. К счастью, при наличии CAP_DAC_READ_SEARCH атакующий теперь может перезаписывать файлы на хосте!
Как объясняется на https://dirtypipe.cm4all.com/, для перезаписи файла, доступного только для чтения, мы должны splice() его в pipe. Чтобы использовать 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(), чтобы отправить содержимое целевого файла в pipe, а затем перезаписать его!
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.

Да, мы только что перезаписали файл на хосте из контейнера!