Уязвимости snapd и rust coreutils: получение root-доступа в ubuntu

Уязвимости в snapd и Rust Coreutils: как локальный пользователь может получить root-доступ в Ubuntu
------------------------------------------------------------------------------

Исследователи из компании Qualys обнаружили критическую уязвимость (CVE-2026-3888) в механизме взаимодействия инструментов snap-confine и systemd-tmpfiles в Ubuntu. Ошибка позволяет обычному локальному пользователю при определённых условиях повысить свои привилегии до уровня root. Наиболее опасна проблема для Ubuntu 24.04, где используемая по умолчанию конфигурация делает систему уязвимой сразу после установки.

В более ранних версиях Ubuntu - с 16.04 по 22.04 - эксплойт возможен не всегда, а только в тех нестандартных конфигурациях, где администратор вручную приблизил поведение системы к новым релизам (например, изменил параметры очистки временных каталогов). Ветки Ubuntu, в которых используется snapd, получили исправление через обновление пакета: уязвимость закрыта в версии snapd 2.75.

Где именно возникла проблема

Корень уязвимости - в некорректном взаимодействии двух компонентов, работающих с повышенными правами:

- snap-confine - утилита, отвечающая за подготовку и запуск изолированного окружения (sandbox) для snap-приложений;
- systemd-tmpfiles - инструмент systemd, занимающийся автоматическим созданием, обслуживанием и удалением временных файлов и каталогов, в том числе в /tmp.

По умолчанию systemd-tmpfiles настроен на удаление устаревших объектов в каталоге `/tmp`. В Ubuntu предусмотрена очистка временных директорий с определённой периодичностью: в версии 24.04 - примерно раз в 10 дней, в более новых релизах - раз в 30 дней. Именно это периодическое удаление и создаёт окно возможностей для атакующего.

Как злоумышленник использует /tmp/.snap

Механизм эксплуатации строится на моменте, когда systemd-tmpfiles удаляет каталог `/tmp/.snap`, а затем snap-confine снова его создаёт. Между этими двумя событиями появляется короткий промежуток времени, в который непривилегированный пользователь может создать подставной каталог `/tmp/.snap` со своим содержимым.

Сценарий атаки выглядит следующим образом:

1. Злоумышленник ждёт, когда systemd-tmpfiles очистит `/tmp` и удалит `/tmp/.snap`.
2. Сразу после удаления он создаёт собственный каталог `/tmp/.snap` и помещает туда подготовленную структуру директорий и файлов.
3. В частности, в директорию `/tmp/.snap/usr/lib/x86_64-linux-gnu.exchange` злоумышленник помещает модифицированные версии разделяемых библиотек и/или динамического загрузчика `ld.so`.
4. Затем он инициирует запуск snap-приложения, чтобы запустить snap-confine и заставить систему сформировать новое sandbox-окружение с опорой на подменённый `/tmp/.snap`.

Так как очистка временных файлов запускается редко, злоумышленнику потенциально приходится ждать дни, пока сработает systemd-tmpfiles. Но при целевой атаке и постоянном контроле над системой это не является техническим препятствием.

Критический момент - подмена библиотек

Во время формирования sandbox-окружения snap-confine временно использует каталог `/tmp/.snap`, где собирается содержимое будущего окружения. На этом этапе атакующий дожидается удобного момента, когда нужные файлы уже созданы, и выполняет ещё один шаг:

- переименовывает каталог `/tmp/.snap/usr/lib/x86_64-linux-gnu.exchange` в
`/tmp/.snap/usr/lib/x86_64-linux-gnu`.

В результате системные библиотеки и загрузчик, которые будут bind-монтированы с правами root, фактически берутся не из доверенного места, а из специально подготовленного злоумышленником набора файлов. Таким образом, он получает контроль над тем, какие разделяемые библиотеки и какой `ld.so` запускаются внутри snap-песочницы.

Достаточно затем запустить любую suid-программу, использующую динамическое связывание внутри этого окружения, - и подготовленные библиотеки выполнят произвольный код уже с root-привилегиями.

Переход из песочницы в основную систему

Формально root-доступ на этом этапе получен внутри изолированного окружения snap, которое ограничено профилями AppArmor и фильтрами системных вызовов на базе seccomp. Но ограничения песочницы не мешают злоумышленнику подготовить "мостик" в основную систему.

Один из наиболее простых и надёжных способов:

