Darwin retira setuid do interpretador na execução de hash bang

1

Esta não é exatamente uma questão sobre como executar um script de hash bang .

Nessa situação, existe um script hash bang que não possui (necessariamente) a permissão u+s . Em vez disso, o interpretador tem u+s e o script designa esse interpretador: #!/path/to/interpreter .

No Mac OS, nessa situação, o próprio intérprete designado não recebe o setuid implícito por seus bits de permissão próprios , como seria se fosse diretamente executado. Seu ID de usuário real e efetivo é apenas o do usuário que executou o script de hash bang.

Existe uma solução alternativa para este que não envolve a reexecução do intérprete em si?

Reexecução de trabalhos:

Kazs-Mac-Pro:txr kaz$ uname -a
Darwin Kazs-Mac-Pro.local 11.0.0 Darwin Kernel Version 11.0.0: Fri Apr  8 20:29:42 PDT 2011; root:xnu-1699.22.36~1/RELEASE_X86_64 x86_64
Kazs-Mac-Pro:txr kaz$ cat setuid.tl
#!./txr --reexec
(put-line 'gids: @(getegid) @(getgid)')
(put-line 'uids: @(geteuid) @(getuid)')
(put-line 'groups: @(getgroups)')
(seteuid 0) ;; throws if unable
Kazs-Mac-Pro:txr kaz$ ls -l txr setuid.tl
-rwsr-xr-x  1 root  wheel      163  5 May 15:18 setuid.tl
-rwsr-xr-x  1 root  wheel  1334500  5 May 15:17 txr
Kazs-Mac-Pro:txr kaz$ ./setuid.tl 
gids: 20 20
uids: 0 501
groups: 20 402 401 12 33 61 79 80 81 98 100 204

Tudo o que --reexec faz é chamar execvp no nome do caminho do programa e os argumentos restantes após --reexec . Poof, setuid privs estão de volta. Isso é feio, no entanto.

Se não tivermos --rexec , este é o comportamento:

Kazs-Mac-Pro:txr kaz$ ./setuid.tl 
gids: 20 20
uids: 501 501
groups: 20 402 401 12 33 61 79 80 81 98 100 204
./txr: unhandled exception of type system-error:
./txr: seteuid failed: 1/"Operation not permitted"
./txr: during evaluation at ./setuid.tl:4 of form (seteuid 0)

(O u+s no script é irrelevante do ponto de vista do sistema; o interpretador usa isso e a propriedade do script para decidir se deve executar o script setuid ou se deve descartar privilégios permanentemente e depois executá-lo. É claro que não queremos fazer esse tipo de coisa com um intérprete que não está ciente da operação setuid e cegamente confere seu privilégio elevado a qualquer parte do código que é solicitado a executar.

    
por Kaz 05.05.2016 / 18:46

1 resposta

0

A maioria das variantes Unix desabilita o setuid em scripts por motivos de segurança. Para obter mais informações, consulte Permitir o setuid em scripts de shell

Versões anteriores do OS X tinham uma configuração para permitir scripts setuid: sysctl kernl.sugid_scripts=1 , mas Não vejo isso documentado em 10.9 . Não sei se ainda existe, mas não está documentado e, se ainda existir, não sei se é seguro.

A maneira usual de executar um script setuid é através de sudo , que cuida de alguns dos problemas de segurança com scripts setuid, em particular, sanitizando o ambiente. Adicione uma regra sudo (execute visudo para editar a configuração do sudo):

ALL ALL = (target_user : target_group) /path/to/script

Isso permite que qualquer pessoa execute sudo -u target_user -g target_group /path/to/script … (com qualquer argumento). Substitua o primeiro ALL por %original_group para permitir que apenas os membros de origininal_group façam isso.

Se você quiser que isso seja transparente, escreva um script de wrapper que invoque sudo como desejado:

#!/bin/sh
exec sudo -u target_user -g target_group /path/to/script "$@"
    
por 06.05.2016 / 02:28

Tags