Компания Qualys выявила две уязвимости (CVE-2021-44731, CVE-2021-44730) в утилите snap-confine, поставляемой с флагом SUID root и вызываемой процессом snapd для формирования исполняемого окружения для приложений, поставляемых в самодостаточных пакетах в формате snap. Уязвимости позволяют локальному непривилегированному пользователю добиться выполнения кода с правами root в системе. Проблемы устранены в сегодняшнем обновлении пакетов snapd для Ubuntu 21.10, 20.04 и 18.04.
Первая уязвимость (CVE-2021-44730) позволяет совершить атаку через манипуляцию жёсткими ссылками, но требует отключения системной защиты жёстких ссылок (установки sysctl fs.protected_hardlinks в 0). Проблема вызвана некорректной проверкой местоположения исполняемых файлов вспомогательных программ snap-update-ns и snap-discard-ns, запускаемых с правами root. Путь к данным файлам вычислялся в функции sc_open_snapd_tool() на основе собственного пути из /proc/self/exe, что позволяло создать жёсткую ссылку на snap-confine в своём каталоге и разместить в этом каталоге свои варианты утилит snap-update-ns и snap-discard-ns. После запуска по жёсткой ссылке snap-confine запускает с правами root файлы snap-update-ns и snap-discard-ns из текущего каталога, подставленные атакующим.
Вторая уязвимость вызвана состоянием гонки и может быть эксплуатирована в конфигурации Ubuntu Desktop по умолчанию. Для успешной работы эксплоита в Ubuntu Server требуется выбор при установке одного из пакетов из секции “Featured Server Snaps”. Состояние гонки проявляется в функции setup_private_mount(), вызываемой во время подготовки пространства имён точек монтирования для пакета snap. Данная функция создаёт временный каталог “/tmp/snap.$SNAP_NAME/tmp” или использует уже существующий для bind-монтировния в него каталогов для пакета в формате snap.
Так как имя временного каталога предсказуемо, атакующий может подменить его содержимое на символическую ссылку в момент после проверки владельца, но перед обращением к системному вызову mount. Например, можно создать в каталоге /tmp/snap.lxd символическую ссылку “/tmp/snap.lxd/tmp”, указывающую на произвольный каталог, и вызов mount() последует за символической ссылкой и примонтирует каталог в пространстве имён snap. Таким образом можно примонтировать своё содержимое в /var/lib и через замену /var/lib/snapd/mount/snap.snap-store.user-fstab организовать монтирование своего каталога /etc в пространстве имён snap-пакета для подстановки своего /etc/ld.so.preload.
Отмечается, что создание эксплоита оказалось нетривиальной задачей, так как утилита snap-confine написана на языке Go с использованием приёмов безопасного программирования, имеет защиту на основе профилей AppArmor, производит фильтрацию системных вызовов на основе механизма seccomp и применяет для изоляции пространство имён для монтирования. Тем не менее, исследователям удалось подготовить рабочий эксплоит для получения прав root в системе.