1. Находясь с правами root внутри sandbox-окружения, злоумышленник копирует `/bin/bash` в каталог вида:
`/var/snap/$SNAP/common/`.
2. На эту копию он выставляет права `04755` (suid root).

Так как каталог `/var/snap//common` доступен как из песочницы, так и из основной системы, изменённый файл bash с установленным suid-битом оказывается виден вне sandbox. После этого любой непривилегированный пользователь на хост-системе может просто запустить:

`/var/snap//common/bash`

и получить полноценный root-доступ уже в обычном системном окружении, без ограничений AppArmor и seccomp.

Дополнительная уязвимость в uutils coreutils (Rust Coreutils)

Параллельно с анализом уязвимости в snapd была выявлена ещё одна проблема - на этот раз в наборе утилит uutils coreutils, которые представляют собой переписанный на языке Rust аналог GNU Coreutils. Несмотря на репутацию Rust как языка, минимизирующего целый класс ошибок с памятью, логические уязвимости, связанные с состояниями гонки и некорректной логикой, по-прежнему возможны.

Обнаруженная уязвимость также позволяет локальному пользователю получить права root. Проблему нашли во время анализа изменений, готовившихся к включению в Ubuntu 25.10. До выхода релиза было принято решение применить обходной путь: вместо уязвимой реализации `rm` из набора uutils в системе поставили классический бинарник `gnurm` как `/usr/bin/rm`.

В исходном пакете uutils баг исправили в версии `uutils coreutils 0.3.0`. При этом в журнале изменений прямо не указали факт устранения уязвимости, ограничившись формулировкой о внедрении "безопасного обхода путей" в таких утилитах, как `rm`, `du`, `chmod` и `chgrp`.

Состояние гонки в утилите rm

Суть ошибки заключалась в состоянии гонки в утилите `rm`, которое проявлялось при работе под root и рекурсивном удалении каталогов. Локальный пользователь мог организовать ситуацию, когда процесс `rm`, выполняющийся с привилегиями суперпользователя, начинал удалять файлы, контролируемые атакующим.

Алгоритм работы `rm -r` в уязвимой реализации был следующим:

1. Сначала `rm` рекурсивно обходит и проверяет все каталоги и подкаталоги, собирая структуру для последующего удаления.
2. Затем, после завершения проверки, он начинает удалять директорий в обратном порядке, вызывая `rmdir()` для каждого каталога.

Если атакующий успевал в интервале между проверкой родительского каталога и проверкой вложенных в него каталогов подменить этот родительский каталог на символическую ссылку, дальнейшее выполнение `rm` приводило к тому, что `rmdir()` вызывался уже на путь, указывающий на совершенно другой каталог в системе.

Результат - можно было добиться:

- удаления произвольного каталога;
- а при грамотном подборе целевой директории - и повышения привилегий, за счёт изменений в файловых структурах, влияющих на безопасность.

Связь с механизмом snap и повторное повышение привилегий

Исследователи показали, что уязвимость в `rm` можно применять не только для разрушительных действий (удаления любых файлов), но и для повторного получения root через механизм snap-песочницы.

Один из векторов атаки:

1. Воспользоваться уязвимым `rm`, чтобы добиться удаления каталога:
`/tmp/snap-private-tmp/$SNAP/tmp/.snap`.
2. После удаления - подменить его содержимое или создать нужную структуру директорий, аналогично описанной выше атаке на snap-confine.
3. Далее метод повышения привилегий повторяет общую схему: воздействие на содержимое sandbox, подмена библиотек и использование suid-приложения.

Таким образом, баг в Rust-реализации `rm` становится ещё одним мостиком к эксплуатации уязвимости в snapd или смежных механизмах.

Как уязвимость могла эксплуатироваться в реальных системах

Особую опасность создаёт то, что уязвимая утилита `rm` потенциально использовалась в сценариях, запускаемых по расписанию с правами root. Один из таких примеров - ежедневный скрипт:

`/etc/cron.daily/apport`

Он выполняется суперпользователем и рекурсивно очищает содержимое каталога `/var/crash`, куда имеют право записи все пользователи системы. Если в этом месте используется уязвимая версия `rm`, атакующий может:

1. Разместить в `/var/crash` специально подготовленной структуры каталогов и файлов.
2. Организовать подмену одного из каталогов на символическую ссылку в подходящий момент.
3. Дождаться запуска cron-скрипта и, через состояние гонки, заставить root-процесс удалить или изменить указанный им путь.

