Это безопасная оболочка suid /ability для скриптов (Python)? - PullRequest
2 голосов
/ 11 февраля 2012

(Примечание: я имею в виду Linux, но проблема может возникнуть на других платформах.)

Проблема: Linux не подходит для #!сценариев и не активирует на них «возможности Linux».

Почему у нас возникла эта проблема? Поскольку во время настройки интерпретатора ядра для запуска сценария злоумышленник мог заменить этот файл.Как?Файл сценария, которому ранее доверяли suid /ability, может находиться в каталоге, которым он управляет (например, может удалить не принадлежащий ему доверенный файл или файл на самом деле является символической ссылкой, которой он владеет).

Правильное решение: заставляет ядро ​​разрешать сценарии suid / cap, если: a) ясно, что вызывающая программа не имеет власти над файлом сценария - или, как это делают некоторые другие операционные системы, b) передает сценарий как /dev / fd / x, ссылаясь на изначально открытый доверенный файл ядра.

Ответ Я ищу: для ядер, которые не могут этого сделать (все Linux), мне нужнобезопасное решение «сейчас».

Что я имею в виду?Бинарная оболочка, которая делает то, что не делает ядро, безопасным способом.

Я бы хотел

  1. услышать от установленных оболочек для (Python) скриптов, которые передают возможности Linux ивозможно suid из файла сценария для интерпретатора, чтобы сделать их эффективными.
  2. получить комментарии к моей оболочке, предложенной ниже

Проблемы с sudo : sudo не являетсяхорошая оболочка, потому что она не помогает ядру не поддаваться только что объясненной ловушке «скрипт получил замену» (так говорит «man sudo» в caveats).


Предлагаемая оболочка

  • на самом деле, я хочу небольшую программу, которая генерирует командную строку оболочки
    • , например: sudo suid_capability_wrapper ./script.py
    • script.py уже имеет бит suid инабор возможностей (без функции, просто информация)
  • генератор suid_capability_wrapper
    • генерирует исходный код C (?) и компилирует
    • компилирует вывод в: default:basename script.py .py или аргумент -o
    • установить владельца оболочки, группу, suid, как script.py
    • установить разрешенные возможности, такие как script.py, игнорировать наследуемые и эффективные ограничения
    • предупреждает, если у интерпретатора (например, / usr / bin / python) нет соответствующих заглавных букв в его наследуемом наборе (это системное ограничение: в противном случае невозможно передать capabilites без suid-root)
  • сгенерированный код выполняет:
    • проверка, открыты ли дескрипторы файлов 0, 1 и 2, в противном случае прервите (возможно, добавьте больше проверок для слишком сумасшедших условий среды)
    • если скомпилированный целевой скрипт скомпилирован с относительным путем, определите местоположение себя с помощью / proc / self / exe
    • , чтобы объединить собственный путь с относительным путем к сценарию, чтобы найти его
    • проверить, есливладелец целевых скриптов, группа, права доступа, прописные буквы, suid по-прежнему похожи на оригинальные (скомпилированные) [это единственная необязательная проверка безопасности, которую я хочу включить: в противном случае я доверяю этому скрипту]
    • установить набор унаследованных возможностей равным набору разрешенных возможностей
    • execve () интерпретатор, аналогичный тому, как это делает ядро, но использует известный нам путь к скрипту и среду, которую мы получили (скриптдолжен заботиться об окружающей среде)

Может быть напечатано несколько заметок и предупреждений suid_capability_wrapper, чтобы информировать пользователя о:

  • убедитесь, чтоникто не может манипулировать сценарием (например, доступным для записи в мире)
  • имейте в виду, что suid /abilities происходят из оболочки, ничто не заботится о монтировании suid / xattr для файла сценария
  • execve () ed, отсюда он получит грязную среду
  • , а также пропустит через него остальную стандартную среду процесса, которая ... ... ... (прочитайте man-страницыдля запуска exec)
  • используйте #! / usr / bin / python-E для иммунизации интерпретатора python от переменных окружения
  • самостоятельно очистите среду в скрипте или учтите, что существует много кода, который вы запускаете как побочный эффект, который заботится о некоторых из этих переменных

1 Ответ

0 голосов
/ 11 февраля 2012

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

Нужно сделать три вещи:

  • Запустить интерпретатор Python (из доверенного пути, взлома chroot-джейлов и т. Д.). Я предлагаю статически связывать libpython и использовать для этого CPython API, но решать вам.
  • Откройте файл сценария FD и атомарно проверьте, что он является suid и принадлежит root. Не допускайте изменения файла между проверкой и выполнением - будьте осторожны.
  • Скажите CPython выполнить скрипт из FD, который вы открыли ранее.

Это даст вам двоичный файл, который будет выполнять все скрипты, принадлежащие корню и suid только под Python . Вам нужна только одна такая программа, а не одна на скрипт. Это ваш "suidpythonrunner".

Как вы и предполагали, вы должны очистить среду перед запуском Python. Ядро позаботится о LD_LIBRARY_PATH, но PYTHONPATH может быть смертельно опасным.

...