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/N
dup(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 в сценариях
suidperl
материал был объявлен устаревшим и отмечен для удаления в течение многих лет (но, тем не менее, сохраняется)suidperl
был удален с perl 5.11 (стабильная версия 5.12): perl5110delta:> "suidperl" был удален. Он использовался для обеспечения механизма эмуляции битов разрешений setuid в системах, которые не поддерживают его должным образом. perl5120delta:> "suidperl" больше не является частью Perl. Он использовался для обеспечения механизма эмуляции битов разрешений setuid в системах, которые не поддерживают его должным образом.Одним из способов решения этой проблемы является вызов сценария оболочки из программы, которая может использовать бит setuid.
это что-то вроде sudo. Например, вот как вы могли бы сделать это в программе на C:
Сохраните его как setuid-test2.c.
compile
Теперь сделайте setuid для этой двоичной программы:
Теперь вы должны быть в состоянии запустить его, и вы увидите, что ваш скрипт выполняется без прав доступа.
Но и здесь вам нужно либо жестко закодировать путь к скрипту, либо передать его как аргумент командной строки вышеупомянутому exe.
источник
PATH
иLD_LIBRARY_PATH
очевидные векторы. Некоторые оболочки выполняют$ENV
или$BASHENV
или~/.zshenv
даже прежде , чем они начнут выполнение сценария собственно, поэтому вы не можете защитить от них вообще из сценария. Единственный безопасный способ вызвать скрипт с привилегиями - это очистить среду . Судо знает, как сделать это безопасно. Так что не пишите свою собственную обертку, используйте sudo .LD_LIBRARY_PATH
среди прочего, когда сталкивается с битом setuid.system
может оказаться более простым (и более эффективным) использование одного изexec
семейств - скорее всегоexecve
. Таким образом, вы не создаете новый процесс и не запускаете оболочку, и вы можете пересылать аргументы (при условии, что ваш привилегированный скрипт может безопасно обрабатывать аргументы).Я префикс нескольких сценариев, которые находятся в этой лодке, таким образом:
Обратите внимание, что это не использует,
setuid
а просто выполняет текущий файл сsudo
.источник
sudo
подсказку. (Для меня весь смысл setuid в том, что все должно запускаться с правами root без необходимости sudo.)Если вы хотите избежать звонка,
sudo some_script
вы можете просто сделать:Программы SETUID должны разрабатываться с особой тщательностью, так как они работают с привилегиями root и пользователи имеют над ними большой контроль. Им нужно здравомыслие - все проверить. Вы не можете сделать это с помощью сценариев, потому что:
sed
,awk
И т.д. должны быть проверены , а такжеОбратите внимание, что это
sudo
обеспечивает некоторую проверку работоспособности, но этого недостаточно - проверяйте каждую строку в своем собственном коде.И последнее замечание: подумайте об использовании возможностей. Они позволяют вам дать процессу, работающему от имени пользователя, специальные привилегии, которые обычно требуют привилегий суперпользователя. Однако, например, хотя
ping
нужно манипулировать сетью, ему не нужно иметь доступ к файлам. Я не уверен, однако, если они унаследованы.источник
/ust/bin/env
должно быть/usr/bin/env
.Вы можете создать псевдоним для sudo + имя скрипта. Конечно, это еще большая работа по настройке, так как тогда вам также нужно настроить псевдоним, но это избавляет вас от необходимости вводить sudo.
Но если вы не возражаете против ужасных угроз безопасности, используйте оболочку setuid в качестве интерпретатора для сценария оболочки. Не знаю, сработает ли это для вас, но я думаю, что может.
Позвольте мне заявить, что я советую не делать этого, хотя. Я просто упоминаю это в образовательных целях ;-)
источник
rm -rf /
(и другие команды из серии НЕ ДЕЛАЙТЕ ЭТОГО НА ДОМУ ).команда супер [-r reqpath] [аргументы]
Super позволяет указанным пользователям выполнять сценарии (или другие команды), как если бы они были пользователем root; или он может установить uid, gid и / или дополнительные группы для каждой команды перед выполнением команды. Он предназначен для безопасной альтернативы созданию скриптов setuid root. Super также позволяет обычным пользователям предоставлять команды для выполнения другими; они выполняются с uid, gid и группами пользователей, предлагающих команду.
Super просматривает файл `` super.tab '', чтобы узнать, разрешено ли пользователю выполнять запрошенную команду. Если разрешение предоставлено, super выполнит pgm [args], где pgm - программа, связанная с этой командой. (Root разрешено выполнение по умолчанию, но все еще может быть отказано, если правило исключает root. Обычные пользователи по умолчанию запрещены к выполнению.)
Если команда является символической ссылкой (или жесткой ссылкой тоже) на супер программу, то ввод% command args эквивалентен вводу% super command args (команда не должна быть супер, иначе супер не распознает, что она вызывается через ссылка.)
http://www.ucolick.org/~will/RUE/super/README
http://manpages.ubuntu.com/manpages/utopic/en/man1/super.1.html
источник
Если по какой-либо причине
sudo
это невозможно, вы можете написать тонкий скрипт-обертку на C:И как только вы скомпилировать его установить его как
setuid
сchmod 4511 wrapper_script
.Это похоже на другой опубликованный ответ, но запускает сценарий с чистой средой и явно использует
/bin/bash
вместо вызываемой оболочки оболочкуsystem()
, что закрывает некоторые потенциальные дыры в безопасности.Обратите внимание, что это полностью отбрасывает окружающую среду. Если вы хотите использовать некоторые переменные окружения, не открывая уязвимости, вам действительно нужно их использовать
sudo
.Очевидно, вы хотите убедиться, что сам сценарий доступен для записи только пользователю root.
источник
Сначала я обнаружил, что этот вопрос, не будучи убежденным во всех ответах, вот гораздо лучший, который также позволяет вам полностью запутать ваш bash-скрипт, если вы так склонны!
Это должно быть само за себя.
Тогда ты бежишь
источник