В улучшить
бит разрешение говорит Linux запускать программу с эффективным идентификатором пользователя владельца вместо исполнителя:
> cat setuid-test.c
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv) {
printf("%d", geteuid());
return 0;
}
> gcc -o setuid-test setuid-test.c
> ./setuid-test
1000
> sudo chown nobody ./setuid-test; sudo chmod +s ./setuid-test
> ./setuid-test
65534
Однако, это касается только исполняемые файлы; скрипты игнорировать бит setuid:
> cat setuid-test2
#!/bin/bash
id -u
> ./setuid-test2
1000
> sudo chown nobody ./setuid-test2; sudo chmod +s ./setuid-test2
> ./setuid-test2
1000
Википедия говорит:
В связи с увеличением вероятности возникновения уязвимостей, многие операционные системы игнорируют атрибут setuid, когда применяется для исполняемых скриптов.
Если предположить, что я'м готов принять эти риски, есть ли способ, чтобы сообщить Linux лечить бит setuid же на скриптах, как это делает на исполняемые файлы?
Если нет, есть ли общее решение для этой проблемы? Мое текущее решение, чтобы добавить запись пользователям использовать sudo?
чтобы все
, чтобы запустить данный скрипт как пользователь я хочу, чтобы запустить его как, с NOPASSWD, чтобы избежать ввода пароля. Основные минусы в том, что это необходимо для записи, а пользователям использовать sudo?каждый раз, когда я хочу сделать это, а также необходимость для абонента
судо некоторые-сценарийвместо просто
какой-сценария`
#!
линии). На сост.в Unix.часто задаваемые вопросы объясняет проблемы безопасности с setuid для сценариев оболочки. Эти проблемы бывают двух видов: стерильные и раковины, а я пойду в более подробно ниже.
Если вы Don'т заботятся о безопасности и хотите разрешить setuid для скриптов под Linux, вы'll необходимо пропатчить ядро. По состоянию на 3.х ядер, я думаю, вы должны добавить вызов [install_exec_creds
](http://lxr.linux.no/linux+В3.18/ДФ/ОТВ.в C#L1187) в [load_script
](http://lxr.linux.no/linux+В3.18/ДФ/binfmt_script.функции C#л90), перед вызовом `open_exec, но я не'т тестирование. Есть состязания, присущие слову притон (#!
) обычно реализуется:
#!
. #!
. Позвольте'ы сказать дескриптор файла для исполняемого файла 3. в/dev/ФД/3
списке аргументов (как и argv1`), и выполняет переводчик.
Свен Mascheck'ы подробно страница содержит много информации на притон по юниксов, в том числе [setuid для поддержки](http://www.in-ulm.de/~mascheck/различных/притон/#с setuid). Позвольте'ы предполагаем, что вы'ве удалось сделать вашу программу запускать от имени root, либо потому, что ваша ОС поддерживает функцию setuid притон или потому, что вы'вэ используется бинарная оболочка (например, судо
). Ты открыл дыру в безопасности? Возможно. Речь здесь идет не о интерпретировано против скомпилированных программ. Вопрос, Является ли ваш системы спокойно ведет себя, если она выполняется с привилегиями.
/Либ/ЛД.так
), который загружает динамических библиотек, необходимых для работы программы. На многих Unix-подобных системах, вы можете настроить путь поиска для динамических библиотек с помощью окружения (переменная LD_LIBRARY_PATH
- это общее название для переменной окружения), и даже загружать дополнительные библиотеки В всех запускаемых программах (LD_PRELOAD
). Призывателя программы может выполнить произвольный код в программу'ы контекста, поместив специально созданный файл libc.так
в $переменная LD_LIBRARY_PATH
(среди других тактик). Всех вменяемых системах игнорировать переменные `LD_* в режиме setuid программы. путь
, если
, и многое другое, у Invoker скрипт имеет много возможностей, чтобы выполнить произвольный код в shell-скрипты'ы контексте. Некоторые снаряды набор этих переменных в значения по умолчанию, если они обнаруживают, что скрипт был вызван с правами, но я не'т знаю, что существует какой-либо конкретной реализации, что я бы доверил. #!/УСР/бин/suidperl -мас
вместо #!/usr/Бен/Perl с -МАС, но на большинстве современных систем,
#!/usr/Бен/на Perl -мас является достаточным.
Обратите внимание, что использование бинарная фантик не в себе, чтобы предотвратить эти проблемы. На самом деле, это может сделать ситуацию хуже, потому что это может помешать вашей среды выполнения обнаруживать, что он вызывается с правами и в обход его выполнения конфигурирования.
Родной бинарных обертке можете сделать скрипт просмотра, если фантик санирует окружающей среды. Скрипт должен заботиться, чтобы не сделать слишком много допущений (например, о текущем каталоге), но к этому идет. Вы можете использовать sudo для этого при условии, что она's была создана для очистки окружающей среды. Переменные черных списков может привести к ошибкам, поэтому всегда белый. С sudo, убедитесь, что опция env_reset
включен, что setenv
, и что env_file
и `env_keep содержат только безобидные переменных. ТЛ ДР:
env_reset
).
¹ <суб>это обсуждение относится в равной степени, если заменить “функцию setgid” за “дополнительное”; они оба игнорировали ядра Linux на Скрипты</суб> Одним из способов решения этой проблемы является вызов скрипта из программы, которые могут использовать setuid-бит. его что-то вроде sudo. Например, вот как вы бы сделать это в программе c:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
setuid( 0 ); // you can set it at run time also
system( "/home/pubuntu/setuid-test2.sh" );
return 0;
}
Сохраните его как дополнительное-test2 на.С. компиляции Теперь с setuid на этой бинарной программе:
su - nobody
[enter password]
chown nobody:nobody a.out
chmod 4755 a.out
Теперь, вы должны быть в состоянии запустить его, и вы'll увидеть ваш скрипт выполняется с никто разрешения. Но здесь также нужно закодировать путь к скрипту или сдать его в командной строке аргументов выше exe-файла.
Я префикса несколько скриптов, которые находятся в этой лодке таким образом:
#!/bin/sh
[ "root" != "$USER" ] && exec sudo $0 "$@"
Обратите внимание, что это не использовать улучшить
, а просто выполняет текущий файл с судо
.
Если вы хотите избежать вызова судо some_script
вы можете просто сделать:
#!/ust/bin/env sh
sudo /usr/local/scripts/your_script
Программы setuid необходимо с особой осторожностью, так как они выполняются с правами root и пользователи имеют большой контроль над ними. Они должны вменяемо-проверяйте все. Вы не можете сделать это с помощью скриптов, потому что:
СЭД
, неужели
, и т. д. должны быть проверены такжеОбратите внимание, что судо
предоставляет некоторые вменяемость-проверки, но это вовсе'т достаточно — проверить каждую строку в свой код.
Как последнее примечание: рекомендуется использовать возможности. Они позволяют придать процессу в качестве особой привилегии пользователей, которые обычно требуют привилегий суперпользователя. Однако, например, в то время как "пинг" должен манипулировать сети, для этого не нужно иметь доступ к файлам. Я'м не уверен, однако если они передаются по наследству.
Вы можете создать псевдоним для судо + имя скрипта. Конечно, это еще больше работы, чтобы настроить, поскольку тогда вам придется слишком настройки псевдоним, но это избавит вас от необходимости вводить судо.
Но если вы Don'т ум ужасные угрозы безопасности, использовать setuid для раковины в качестве переводчика для сценария. Дон'т знаете ли, что'll будет работать для вас, но я предполагаю, что это может.
Позвольте мне заявить, что я советую на самом деле делаете это, хотя. Я'м просто упомянуть его в образовательных целях ;-)
супер [ -Р reqpath] команда [ аргументы ]
Супер позволяет определенным пользователям выполнять скрипты (или других команд), как если бы они были корень; или он может определить UID, GID и/или дополнительных групп на командной основе перед выполнением команды. Он предназначен для надежной альтернативой, чтобы сделать скрипты с setuid корень. Супер также позволяет обычным пользователям подачей команд для исполнения другим; они выполняются с UID, GID и групп пользователей, предлагающих команды.
Супер консультирует `супер.вкладка'' файл, чтобы увидеть, если пользователь может выполнить запрашиваемую команду. Если разрешение предоставлено, супер будет старпома ПГМ [ аргументы ], где ПГМ-это программа, которая связана с этой командой. (Корень допускается исполнение по умолчанию, но все равно может быть отказано, если правило исключает корень. Обычные пользователи могут запретить выполнение по умолчанию.)
Если команда является символической ссылкой (или жесткая ссылка, тоже) к программе супер, затем введите команду % аргументы вместо того, чтобы вводить % супер команду параметры (команды не должны быть супер, или супер не признать, что она'ы, вызываемого по ссылке.)
http://www.ucolick.org/ - с/РУП/супер/ридми
http://manpages.ubuntu.com/manpages/utopic/en/man1/super.1.html
Если по каким-то причинам судо
недоступна, вы можете писать тонким скрипт-обертку на C:
#include <unistd.h>
int main() {
setuid(0);
execle("/bin/bash","bash","/full/path/to/script",(char*) NULL,(char*) NULL);
}
И после компиляции установить его как дополнительное
с командой chmod 4511 wrapper_script
.
Это похоже на очередную запостил ответ, но запускает скрипт с чистой экологией и явно использует /Бен/Баш вместо раковины называют
системы (), а так закрывает некоторые потенциальные дыры в безопасности.
Обратите внимание, что это полностью отбрасывает окружающую среду. Если вы хотите использовать некоторые переменные среды без открытия уязвимости, вам просто нужно использовать sudo
.
Очевидно, вы хотите убедиться, что сам скрипт только для записи корня.
Я сначала нашел этот вопрос, убежден на все ответы, здесь намного лучше, что также позволяет полностью скрыть ваш bash-скрипт, если вы так склонны!
Она должна быть самодостаточной.
#include <string>
#include <unistd.h>
template <typename T, typename U>
T &replace (
T &str,
const U &from,
const U &to)
{
size_t pos;
size_t offset = 0;
const size_t increment = to.size();
while ((pos = str.find(from, offset)) != T::npos)
{
str.replace(pos, from.size(), to);
offset = pos + increment;
}
return str;
}
int main(int argc, char* argv[])
{
// Set UUID to root
setuid(0);
std::string script =
R"(#!/bin/bash
whoami
echo $1
)";
// Escape single quotes.
replace(script, std::string("'"), std::string("'\"'\"'"));
std::string command;
command = command + "bash -c '" + script + "'";
// Append the command line arguments.
for (int a = 0; a < argc; ++a)
{
command = command + " " + argv[a];
}
return system(command.c_str());
}
Затем вы бежите
g++ embedded.cpp -o embedded
sudo chown root embedded
sudo chmod u+s embedded