O modo de permissão executável S é usado para alguma coisa?

4

Se você adicionar o bit setuid para a permissão de um arquivo em que tiver permissão de execução, ele alterará o x para um s para significar que, se você executar esse arquivo, ele será executado como proprietário do arquivo a pessoa realmente a executando.

Mas também observei que, se você adicionar a permissão s , mas remover a permissão x , ela mudará para S na listagem de permissões. De alguma forma isso implicaria que não poderia ser executado, mas seria executado simultaneamente como o proprietário, se pudesse ser executado? Está certo?

Estou entendendo mal essa permissão? Para que isso é usado? O que significa isso?

    
por Aruka J 04.10.2017 / 06:30

3 respostas

2

Todas as quatro combinações existem e são significativas.

"O dono real deste arquivo pode executá-lo?" e "Quem o sistema fingirá que está executando este arquivo?" são duas perguntas separadas. Todas as quatro combinações são possíveis e significativas.

As strings de permissões exibidas por ls -l ou stat -c %A show, na posição de execução do proprietário (isto é, no lugar de ? in ---?------ ), quatro caracteres diferentes, um para cada combinação:

  1. - significa que o proprietário não pode executar o arquivo e, se um não-proprietário o executar, ele será executado como esse outro usuário .
  2. x significa que o proprietário pode executar o arquivo e, se um não proprietário o executar, ele será executado como esse outro usuário .
  3. S significa que o proprietário não pode executar o arquivo e, se um não proprietário o executar, ele será executado como o proprietário .
  4. s significa que o proprietário pode executar o arquivo e, se um não-proprietário o executar, ele será executado como o proprietário .

O bit setuid e os bits de execução são bits separados, e o modo string é apenas uma maneira conveniente de visualizar os bits de permissão, incluindo aqueles. Outra maneira de pensar sobre isso é:

  • x ou s significa que o bit de execução está definido. - ou S significa que não é.
  • s ou S significa que o bit setuid está definido. - ou x significa que não é.

Da mesma forma, um grupo pode ou não ter permissões de execução em um arquivo e, se executado, pode ou não ser executado com uma identidade de grupo diferente da do usuário que o executa. Para fazer com que um arquivo seja executado com a identidade do grupo do proprietário do grupo, e não do usuário que o executa, defina bit setgid ( ------s--- ou ------S--- ).

S não representa um bit de modo separado. É simplesmente uma maneira de significar que o bit setuid (ou setgid) está definido, mas o bit executável correspondente não está definido.

$ touch foo
$ chmod u+S foo
chmod: invalid mode: ‘u+S’
Try 'chmod --help' for more information.

Você pode examinar os bits em si.

Para ver se esses bits são separados, use o especificador de formato %a para stat em vez de %A . Para simplificar as coisas, anulei todos os outros bits de modo.

$ touch a b c d
$ chmod u=,g=,o= a
$ chmod u=x,g=,o= b
$ chmod u=s,g=,o= c
$ chmod u=xs,g=,o= d
$ stat -c '%A %n' a b c d
---------- a
---x------ b
---S------ c
---s------ d
$ stat -c '%04a %n' a b c d
0000 a
0100 b
4000 c
4100 d

Isso deixa claro ... se você está confortável com octal . Se você quiser vê-lo em binário (eles são bits depois de tudo) você pode converter as representações:

$ stat -c '%a %n' a b c d | perl -pe 's/\d+/sprintf("%012b", oct($&))/e'
000000000000 a
000001000000 b
100000000000 c
100001000000 d

Setuid define o ID do usuário efetivo, não o ID do usuário real.

Execute o controle de bits se uma tentativa executar um arquivo pode ou não suceder, enquanto os bits setuid / setgid controlam a identidade na qual o novo processo é executado se for permitido criá-lo. Portanto, não há nada inconsistente ou surpreendente sobre a combinação de permissões S representa ( -x,+s ). Isto seria assim mesmo se um executável rodando como seu dono, porque seu dono realmente o rodasse, funcionasse exatamente como um executável rodando como seu dono, porque alguém o executou, mas foi setuid. Mas não é assim que funciona.

