Как выполнить процесс, сохранив возможности, несмотря на отсутствие возможностей файловой системы?

Я хочу сделать систему пригодной для использования без setuid, возможностей файла "+p" и вообще без вещей, которые отключаются, когда я устанавливаю PR_SET_NO_NEW_PRIVS.

При таком подходе (init устанавливает PR_SET_NO_NEW_PRIVS и повышение возможностей на основе файловой системы больше невозможно) вы не можете «пополнить» свои возможности, и вам нужно только быть осторожным, чтобы не «разбрызгать» их.

Как execve выполнить какой-либо другой процесс, не "разбрызгивая" какие-либо предоставленные возможности (например, если файл новой программы - setcap =ei)? Просто «я доверяю этому новому процессу, как доверяю себе». Например, пользователю дана возможность (и пользователь хочет использовать ее в любой программе, которую он запускает)...

Могу ли я сделать всю файловую систему постоянной =ei? Я хочу, чтобы файловая система просто не мешала схеме, не могла предоставлять или отзывать возможности; контролировать все через родительские-> дочерние вещи.


person Vi.    schedule 31.01.2013    source источник
comment
Не могли бы вы прояснить момент, в своем заголовке вы написали, несмотря на отсутствующие возможности файла, в своем вопросе вы говорите, что хотите использовать эту функцию, и установите биты возможностей всего файла на ei. Эта функция присутствует или нет в вашей системе?   -  person Étienne    schedule 08.05.2013
comment
Означает, что возможности файловой системы не позволяют +i, например, для файлов, которые пользователь только что скомпилировал, но мы все же хотим, чтобы этот пользователь мог использовать эту возможность. Получение возможностей с помощью +i работает только как пересечение +i процесса (пользователя) и +i файловой системы. Без проверки файловой системы (без +p и без +i) я не могу запустить другой исполняемый файл, сохраняя уже имеющиеся у меня эффективные возможности. Это создало несоответствие (т.е. может загрузить динамическую библиотеку, которая будет использовать мои возможности, но эта библиотека не может создавать процессы без потери колпачков).   -  person Vi.    schedule 09.05.2013
comment
Так что это работает, но не так, как вы ожидали.   -  person ctrl-alt-delor    schedule 18.01.2018


Ответы (3)


Я не говорю, что рекомендую это для того, что вы делаете, но вот оно.

Извлечено из руководства. Были внесены некоторые изменения. Согласно ему: fork возможностей не меняет. И теперь в ядро ​​​​Linux 4.3 добавлен внешний набор, похоже, это то, что вы пытаетесь сделать.

   Ambient (since Linux 4.3):
          This is a set of capabilities that are preserved across an execve(2) of a program that is not privileged.  The ambient capability set obeys the invariant that no capability can ever
          be ambient if it is not both permitted and inheritable.

          The ambient capability set can be directly modified using
          prctl(2).  Ambient capabilities are automatically lowered if
          either of the corresponding permitted or inheritable
          capabilities is lowered.

          Executing a program that changes UID or GID due to the set-
          user-ID or set-group-ID bits or executing a program that has
          any file capabilities set will clear the ambient set.  Ambient
          capabilities are added to the permitted set and assigned to
          the effective set when execve(2) is called.

   A child created via fork(2) inherits copies of its parent's
   capability sets.  See below for a discussion of the treatment of
   capabilities during execve(2).

Transformation of capabilities during execve()
   During an execve(2), the kernel calculates the new capabilities of
   the process using the following algorithm:

       P'(ambient) = (file is privileged) ? 0 : P(ambient)

       P'(permitted) = (P(inheritable) & F(inheritable)) |
                       (F(permitted) & cap_bset) | P'(ambient)

       P'(effective) = F(effective) ? P'(permitted) : P'(ambient)

       P'(inheritable) = P(inheritable)    [i.e., unchanged]

   where:

       P         denotes the value of a thread capability set before the
                 execve(2)

       P'        denotes the value of a thread capability set after the
                 execve(2)

       F         denotes a file capability set

       cap_bset  is the value of the capability bounding set (described
                 below).

   A privileged file is one that has capabilities or has the set-user-ID
   or set-group-ID bit set.
person ctrl-alt-delor    schedule 04.06.2016
comment
Реализация возможности настройки окружения в моем инструменте dived. - person Vi.; 04.07.2016
comment
@vi ты можешь сказать это снова, используя полное предложение? - person ctrl-alt-delor; 04.07.2016
comment
Я искал здесь и там, чтобы найти инструмент, позволяющий экспериментировать с внешними кабелями, но не нашел ни одного (особенно в Debian Stable). Поэтому я добавил еще один вариант для этого в свое погружение с инструментами. Чтобы помочь другим пользователям, которые хотят поиграть с окружающими возможностями, не дожидаясь, пока появятся соответствующие инструменты и библиотеки, я решил опубликовать ссылку где-нибудь по теме. И этот ответ, который просветил меня об этой функции, кажется, что это связанное место. - person Vi.; 04.07.2016

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

