Вызов script из root-программы setuid root - script не запускается с правами root
Мне нужно запустить bash script как root (без пароля sudo или su v жизнеспособно), и поскольку вы не можете установить script в Linux, я подумал о том, чтобы вызвать его из исполняемого файла и сделать его setuid:
$ cat wrapper.c
int main(void)
{
system("/bin/bash ./should_run_as_root.sh");
}
$ gcc -o wrapper wrapper.c
$ sudo chown root wrapper
$ sudo chmod ug+s wrapper
$ ll wrapper
-rwsr-sr-x 1 root users 6667 2009-02-17 11:11 wrapper
$
Это работает - как при правильном выполнении script, но script работает как пользователь, который выполняет "./wrapper".
Почему? И как правильно это реализовать?
Спасибо!
Ответы
Ответ 1
Поскольку бит suid
в исполняемых файлах изменяет только эффективный UID (EUID), исполняемый файл будет работать как, а не реальный UID (RUID), который getuid()
возвращает, и в дополнение к ограничению на suid
интерпретируется скрипты (любой исполняемый файл, начинающийся с "#!
" ), некоторые оболочки, такие как bash
в качестве дополнительной меры безопасности, в этом случае вернут EUID в RUID, вам нужно будет использовать вызов setuid(0)
в коде C перед выполнением script.
Обратитесь к страницам man
setuid
, seteuid
, getuid
и geteuid
, чтобы узнать точную семантику действительных и эффективных UID.
(ПРЕДУПРЕЖДЕНИЕ) Конечно, это подходящий момент, чтобы упомянуть, что ограничение на suid
скрипты во многих Unix-системах, оболочках и интерпретаторах существует по какой-то причине, а именно: если script не очень заботясь о том, чтобы дезинфицировать свой вклад и состояние окружающей среды, когда оно выполняется, они опасны и могут быть использованы для эскалации безопасности. Поэтому будьте очень осторожны при этом. Задайте доступ к вашему script и обертке как можно более строгим, разрешите только этот конкретный script, который вы намереваетесь выполнить, и очистите среду в своей программе C до запуска script, изменяя переменные среды окружения как PATH
, чтобы содержать именно то, что необходимо в правильном порядке, и никакие каталоги, которые можно записывать другим.
Ответ 2
Еще одно замечание: ограничение здесь происходит от bash, а не от самой системы * nix. bash действительно делают проверки на скриптах SUID только для их выполнения с помощью корня EUID. Если вы берете старые раковины, вы часто получаете то, что хотите, из коробки. Например, sh не делает такого рода проверки:
$ cat wrapper.c
int main(void)
{
system("/bin/sh -c whoami");
}
$ ls -l wrapper
-rwsr-sr-x 1 root users 8887 Feb 17 14:15 wrapper
$ ./wrapper
root
С помощью bash:
$ cat wrapper.c
int main(void)
{
system("/bin/bash -c whoami");
}
$ ls -l wrapper
-rwsr-sr-x 1 root users 8887 Feb 17 14:18 wrapper
$ ./wrapper
skinp
Тем не менее, ответ Tom, как правило, подходит для создания оболочки для корневых программ SUID.
Ответ 3
Добавьте setuid (0) в script и соблюдайте его. После этого он будет работать.
$ cat wrapper.c
int main(void)
{
setuid(0);
system("/bin/bash ./should_run_as_root.sh");
}
$ gcc -o wrapper wrapper.c
$ sudo chown root wrapper
$ sudo chmod ug+s wrapper
$ ll wrapper
-rwsr-sr-x 1 root users 6667 2009-02-17 11:11 wrapper
$
Ответ 4
Примеры ужасно небезопасны и позволяют любому, у кого есть два бита знаний, запускать любую программу, которую они хотят, в качестве пользователя setuid.
Никогда не проходите через оболочку, если вы сначала не дезинфицируете среду, большинство примеров, показанных здесь, уязвимы для того, чтобы установить IFS и PATH перед ее запуском.
Ответ 5
Почему sudo нежизнеспособно? Это позволяет избежать бушующих дыр в безопасности, таких как:
bash-3.2$ cat test
#!/bin/bash
echo ima shell script durp durp
bash-3.2$ chmod +x test
bash-3.2$ ./test
heh heh
bash-3.2$
Из-за того, что среда не подвергается надлежащей дезинфекции, например, в этом случае:
export echo='() { builtin echo heh heh; }'
sudo sanitizes этот случай, и, возможно, другие случаи края и gotchas, что было бы хорошо не писать в пользовательскую оболочку suid.
Ответ 6
Чистая атомная энергия dr.hrb.freeshell.org