O kernel usa mais de um número para acompanhar a identidade do usuário de um processo em execução. Um desses números é o UID e outro é o EUID. Veja este artigo para detalhes. O bit setuid faz com que o EUID (ID do usuário efetivo) seja alterado, mas o UID (ID do usuário real) permanece o mesmo. Um uso disso para permitir que os sinais sejam trocados entre processos que compartilham um UID, mas têm EUIDs diferentes, mas outro é que ele permite que um programa seja projetado para ter seu bit setuid configurado para verificar quem o executou .

Por exemplo, passwd deve ser setuid, porque somente root pode alterar entradas no banco de dados de senhas:

$ ls -l "$(command -v passwd)"
-rwsr-xr-x 1 root root 54256 May 16 19:37 /usr/bin/passwd

-rwsr-xr-x tem r-x no final, para outros . Devido ao x , mesmo os usuários que não são root ou no grupo raiz podem executar passwd . E tem rws perto do começo, para proprietário . Devido ao s , o programa é executado como root, mesmo quando não proprietários o executam. Mas quando você executa passwd , ele redefine sua senha, não a do root.

passwd é capaz de realizar qualquer alteração no banco de dados de usuários e senhas, porque ele é executado com o ID de usuário efetivo do root. Mas ele é projetado para se recusar a mudar a senha de qualquer pessoa, mas o usuário a executou - exceto quando esse usuário é root - porque verifica seu ID de usuário real.

Este é o caso de uso típico do executável setuid: para criar uma interface que permite que um usuário faça com que as ações sejam executadas como outro, de uma maneira limitada, que é verificada pelo código do executável setuid.Portanto, é apenas seguro definir o bit setuid (ou o bit setgid) em um programa que é projetado para ter essas permissões.

Esta é a outra parte do quebra-cabeça para entender por que as permissões S significam não há enigma: a potência que o setuid bit confere não atinge a mesma coisa que a execução real o programa como seu proprietário , mesmo que o programa tenha permissão para ser executado.

A verificação de UID e EUID com uma cópia de id mostra como o setuid funciona.

Ok, bem, vou definir o bit setuid em um executável que não foi projetado para ele, para mostrar como os IDs de usuário reais e efetivos são afetados.

  • O executável será uma cópia do id programa que, entre outras coisas, informa seus IDs de usuário reais e efetivos. Embora este programa não seja projetado para ser setuid, ele também não foi projetado para alterar nada - exceto pela produção de saída -, portanto, isso é razoavelmente seguro. Mas você ainda deve excluí-lo depois. (Sua cópia. Não é o original.)
  • Estamos usando uma cópia, não alterando as permissões no original. Você não precisa usar sudo ou executar qualquer ação como root para isso.
  • Para executá-lo como outro usuário, você precisa de uma segunda conta de usuário, mas pode usar su para executar ações como esse usuário. (Por padrão, a conta root não permite que você faça login com uma senha, por isso, se você cometer um erro e executar su sem fornecer o nome de usuário para o qual deseja alternar, não será acidentalmente se tornando root em vez disso, a menos que você também tenha ativado logins de raiz. Se você realmente quiser usar sudo -u user em vez de su user -c , então você pode.)

Minha conta de usuário principal é chamada ek e minha segunda conta é ek2 . Tudo bem se vocês são diferentes. Primeiro, como ek , copio id para o diretório atual (que está em algum lugar dentro do meu diretório pessoal):

$ type -a id
id is /usr/bin/id
$ cp /usr/bin/id .

A cópia tem a propriedade do usuário não raiz que a copiou, mas as permissões originais:

$ ls -l id /usr/bin/id
-rwxr-xr-x 1 ek   ek   39760 Oct  5 11:23 id
-rwxr-xr-x 1 root root 39760 Mar  2  2017 /usr/bin/id

Passar -n para id mostra nomes em vez de números de ID, -u mostra o usuário (e não outras informações como grupos) e -r faz com que a ID do usuário real seja mostrada. Sem -r , -u mostra o ID do usuário efetivo. Esse comportamento se aplica totalmente à cópia de id que acabei de criar.

