Linux игнорирует бит setuid¹ во всех интерпретируемых исполняемых файлах (т.е. исполняемых файлах, начинающихся со #!строки). Comp.unix.questions FAQ объясняет проблемы безопасности с УИП сценариями оболочки. Эти проблемы бывают двух видов: связанные с Шебангом и связанные с оболочкой; Я вхожу в более подробную информацию ниже.
Если вы не заботитесь о безопасности и хотите разрешить сценарии setuid, в Linux вам нужно будет исправить ядро. Что касается ядер 3.x, я думаю, вам нужно добавить вызов install_exec_credsв load_scriptфункцию перед вызовом open_exec, но я не проверял.
Сетуид Шебанг
Существует способ состязания, свойственный тому, как #!обычно реализуется shebang ( ):
- Ядро открывает исполняемый файл и находит, что оно начинается с
#!.
- Ядро закрывает исполняемый файл и открывает вместо него интерпретатор.
- Ядро вставляет путь к сценарию в список аргументов (as
argv[1]) и выполняет интерпретатор.
Если в этой реализации разрешены сценарии setuid, злоумышленник может вызвать произвольный сценарий, создав символическую ссылку на существующий сценарий setuid, выполнив ее и организовав изменение ссылки после того, как ядро выполнит шаг 1 и до того, как интерпретатор дойдет до открывая свой первый аргумент. По этой причине большинство юнитов игнорируют бит setuid при обнаружении шебанга.
Одним из способов защиты этой реализации было бы то, чтобы ядро блокировало файл сценария до тех пор, пока интерпретатор не откроет его (обратите внимание, что это должно предотвратить не только удаление или перезапись файла, но также переименование любого каталога в пути). Но Unix-системы, как правило, уклоняются от обязательных блокировок, а символические ссылки делают правильную блокировку особенно трудной и агрессивной. Я не думаю, что кто-то так делает.
Несколько систем UNIX ( в основном OpenBSD, NetBSD и Mac OS X, все из которых требуют настройки ядра должны быть включены) осуществлять безопасное Setuid хижины с помощью дополнительной функции: путь относится к файлу уже открыт дескриптор файла N (так открытие является примерно эквивалентно ). Многие системы Unix (включая Linux) имеют, но не имеют сценариев setuid./dev/fd/N/dev/fd/Ndup(N)/dev/fd
- Ядро открывает исполняемый файл и находит, что оно начинается с
#!. Допустим, дескриптор файла для исполняемого файла равен 3.
- Ядро открывает интерпретатор.
- Ядро вставляет
/dev/fd/3список аргументов (как argv[1]) и выполняет интерпретатор.
Страница Шебанга Свена Машика содержит много информации о Шебанге в разных отделениях, включая поддержку setuid .
Сетуид переводчики
Предположим, вам удалось запустить программу от имени root, либо потому, что ваша ОС поддерживает setuid shebang, либо потому, что вы использовали встроенную двоичную оболочку (например, sudo). Вы открыли дыру в безопасности? Может быть . Проблема здесь не в интерпретируемых, а в скомпилированных программах. Вопрос в том, будет ли ваша среда выполнения работать безопасно, если она выполняется с привилегиями.
Любой динамически связанный собственный двоичный исполняемый файл интерпретируется динамическим загрузчиком (например /lib/ld.so), который загружает динамические библиотеки, необходимые для программы. На многих устройствах вы можете настроить путь поиска динамических библиотек в среде ( LD_LIBRARY_PATHэто общее имя переменной среды) и даже загрузить дополнительные библиотеки во все исполняемые двоичные файлы ( LD_PRELOAD). Вызывающий программы может выполнить произвольный код в контексте этой программы путем размещения специально созданный libc.soв $LD_LIBRARY_PATH(среди других тактик). Все вменяемые системы игнорируют LD_*переменные в исполняемых файлах setuid.
В оболочках, таких как sh, csh и производные, переменные среды автоматически становятся параметрами оболочки. Благодаря таким параметрам, как PATH, IFS, и многое другое, запустившего сценарий имеет много возможностей для выполнения произвольного кода в контексте сценариев оболочки игровая. Некоторые оболочки устанавливают эти переменные в разумные значения по умолчанию, если обнаруживают, что скрипт был вызван с привилегиями, но я не знаю, есть ли какая-то конкретная реализация, которой я бы доверял.
Большинство сред выполнения (будь то нативное, байт-код или интерпретируемое) имеют сходные функции. Мало кто принимает особые меры предосторожности в исполняемых файлах setuid, хотя те, которые запускают нативный код, часто не делают ничего более хитрого, чем динамическое связывание (которое требует предосторожности).
Perl является заметным исключением. Он явно поддерживает сценарии setuid безопасным способом. Фактически, ваш скрипт может запускать setuid, даже если ваша ОС игнорирует бит setuid в скриптах. Это связано с тем, что perl поставляется с корневым помощником setuid, который выполняет необходимые проверки и повторно вызывает интерпретатор для нужных сценариев с желаемыми привилегиями. Это объясняется в руководстве perlsec . Раньше было так, что #!/usr/bin/suidperl -wTвместо этого #!/usr/bin/perl -wT, но на большинстве современных систем, #!/usr/bin/perl -wTдостаточно было бы использовать perl-скрипты setuid .
Обратите внимание, что использование встроенной двоичной оболочки ничего не делает само по себе, чтобы предотвратить эти проблемы . На самом деле, это может сделать ситуацию еще хуже , потому что это может предотвратить среды выполнения от обнаружения того, что она вызывается с правами и в обход его выполнения настраиваемость.
Собственная двоичная оболочка может сделать сценарий оболочки безопасным, если оболочка дезинфицирует среду . Сценарий должен позаботиться о том, чтобы не делать слишком много предположений (например, о текущем каталоге), но это так. Вы можете использовать sudo для этого при условии, что он настроен для очистки среды. Переменные в черном списке подвержены ошибкам, поэтому всегда белый список. С помощью sudo убедитесь, что env_resetопция включена, setenvвыключена env_fileи env_keepсодержит только безобидные переменные.
TL, DR:
- Сетуид Шебанг небезопасен, но обычно игнорируется.
- Если вы запускаете программу с привилегиями (либо через sudo, либо через setuid), пишете собственный код или perl, либо запускаете программу с оболочкой, которая дезинфицирует среду (например, sudo с
env_resetопцией).
Discussion Это обсуждение в равной степени применимо, если вы замените «setgid» на «setuid»; они оба игнорируются ядром Linux в сценариях