During an execve(2), the kernel calculates the new capabilities of the process
using the following algorithm:

P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & cap_bset)

P'(effective) = F(effective) ? P'(permitted) : 0 

P'(inheritable) = P(inheritable)    [i.e., unchanged]

where:

P        denotes the value of a thread capability set before the execve(2)
P'       denotes the value of a capability set after the execve(2)
F        denotes a file capability set
cap_bset is the value of the capability bounding set 

Если файл, который вы хотите выполнить, не имеет установленного бита fP или если его биты fI не установлены, ваш процесс не будет иметь разрешенных и, следовательно, эффективных возможностей.

Разрешение всей файловой системы и битов наследования было бы технически возможно, но это не имело бы большого смысла, поскольку сильно снизило бы безопасность системы (изменить: и, как вы упомянули, это не будет работать для новых исполняемых файлов).

Вы действительно можете дать пользователю некоторые возможности с помощью pam_cap, но вы не можете позволить ему выполнять какой-либо файл, который он только что скомпилировал с его помощью. Возможности предназначены для предоставления возможностей программам, а не пользователям, вы можете прочитать в Бумага Халлина:

Ключевым моментом является наблюдение, что привилегиями пользуются программы, а не люди. То есть все, что делается на компьютере, осуществляется через агентов — программы, и только если эти программы знают, что делать с привилегиями, им можно доверять.

См. также проект POSIX 1003.1e, определяющий возможности POSIX, стр. 310. :

Также нецелесообразно устанавливать для цепочки процессов (последовательности программ внутри одного процесса) набор возможностей, который остается фиксированным и активным на протяжении всего жизненного цикла этой цепочки. [...] Это применение принципа наименьших привилегий, и оно в равной степени относится как к пользователям, так и к процессам.

Кто-то попросил представить, что вы хотите сделать в качестве функции в этот список рассылки ядра Linux недавно (декабрь 2012 г.), и есть несколько очень интересных ответов. Некоторые люди утверждают, что удаление файловых возможностей в правилах наследования через exec вызовет некоторые проблемы с безопасностью, и что возможности не предназначены для такой функции, хотя не дается никакого объяснения, какую проблему безопасности это вызовет:/

В настоящее время единственный способ сделать это — изменить способ наследования возможностей в ядре Linux (2 файла для изменения, я успешно протестировал его на ядре 3.7), но неясно, защищено ли это или нет, как указано выше.

В старых ядрах (до 2.6.33) была возможность компилировать без файловых возможностей (CONFIG_SECURITY_FILE_CAPABILITIES), но я сомневаюсь, что работа с таким старым ядром подойдет вам.