Quando eu o executo como um usuário substituto, os IDs reais e efetivos dos usuários são alterados. Isso é parte de como su e sudo são escritos, e não é mero resultado de su estar sendo root setuid, embora seja. (É por isso que usei passwd como exemplo de um executável setuid típico, em vez de su ou sudo .) Esta é nossa linha de base, para ver que id no diretório atual funciona como esperado:

$ ./id -nu                # ek runs id, displaying the effective user
ek
$ ./id -nur               # ek runs id, displaying the real user
ek
$ su ek2 -c './id -nu'    # ek2 runs id, displaying the effective user
Password:
ek2
$ su ek2 -c './id -nur'   # ek2 runs id, displaying the real user
Password:
ek2

Agora faço esta cópia local de id setuid:

$ chmod u+s id
$ ls -l id
-rwsr-xr-x 1 ek ek 39760 Oct  5 11:42 id

Agora, quando o executo, seu ID de usuário real ainda é o do usuário que o executou, enquanto seu ID de usuário efetivo é o de ek , mesmo quando ek2 o executa:

$ ./id -nu                # ek runs id, displaying the effective user
ek
$ ./id -nur               # ek runs id, displaying the real user
ek
$ su ek2 -c './id -nu'    # ek2 runs id, displaying the effective user
Password:
ek
$ su ek2 -c './id -nur'   # ek2 runs id, displaying the real user
Password:
ek2

Agora eu tiro as permissões executáveis do proprietário, mas as deixo para todos os outros:

$ chmod u-x id
$ ls -l id
-rwSr-xr-x 1 ek ek 39760 Oct  5 11:42 id

ek2 ainda pode executá-lo como com o ID de usuário efetivo de ek , mesmo que ek não possa executá-lo:

$ ./id -nu                # ek runs id, displaying the effective user
-bash: ./id: Permission denied
$ ./id -nur               # ek runs id, displaying the real user
-bash: ./id: Permission denied
$ su ek2 -c './id -nu'    # ek2 runs id, displaying the effective user
Password:
ek
$ su ek2 -c './id -nur'   # ek2 runs id, displaying the real user
Password:
ek2

Mas, como mostrado, isso não produz o mesmo resultado que ek na execução. ek2 não pode realmente fazer o que ek poderia fazer se ek tivesse permissão para executar o programa, a menos que o programa o permitisse.

(Depois, eu corri o rm id para remover o arquivo, então eu não teria um executável setuid desnecessário no meu diretório pessoal. Ou você poderia apenas remover o bit setuid com chmod -s id .)

    
por Eliah Kagan 05.10.2017 / 18:16
3

A saída exibe S se setuid estiver definido, mas as permissões do usuário não incluem a execução. No entanto, contanto que o grupo ou outro possa executar, o bit setuid tem significado: se alguém além do proprietário executar o arquivo, ele será executado como o proprietário, que é a finalidade pretendida do setuid. Se o proprietário puder executar o arquivo, ele será executado como seu usuário, portanto, o setuid é irrelevante para o proprietário.

Aqui está uma ilustração simples:

$ cp $(which whoami) foo
$ sudo chmod u=rs,go+x foo
$ stat -c %A foo
-r-Sr-xr-x
$ ./foo
zsh: permission denied: ./foo
$ sudo -u www-data whoami
www-data
$ sudo -u www-data ./foo
muru
    
por muru 04.10.2017 / 06:55
1

Isso está de fato certo. Normalmente, deve ser s quando o x é definido no arquivo em questão. Mas quando o bit de execução x foi removido, o s é alterado para S para informar que, embora o setuid seja usado nesse arquivo, ele não possui x set.

Nesse caso, isso nem será executado, pois o x não está definido. Agora temos esse -r-Srwxr-x , que significa o - outros ainda podem executar esse script. Então, quando você mudar para qualquer outro usuário que não seja owner , o script será executado

Info ls :

 ‘s’
      If the set-user-ID or set-group-ID bit and the corresponding
      executable bit are both set.

 ‘S’
      If the set-user-ID or set-group-ID bit is set but the
      corresponding executable bit is not set.
    
por George Udosen 04.10.2017 / 06:48