Вызов сценария из программы C с setuid root - сценарий не запускается от имени пользователя root

StackOverflow https://stackoverflow.com/questions/556194

  •  05-09-2019
  •  | 
  •  

Вопрос

Мне нужно запустить сценарий bash от имени пользователя root (sudo без пароля или su нежизнеспособно), и поскольку вы не можете установить идентификатор сценария в 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
$

Это работает - как и правильно запускает скрипт - но скрипт запускается от имени пользователя, который выполняет "./wrapper".

Почему?И как это правильно реализовать?

Спасибо!

Это было полезно?

Решение

Поскольку suid бит в исполняемых файлах изменяет только эффективный UID (EUID), под которым будет запускаться исполняемый файл, а не реальный UID (RUID), который getuid() возвращается, и в дополнение к ограничению на suid интерпретируемые сценарии (любые исполняемые файлы, начинающиеся с «#!"), некоторые оболочки типа bash поскольку дополнительная мера безопасности приведет к тому, что EUID вернется к RUID, в этом случае вам нужно будет использовать вызов setuid(0) в коде C перед выполнением сценария.

См. man страницы setuid, seteuid, getuid, и geteuid узнать точную семантику реальных и эффективных UID.

(ПРЕДУПРЕЖДЕНИЕ) Конечно, уместно упомянуть, что ограничение на suid Сценарии во многих системах Unix, оболочках и интерпретаторах существуют по определенной причине: если сценарий не очень тщательно очищает свои входные данные и состояние среды при его выполнении, они опасны и могут быть использованы для повышения безопасности. .Поэтому будьте очень осторожны, делая это.Установите максимально строгий доступ к вашему сценарию и оболочке, разрешите выполнение только этого конкретного сценария, который вы собираетесь выполнять, и очистите среду в вашей программе C перед запуском сценария, установив переменные среды, такие как PATH содержать именно то, что необходимо, в правильном порядке и не содержать каталогов, доступных для записи другим.

Другие советы

Еще следует отметить, что ограничение здесь связано с 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

С Башем:

$ 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

Тем не менее, ответ Тома, как правило, является способом создания оболочки для корневых программ SUID.

Добавьте setuid(0) в скрипт и соблюдайте его.После этого должно работать.

$ 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 
$ 

Примеры ужасно небезопасны и позволяют любому, у кого есть хоть немного знаний, запустить любую программу, которую он хочет, от имени пользователя setuid.

Никогда не используйте оболочку, если вы предварительно не очистите среду. Большинство показанных здесь примеров уязвимы из-за установки IFS и PATH перед их запуском.

Почему 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 очищает этот случай и, возможно, другие крайние случаи и ошибки, которые было бы хорошо не записывать в специальную оболочку suid.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top