person Étienne    schedule 07.05.2013
comment
Представьте, что я каким-то образом запускаю программу (оболочку), у которой есть эффективное разрешение. Я могу заставить его динамически загружать библиотеки и выполнять любой код. Но было бы удобно также включить загрузку чего-то помимо динамических библиотек (просто обычные программы). С PR_SET_NO_NEW_PRIVS вы не можете получить новые привилегии. Но мне нужен инструмент для предотвращения потери уже существующих привилегий. - person Vi.; 08.05.2013
comment
Setting the whole file system effective bit -> Или установить для /lib/ld-linux*. strongly reduce the security on the system -› Не должен, если вы контролируете процессы, получающие +i. Он смещает предоставление привилегий программам на предоставление привилегий пользователям (т.е. пользователь может скомпилировать и запустить любую программу, использующую эту привилегию). - person Vi.; 08.05.2013
comment
Вы не можете предоставить возможности пользователю напрямую, можете ли вы подробнее описать, чего вы пытаетесь достичь? Почему бы вам не установить права доступа к файлам из вашей оболочки, а затем разрешить запускать эту оболочку только пользователям, которым вы доверяете? Вы пытаетесь написать программу? взломать ядро? - person Étienne; 08.05.2013
comment
установить возможности файла из вашей оболочки -> Требуется CAP_SETFCAP. - person Vi.; 09.05.2013
comment
Пример: разрешить пользователю только CAP_NET_BIND_SERVICE для любых программ (включая те, которые он только что скомпилировал). CAP_NET_BIND_SERVICE+i для этого пользователя можно установить с помощью PAM. Хакерский обходной путь включает установку + i для /lib/ld-linux.so.2. - person Vi.; 09.05.2013
comment
Пример 2: Полупривилегированный (например, с CAP_NET_RAW) процесс с плагинами (в виде динамических библиотек), и он может автоматически обновлять свои плагины. Внезапно один из плагинов подвергся рефакторингу и теперь порождает отдельный исполняемый файл, чтобы что-то делать (также требующий CAP_NET_RAW). Но приложение не может установить CAP_NET_RAW+i для этого нового исполняемого файла, а также не может вызывать его с сохранением действующего и унаследованного CAP_NET_RAW... - person Vi.; 09.05.2013
comment
Я расширил свой ответ, так как неправильно понял ваш вопрос, когда впервые ответил. Я думал, вы имели в виду отсутствующие возможности файловой системы, как в файловых системах, таких как NFS, которые не поддерживают расширенные атрибуты и не имеют никаких возможностей файловой системы. - person Étienne; 16.05.2013
comment
dropping file capabilities in inheritance rules across exec would introduce some security problems -> Конечно, если исполняемая программа этого не ожидает (т.е. выполняет ненадежные вещи). Такой exec-preserving-all-access должен быть явно запрошен вызывающей стороной exec и рассматриваться как загрузка библиотеки и выполнение функции из нее с точки зрения безопасности. - person Vi.; 16.05.2013
comment
Но это то, что вы хотите сделать, не так ли? - person Étienne; 16.05.2013
comment
Да. Я не хочу, чтобы execve менял свое поведение по умолчанию, но чтобы предоставить что-то вроде trusted_execve (например, prctl, затем execve), которое никогда не отбрасывает никаких привилегий/возможностей. Таким образом, я буду уверен, что смогу выделить вещи не только в библиотеку, но и в отдельный исполняемый файл (без возни с дополнительными вещами, такими как требование, чтобы кто-то настроил +i для этого нового исполняемого файла). - person Vi.; 16.05.2013
comment
На данный момент это невозможно, прочитайте обсуждение в списке рассылки ядра, на которое я дал ссылку, они называют trusted_execve SECURE_CAP_INHERITANCE. - person Étienne; 17.05.2013
comment
Этот абзац «Если файл, который вы хотите выполнить, не имеет установленного бита fE или его биты fI не установлены, ваш процесс не будет иметь разрешенных и, следовательно, эффективных возможностей». это неверно. - person ctrl-alt-delor; 01.09.2016
comment
Спасибо, я изменил предложение и заменил fE на fP. Намерение состояло в том, чтобы просто перефразировать первое из 3 уравнений. - person Étienne; 04.09.2016

Я думаю (мое понимание), что лучший способ использовать возможности:

  • For programs that need capabilities and are trusted including trusted not to leak capabilities: e.g. the packet sniffing part of wire-shark, a web server that needs to listen on port 80.
    • new programs, capabilities aware: set permitted.
    • устаревшие программы, не осведомленные о возможностях: установите разрешенные и эффективные
  • For programs that will leak capabilities, and have code that could (sometimes) use a capability: set inherited
    • e.g. for chmod set inherit CAP_FOWNER, if user needs super powers (those normally held by root), then they need to use setpriv (or equivalent, this could be rolled into sudo), else it works in unprivileged mode.
  • Когда процессу необходимо разветвиться и поделиться некоторыми возможностями, тогда и только тогда используйте ambient. Вероятно, тот же исполняемый файл; если бы это был другой, то этот новый разрешил бы или унаследовал набор в файле. [Редактировать: я только что понял, что вам не нужен эмбиент, если вы не выполняете exec. Если я придумаю вариант использования эмбиента в хорошо настроенной системе, я добавлю его сюда. Ambient можно использовать в качестве переходного механизма, когда унаследованное не установлено для файлов, которые могут его использовать.]

Использование окружающего:

  • В системе, где файлы не имеют правильных возможностей. (переходная техника).
  • Для сценариев оболочки, у которых не может быть возможностей (поскольку они не могут иметь setuid), за исключением систем, которые исправили, а затем разрешили setuid для сценариев.
  • Добавьте больше здесь.
person ctrl-alt-delor    schedule 01.09.2016
comment
Возможности окружения можно использовать, например, чтобы просто отменить порты меньше 1024 только для корневого правила. Или включить код настройки сети в сценарий оболочки без каких-либо настроек в /bin/sh. Или когда файловая система тупая и не имеет расширенных атрибутов. - person Vi.; 02.09.2016
comment
@Vi Я сделал то, что ты сказал. И кстати s/[?]/g/. - person ctrl-alt-delor; 02.09.2016
comment
@Vi, у вас есть хорошая мысль, которую я не видел: эмбиент для запуска сценариев оболочки. Что касается вашего первого пункта, если вам нужно прослушивать порты ‹ 1024, установите соответствующий унаследованный бит в исполняемом файле. sudo/setpriv или когда он когда-либо вызывается, может по умолчанию грабить, какие унаследованные биты установлены, а также устанавливать их, чтобы активировать их (для сценария используйте окружающий). - person ctrl-alt-delor; 02.09.2016