Так реализуется локальное повышение привилегий без прямого взаимодействия с администратором.

Почему язык Rust не спас от уязвимости

Важно подчеркнуть: Rust действительно решает значительную часть проблем, связанных с безопасностью памяти (use-after-free, переполнения буфера, двойное освобождение и т.д.). Однако он не гарантирует отсутствие логических ошибок и состояний гонки на уровне архитектуры программы.

В данном случае:

- Ошибка заключалась в том, как именно реализован обход файловой системы и порядок операций над каталогами.
- Никаких типичных "опасных" конструкций работы с памятью не было - уязвимость появилась чисто из-за того, что разработчики недоучли возможность изменения структуры каталогов между проверкой и удалением.

Этот пример подчёркивает: выбор языка снижает вероятность определённых классов ошибок, но не отменяет необходимость тщательного аудита логики и моделирования сценариев, в которых атакующий может вмешаться в последовательность системных вызовов.

Что уже сделано и как защититься

С точки зрения конечного пользователя и администратора важно следующее:

- Уязвимость в snapd устранена в snapd версии 2.75. При установке обновлений безопасности пакет подтягивается автоматически большинством стандартных конфигураций Ubuntu.
- Проблема в uutils coreutils исправлена в uutils coreutils 0.3.0, а в планировавшейся Ubuntu 25.10 был применён дополнительный защитный шаг - использование проверенного `gnurm` вместо Rust-реализации `rm` в системных задачах.
- Исправлена логика обхода путей в нескольких критичных утилитах (`rm`, `du`, `chmod`, `chgrp`), что снижает риск аналогичных атак в будущем.

Администраторам стоит:

1. Убедиться, что система установила последние обновления безопасности, особенно связанные с snapd и системными утилитами.
2. Проверить, не используются ли в критичных скриптах альтернативные реализации coreutils из сторонних репозиториев без должного аудита.
3. По возможности ограничить частоту и условия запуска задач, работающих с world-writable каталогами (`/tmp`, `/var/crash` и т.п.), а также контролировать права доступа к таким путям.

Практические выводы для администраторов и разработчиков

Эта история демонстрирует несколько важных моментов:

- Сложные подсистемы изолирования (как snap, AppArmor, seccomp) сами по себе становятся мишенью для атак, если в их логике есть несогласованности.
- Временные каталоги и системные инструменты очистки нуждаются в особом внимании: взаимодействие периодической очистки и механизмов песочниц может порождать неожиданные состояния гонки.
- Язык программирования не является абсолютной защитой: Rust помогает избежать целого пласта ошибок, но не освобождает от необходимости тщательного проектирования алгоритмов и проверки граничных случаев, особенно связанных с файловой системой и правами доступа.

Для разработчиков системных компонентов критически важно учитывать модель противника: даже простой локальный пользователь с правом записывать в /tmp и /var/crash может пошагово подготовить сложную атаку, опирающуюся на редкие, но предсказуемые события - такие как запуски systemd-tmpfiles или ежедневные cron-задания.

Итог

Уязвимости в связке snapd + systemd-tmpfiles и в Rust-реализации coreutils показали, что даже современные дистрибутивы и "безопасные" языки не гарантируют безупречной защиты. Ошибки в логике и в организации работы с файловой системой позволяют локальным пользователям поднимать свои привилегии до root, используя редкие, но неизбежные системные процедуры - очистку временных файлов, работу песочниц и автоматические cron-задания.

Своевременное обновление пакетов, осторожное использование альтернативных системных утилит и внимательное отношение к world-writable каталогам остаются ключевыми практиками, без которых нельзя говорить о реальной безопасности даже в формально защищённой системе.

Комментарии

ИванСтроитель 13-04-2026 15:28
Если тема загородных домов действительно интересна, рекомендую присмотреться к СК «Счастливая Жизнь» — они как раз специализируются на проектировании и строительстве домов комфорт и премиум-класса под ключ в Ижевске и по Удмуртии. Делают полный цикл: от проекта и согласований до отделки и благоустройства участка, можно сразу въезжать. У знакомых готовый коттедж уже второй год — по качеству и срокам нареканий нет. Сайт тут: СК «Счастливая Жизнь» — есть примеры реализованных проектов и можно прикинуть бюджет по метражу и комплектации.
1
1
Прокрутить вверх