В предыдущей статье мы рассмотрели вопросы хранения учетных данных в ОС семейства Линукс. Теперь перейдем к обсуждению вопросов правильной и не очень настройки прав доступа к различным объектам операционной системы.

Напомню основные моменты относительно учетных записей в Линукс: есть суперпользователь root (id=0), который может все и есть все остальные учетные записи (id от 500 или 1000), которые имеют ряд ограничений и по идее не могут нанести большого вреда системе.

Но на практике возможны различные ситуации, когда обычному пользователю необходимы административные права. Например, обычный пользователь не может прочитать файл с хэшами паролей /etc/shadow, но он может изменить свой собственный пароль с помощью команды passwd. Очевидно, что для внесения изменений в защищенный файл команда должна выполняться с правами суперпользователя. И таких примеров может быть довольно много.

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

su и sudo, когда хочется большего…

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

Команда su заменяет пользователя текущей оболочки shell на указанного, например su user1 заменит на пользователя user1. Естественно, при запуске su система запросит пароль того пользователя, на shell которого вы хотите переключиться. Далее происходит запуск нового экземпляра оболочки с указанными параметрами. Команда su позволяет не выходя из системы, без лишних манипуляций повышать возможности управления операционной системой или наоборот ограничивать их.

Вызов su без аргументов приведет к запуску оболочки root. Для возврата в оболочку основного пользователя, из под которого была вызвана команда su необходимо просто ввести exit.

Одновременным достоинством и недостатком su является то, что эта команда переключает в оболочку другого пользователя и позволяет выполнять в ней любые действия, разрешенные данному пользователю. Удобно для выполнения административных задач но не слишком безопасно, когда обычному пользователю необходимо просто разрешить выполнение одной или нескольких привилегированных команд.

Альтернативой su является команда sudo.  Данная команда предоставляет временное повышение привилегий для одной команды. Предоставляя привилегии root только при необходимости, sudo снижает вероятность того, что пользователь сможет нанести существенный ущерб системе своими действиями.

Основное отличие двух команд на примере пользователя root: su переключает вас в аккаунт root и требует пароль root. Sudo запускает с привилегиями root одну команду - она не переключает вас в аккаунт суперпользователя и не требует отдельного пароля root. Исключение sudo -i.

Кстати, о паролях. При вводе sudo команда система запрашивает пароль текущего пользователя. Хотя возможен вариант, когда sudo выполняется без пароля, но об этом чуть позже. Запрос пароля делается для того, чтобы в случае, если посторонний получил доступ к незаблокированной консоли, он не смог выполнить ничего привилегированного.

Но даже ввод корректного пароля еще не гарантирует выполнение команды под root.

Дело в том, что для разрешения запуска команд по sudo пользователь должен быть внесен в специальный файл /etc/sudoers, содержащий настройки использования sudo. Для нас в плане настройки доступа наиболее интересен раздел, связанный с разрешенными пользователям командами:

# User privilege specification

root    ALL=(ALL:ALL) ALL

user2 ALL = (root) NOPASSWD: /usr/sbin/iftop

user2 ALL = (root) NOPASSWD: /bin/more

Если мы хотим разрешить пользователю запускать под sudo любые команды, то необходимо использовать ключ ALL, например

user2 ALL=(ALL) ALL

 А если при этом мы еще и не хотим спрашивать пароль, то используем NOPASSWD

user3 ALL=(ALL) NOPASSWD: ALL

Аналогично, мы можем не спрашивать пароль при запуске конкретной команды

user2 ALL = (root) NOPASSWD: /bin/more

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

Например

Как мы узнаем из следующей статьи, гранулированные настройки тоже не всегда являются безопасными и в некоторых случаях могут привести к получению пользователем командной оболочки root. Но разрешение ALL точно позволит пользователю получить командную оболочку, если он этого захочет.

Поэтому учитывайте это обстоятельство при настройке /etc/sudoers. Разрешать всем все явно не нужно.

Права и SUID bit

Вернемся к приведенному ранее примеру со сменой пароля обычным пользователем с помощью команды passwd. Но для того, чтобы понять как выполняется этот трюк с доступом к привилегированному файлу мы немного поговорим о том, как в Линукс осуществляется доступ к файлам.

В стандартной модели доступа есть 3 вида прав, помимо специальных:

  1. чтение

  2. запись

  3. исполнение (для директорий прохождение через них)

Права на файлы определяются для пользователей из трех групп:

  1. для владельца

  2. для группы владельца

  3. для всех остальных

Для каждой операции выделены свои группы битов:

В зависимости от того, что разрешено, мы можем увидеть соответствующий набор значений:

Также права доступа можно представить в виде чисел, формируемых по следующему правилу:

Для того, чтобы пользователь не обладающий административными правами мог запускать приложения, требующие права root для своей работы (как в нашем примере с passwd) в Линукс предусмотрен специальный механизм - SUID (Set UID) bit. Данный бит позволяет выполнение программы с правами хозяина файла. Это ключевой механизм повышения прав в Unix системах. Особенности SUID программ в стандартных конфигурациях Linux:

  • Работают с полномочиями пользователя root.

  • Используются для выполнения безопасных привилегированных операций.

  • Используются для штатной смены идентификаторов пользователя: su, sudo, pkexec.

  • Программы учитывают идентификатор запустившего их пользователя и различные файлы конфигурации.

Для того, чтобы установить SUID бит необходимо воспользоваться следующей командой:

chmod u+s выполнимый_файл

в результате в выводе в правах будет отображаться буква s

Обратите внимание на то, что владельцем файла является root. Кстати же знакомая нам команда sudo тоже имеет SUID бит.

Посмотрим, что произойдет, когда двоичный файл, имеющий SUID бит, выполнится. Созданный процесс изменит свой эффективный идентификатор пользователя (EUID) со стандартного UID на владельца этого специального двоичного исполняемого файла который в этом случае - root.

Ядро принимает решение, имеет ли этот процесс привилегию, просматривая EUID процесса. Потому что теперь EUID указывает на root - эта операция не будет отклонена ядром.

При самостоятельной установке SUID bit администраторам нужно быть особенно внимательными, так как некоторые утилиты имеют штатный функционал позволяющий запускать командную оболочку. О том как эксплуатировать подобные уязвимости мы подробно поговорим в следующей статье. Но прежде, чем разрешать какой-либо команде запускаться по sudo или устанавливать SUID bit я бы рекомендовал сначала прочитать man по данной команде, нет ли там ключика, позволяющего запускать shell.

Непутевый PATH

Переменная среды PATH предназначена для указания оболочке, где искать исполняемые файлы. То есть, благодаря PATH можно указывать только имя выполняемого файла без полного пути, а дальше уже ОС будет пытаться найти файл с таким именем по всем прописанным в переменной путям.

Но при не совсем корректном составлении списка путей в переменной PATH возможна ситуация, когда злоумышленник сможет разместить по одному из путей, указанных в PATH свой файл с таким же названием, как и легальное приложение. Но этот файл будет выполнен вместо легального приложения, так как путь к нему прописан в PATH раньше, чем путь к легальному приложению. Например, на скриншоте /usr/local/bin идет раньше, чем /usr/bin, поэтому если легальный файл лежит по второму пути, то злоумышленник может сохранить свой файл с таким же именем по первому и он будет выполнен вместо легального. Таким образом, злоумышленник имея доступ в каталоги прописанные в PATH может поместить свой выполнимый файл с тем же именем, и при выполнении, по сути, подменить легальный файл на свой. А учитывая, что файл могут пытаться запустить с правами суперпользователя злоумышленник в результате подмены может получить права root.

Заключение

В этой статье мы рассмотрели основные моменты настройки прав доступа. Я сознательно не рассматривал никакие “хакерские фокусы”, то есть практические примеры эксплуатации ошибок в данных настройках, так как этому будет полностью посвящена следующая статья. Но основные рекомендации по безопасности можно дать уже сейчас. Прежде всего, необходимо использовать принцип минимизации привилегий, то есть пользователям необходимо назначать только те права, которые необходимы им для работы. Недопустимо использование прав 777 на те приложения, запуск которых может привести к получению root-shell. Также недопустимо разрешение пользователям запуска любых команд под sudo, так как это равносильно получению прав root. Аналогично, SUID бит должен устанавливаться только на безопасные приложения, в противном случае есть риск получения пользователем прав root.

Вместо заключения хочу пригласить вас на бесплатные демоуроки по Linux от OTUS. Зарегистрироваться на уроки можно по ссылкам ниже:

Комментарии (7)


  1. T968
    30.09.2022 21:06
    +1

    Мне жаль, но слова

    owner, group, other,

    А вот буквы правильно - u, g, o.

    И сразу видно, кто читал доки, а кто слушал курсы. ))


  1. mihmig
    01.10.2022 13:03
    -2

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


    1. polearnik
      01.10.2022 13:14

      но это ведь логично . Нужна администраторская учетка на сервере которая позволяет манипулировать учетками пользователей. Кто должен удалить учетку уволившегося сотрудника? а сменить пароль забывшему ? а создать новую? иначе приходим к системам как на залоченных телефонах где шаг влево шаг вправо невозможен


    1. Oxyd
      03.10.2022 05:17

      Было бы удивительно если бы superuser не имел полных прав в системе. Поэтому и были придуманы sudo, doas и блокировка root аккаунта. sudo логгирует действия вызвавшего его пользователя.


  1. osipov_dv
    01.10.2022 16:08
    +1

    Разница между sudo -i и sudo -s не раскрыта... и почему-то про ключ -s вообще автор не знает, а только категорично про -i.


    1. Fafhrd
      01.10.2022 17:33
      +2

      ну хотя бы ереси типа sudo su не замечено


      1. osipov_dv
        01.10.2022 18:10
        +1

        ну sudo su - someuser имеет смысл. А вот указанный в статье sudo bash нет )