Я есть root. Повышение привилегий в ОС Linux через SUID/SGID
В прошлом посте я провел «обзорную экскурсию» по методам повышения привилегий в ОС Linux. Сегодня разбираю вектор повышения привилегий через небезопасные разрешения SUID/SGID. Поэтому больше консоли и меньше слов.

Что такое SUID?
Бит смены владельца или SUID (Set User ID) — это разрешение файловой системы Linux, которое позволяет запустить исполняемый файл от имени его владельца. Он нужен, потому что многие действия в Linux (например, открытие «сырого» сетевого сокета) требуют прав суперпользователя. Хорошо знакомая всем команда ping использует сетевые сокеты и поэтому должна быть запущена от root«а. Каким образом можно позволить обычному пользователю применять команду ping? Можно выдать пользователю sudo на необходимые команды. Но представьте, что на условной Linux-машине имеется 100 пользователей и насчитывается около 20 привилегированных команд. А как потом управлять разрешениями sudo на все это «богатство»? Не самое элегантное решение, не правда ли? С другой стороны, бит смены владельца значительно упрощает процесс. Бит смены владельца сообщит системе, что все 100 пользователей системы запускают команду ping от имени root.
Итак, мы с вами поняли, что представляет собой SUID, но также это понимают и хакеры. В большинстве случаев повышение привилегий через исполняемый файл с SUID возможно, если:
- исполняемый файл позволяет взаимодействовать с файловой системой;
- исполняемый файл так или иначе имеет возможность выхода в командную строку.
Пример с curl
Разберемся по порядку. Допустим, я обнаружил, что исполняемому файлу curl выставлен бит смены владельца, мы можем это понять по букве s в разрешениях файла.

Выставление SUID для curl
Выставленный SUID позволяет скачивать файл от имени root«а. Поскольку файл скачивает root, то он же является и владельцем файла.

Загрузка файла через curl с SUID
Хорошо, что с этим делать дальше? Попытаюсь заменить какой-нибудь чувствительный файл: /etc/passwd подходит как нельзя лучше. Сначала скопирую существующий файл на хост атакующего.

Скачиваю файл командой scp
В полученном файле поменяю ID пользователя и группы для пользователя bob с 1000 на 0 (что соответствует root).

Исходные ID пользователя bob
Отредактированный файл скачаю на атакуемый хост с помощью команды curl.

Успешное повышение привилегий
Пример с systemctl
Думаю, стало понятнее, однако давайте разберем другой пример: я подобрал пароль пользователя bob и получил доступ по SSH. Осматриваюсь и изучаю окружение — в этом случае командой find.
find / -user root -perm -u=s -type f 2>/dev/null

Почувствуй разницу: слева вывод linpeas, справа, по сути, тот же вывод, но команда find введена вручную
Нахожу в выводе команды find бинарник /usr/bin/systemctl. Раз у меня есть доступ к systemctl, да еще и в контексте root (ведь я нашел этот бинарник, выполняя поиск файлов, владельцем которых является root и для которых выставлен suid), я могу запустить вредоносный сервис. Особого кун-фу тут не требуется, достаточно создать текстовый файл с описанием сервиса.
[Service]
Type=oneshot
ExecStart=/bin/sh -c "id > /tmp/output"
[Install]
WantedBy=multi-user.target

Демонстрация работы сервиса
Мне ничего не мешает изменить сервис, например, написать в него бэк-коннект. Остается только поднять хендлер (обработчик) на хосте атакующего и перезапустить сервис.

Успешное повышение привилегий. Наверху хендлер, внизу запуск сервиса
Я привел примеры, в которых бит смены владельца выставлен у пользователя root, но этот вектор также можно использовать для компрометации менее привилегированных пользователей системы. Как видите, бит смены владельца — это довольно чувствительная к безопасности «вещь», и он может оказаться узким местом харденинга Linux-системы.
Больше конкретных примеров повышения привилегий через SUID можно найти тут, включая разобранный нами.
А что с битом смены группы владения SGID (Set Group ID)?
В целом суть та же, но некоторые трюки будут сложнее, например /etc/passwd таким образом перезаписать не удастся, так как группе root нельзя редактировать файл. Да и сервис перезапустить не получится.

Разрешения файла /etc/passwd не позволяют группе root изменение

Попытка перезапуска сервиса
Остается вариант с интерактивным шеллом, например через vim. Для этого используйте команду:
vim -c ':py import os; os.execl("/bin/sh", "sh", "-pc", "reset; exec sh -p")
Группа root позволяет читать содержимое директории /root, но при этом нельзя даже прочитать содержимое файла id_rsa. Бит смены группы владения SGID дает несравнимо меньшие возможности для повышения привилегий.

Содержимое директории /root
Харденинг
Для безопасного харденинга рекомендую исключить наличие бита смены владельца/группы для указанных в перечне исполняемых файлов. При этом нужно учитывать, что за удалением бита смены владельца/группы могут последовать некорректное поведение сервиса и траблшутинг. И уж точно не стоит удалять бит смены владельца у всех исполняемых файлов.
Напоследок
В статье я использовал примеры из лучшего, на мой взгляд, сборника по повышению привилегий gtfobins.
- curl
- systemctl
- vim
Если у вас появится интерес к разбору других кейсов повышения привилегий через SUID/SGID (или нет, не важно), пишите в комментариях или мне в личку. В следующем посте обсудим, как получать стабильный shell. Успешной охоты!
