Исследователь безопасности из GitHub выявил уязвимость (CVE-2020-16125) в дисплейном менеджере GDM (GNOME Display Manager), отвечающем за вывод экрана входа в систему. В сочетании с другой уязвимостью в сервисе отслеживания учётных записей (accounts-daemon) проблема позволяет выполнить код с правами root. Уязвимость устранена в GNOME 3.36.2 и 3.38.2. Возможность эксплуатации уязвимости подтверждена в Ubuntu и производных дистрибутивах.
Уязвимость связана с некорректным запуском утилиты начальной настройки в случае невозможности обратиться к сервису accounts-daemon через DBus. Непривилегированный пользователь может вызвать крах или зависание процесса accounts-daemon, что создаст условия для запуска из GDM утилиты gnome-initial-setup, через которую можно зарегистрировать нового пользователя, входящего в группу sudo, т.е. имеющего возможность запуска программ с правами root. В штатной ситуации GDM вызывает gnome-initial-setup для заведения первого пользователя, если в системе отсутствуют учётные записи. Проверка наличия учётных записей производится через обращение к accounts-daemon. В случае сбоя указанного процесса, GDM считает, что учётные записи отсутствуют и запускает процесс начальной настройки.
Выявлено два способа нарушения работы accounts-daemon: Первый (CVE-2020-16126) вызван некорректным сбросом привилегий, а второй (CVE-2020-16127) ошибкой при обработке файла ".pam_environment". Кроме того в accounts-daemon найдена ещё одна уязвимость (CVE-2018-14036), вызванная неверными проверками файловых путей и позволяющая прочитать содержимое произвольных файлов в системе. Уязвимости в accounts-daemon вызваны изменениями, внесёнными разработчиками Ubuntu, и не проявляются в основном коде accounts-daemon от проекта FreeDesktop и в пакете из Debian.
Проблема CVE-2020-16127 присутствует в добавленном в Ubuntu патче с реализацией функции is_in_pam_environment, которая читает содержимое файла .pam_environment из домашнего каталога пользователя. Если вместо этого файла разместить символическую ссылку на /dev/zero, процесс accounts-daemon зависает на операции бесконечного чтения и перестаёт отвечать на запросы через DBus.
Уязвимость CVE-2020-16126 вызвана другим патчем, выполняющим сброс привилегий до текущего пользователя при обработке некоторых вызовов DBus (например, org.freedesktop.Accounts.User.SetLanguage). Процесс accounts-daemon штатно выполняется с правами root, что не позволяет обычному пользователю отправлять сигналы. Но благодаря добавленному патчу, привилегии процесса могут быть сброшены и пользователь может завершить этот процесс через отправку сигнала. Для совершения атаки достаточно создать условия для сброса привилегий (RUID) и отправить процессу accounts-daemon сигнал SIGSEGV или SIGSTOP.
Типовой сценарий атаки:
Уязвимость связана с некорректным запуском утилиты начальной настройки в случае невозможности обратиться к сервису accounts-daemon через DBus. Непривилегированный пользователь может вызвать крах или зависание процесса accounts-daemon, что создаст условия для запуска из GDM утилиты gnome-initial-setup, через которую можно зарегистрировать нового пользователя, входящего в группу sudo, т.е. имеющего возможность запуска программ с правами root. В штатной ситуации GDM вызывает gnome-initial-setup для заведения первого пользователя, если в системе отсутствуют учётные записи. Проверка наличия учётных записей производится через обращение к accounts-daemon. В случае сбоя указанного процесса, GDM считает, что учётные записи отсутствуют и запускает процесс начальной настройки.
Выявлено два способа нарушения работы accounts-daemon: Первый (CVE-2020-16126) вызван некорректным сбросом привилегий, а второй (CVE-2020-16127) ошибкой при обработке файла ".pam_environment". Кроме того в accounts-daemon найдена ещё одна уязвимость (CVE-2018-14036), вызванная неверными проверками файловых путей и позволяющая прочитать содержимое произвольных файлов в системе. Уязвимости в accounts-daemon вызваны изменениями, внесёнными разработчиками Ubuntu, и не проявляются в основном коде accounts-daemon от проекта FreeDesktop и в пакете из Debian.
Проблема CVE-2020-16127 присутствует в добавленном в Ubuntu патче с реализацией функции is_in_pam_environment, которая читает содержимое файла .pam_environment из домашнего каталога пользователя. Если вместо этого файла разместить символическую ссылку на /dev/zero, процесс accounts-daemon зависает на операции бесконечного чтения и перестаёт отвечать на запросы через DBus.
Уязвимость CVE-2020-16126 вызвана другим патчем, выполняющим сброс привилегий до текущего пользователя при обработке некоторых вызовов DBus (например, org.freedesktop.Accounts.User.SetLanguage). Процесс accounts-daemon штатно выполняется с правами root, что не позволяет обычному пользователю отправлять сигналы. Но благодаря добавленному патчу, привилегии процесса могут быть сброшены и пользователь может завершить этот процесс через отправку сигнала. Для совершения атаки достаточно создать условия для сброса привилегий (RUID) и отправить процессу accounts-daemon сигнал SIGSEGV или SIGSTOP.
Типовой сценарий атаки:
- Создаётся символическая ссылка ~/.pam_environment, указывающая на /dev/zero:
ln -s /dev/zero ~/.pam_environment
- Вызывается операция для активации accounts-daemon, которая приводит к чтению файла ~/.pam_environment, зацикливанию и сбросу привилегий до RUID текущего пользователя (вместо запуска dbus-send можно просто изменить язык в настройках "Region & Language"):
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply=literal /org/freedesktop/Accounts/User`id -u` org.freedesktop.Accounts.User.SetLanguage string:kevwozere &
- Обработчик останавливается через отправку сигнала SIGSTOP, а файл ~/.pam_environment удаляется, чтобы не блокировать следующие входы в систему:
kill -SIGSTOP `pidof accounts-daemon`
rm ~/.pam_environment
- Пользователь завершает графический сеанс и переходит к текстовую консоль (Ctrl-Alt-F1).
- После завершения графического сеанса GDM пытается вывести экран входа в систему, но подвисает, пытаясь получить ответ от accounts-daemon.
- Из консоли процессу accounts-daemon отправляются сигналы SIGSEGV и SIGCONT, что приводит к его краху. Также можно отправить сигналы до выхода из графического сеанса, но нужно сделать это с задержкой, чтобы успеть завершить сеанс и до отправки сигнала успел запуститься GDM:
nohup bash -c "sleep 30s; kill -SIGSEGV `pidof accounts-daemon`; kill -SIGCONT `pidof accounts-daemon`"
- Запрос к accounts-daemon в GDM завершается сбоем и GDM вызывает утилиту gnome-initial-setup, в интерфейсе которой достаточно создать новую учётную запись.