web-dev-qa-db-fra.com

Le mode d'autorisation exécutable S est-il utilisé pour quoi que ce soit?

Si vous ajoutez le bit setuid pour l'autorisation d'un fichier où vous avez l'autorisation d'exécution, le x devient un s, ce qui signifie que si vous exécutez ce fichier, il sera exécuté en tant que propriétaire du fichier. que la personne qui l'exécute réellement.

Mais j'ai aussi remarqué que si vous ajoutez l'autorisation s mais supprimez l'autorisation x, elle devient S dans la liste des autorisations. D'une certaine manière, cela impliquerait qu'il ne pourrait pas être exécuté mais qu'il serait simultanément exécuté en tant que propriétaire s'il pouvait être exécuté? Est-ce correct?

Est-ce que je comprends mal cette permission? A quoi cela sert? Qu'est-ce que ça veut dire?

4
AJJ

Les quatre combinaisons existent et ont un sens.

"Le propriétaire actuel de ce fichier peut-il l'exécuter?" et "Qui le système prétend-il exécuter ce fichier?" sont deux personnes distinctes des questions. Les quatre combinaisons sont possibles et significatives.

Les chaînes de permissions affichées par ls -l ou stat -c %A montrent, dans la position d'exécution du propriétaire (c'est-à-dire à la place de ? dans ---?------), quatre caractères différents, un pour chaque combinaison:

  1. - signifie que le propriétaire ne peut pas exécuter le fichier et, si un non-propriétaire l'exécute, il s'exécute sous le nom de cet autre utilisateur .
  2. x signifie que le propriétaire peut exécuter le fichier et, si un non-propriétaire l'exécute, il s'exécute comme cet autre utilisateur .
  3. S signifie que le propriétaire ne peut pas exécuter le fichier et, si un non-propriétaire l'exécute, il exécute en tant que propriétaire à la place . .
  4. s signifie que le propriétaire peut exécuter le fichier et, si un non-propriétaire l'exécute, il exécute en tant que propriétaire à la place .

Le bit setuid et les bits d'exécution sont des bits séparés, et la chaîne de mode n'est en réalité qu'un moyen pratique de visualiser les bits d'autorisation, y compris ceux-ci. Une autre façon de penser est:

  • x ou s signifie que le bit d'exécution est activé. - ou S signifie que ce n'est pas le cas.
  • s ou S signifie que le bit setuid est activé. - ou x signifie que ce n'est pas le cas.

De même, un groupe peut avoir ou non des autorisations d'exécution sur un fichier et, s'il est exécuté, il peut ou non être exécuté avec une identité de groupe différente de celle de l'utilisateur qui l'exécute. Pour qu'un fichier soit exécuté avec l'identité de groupe de son propriétaire plutôt que celle de l'utilisateur qui l'exécute, vous devez définir le bit setgid (------s--- ou ------S---). .

S ne représente pas un bit de mode séparé. C'est simplement une façon de signifier que le bit setuid (ou setgid) est activé mais que le bit exécutable correspondant n'est pas activé.

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

Vous pouvez examiner les bits eux-mêmes.

Pour voir qu'il s'agit de bits séparés, utilisez le spécificateur de format %a pour stat au lieu de %A. Pour simplifier les choses, j'ai désactivé tous les autres bits du mode.

$ 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

Cela rend clair ... si vous êtes à l'aise avec octal . Si vous voulez le voir dans binary (ils sont bits après tout), vous pouvez convertir les représentations:

$ 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 définit l'ID utilisateur effectif, pas le véritable ID utilisateur.

Execute bits contrôle si une tentative pour exécuter un fichier peut réussir, tandis que setuid/setgid bits contrôle l'identité du nouveau processus s'il est autorisé à le créer. La combinaison des autorisations que S représente (-x,+s) ne présente donc aucune incohérence ni aucune surprise. Ce serait le cas même si un exécutable fonctionnant en tant que propriétaire parce que son propriétaire fonctionnait réellement, il fonctionnait exactement de la même manière qu'un exécutable exécutant sous le nom de son propriétaire car quelqu'un l'exécutait mais il était défini sur setuid. Mais ce n'est pas comme ça que ça marche.

Le noyau utilise plus d'un numéro pour garder trace de l'identité de l'utilisateur d'un processus en cours d'exécution. L'un de ces numéros est l'UID et un autre est l'EUID. Voir cet article pour plus de détails. Le bit setuid entraîne la modification de l’UEID (ID utilisateur effectif), mais l’UID (ID utilisateur réel) reste le même. L’une de ses utilisations est de permettre l’échange de signaux entre des processus partageant un UID mais ayant des EUID différents, mais elle permet également à un programme conçu pour que son bit setuid soit défini sur et vérifie qui a exécuté le bit. il.

Par exemple, passwd doit être setuid, car seul root peut modifier les entrées de la base de données de mots de passe:

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

-rwsr-xr-x a r-x à la fin, pour autres . En raison de x, même les utilisateurs qui ne sont ni root ni dans le groupe racine peuvent exécuter passwd. Et il y a rws au début, pour propriétaire . En raison de s, le programme s'exécute en tant que root, même lorsque des non-propriétaires l'exécutent. Mais lorsque vous exécutez vous-même passwd, votre mot de passe est réinitialisé, pas celui de l'utilisateur root.

passwd est capable de modifier de quelque manière que ce soit la base de données des utilisateurs et des mots de passe, car elle s'exécute avec l'ID utilisateur effectif de root. Mais il est conçu pour refuser de changer le mot de passe de quiconque mais que l'utilisateur l'exécutait - sauf lorsque cet utilisateur est root - car il vérifie son véritable ID utilisateur.

C'est le cas typique d'utilisation de setuid exécutable: créer une interface qui permet à un utilisateur de faire en sorte que les actions soient exécutées comme un autre, d'une manière limitée et contrôlée par le code de l'exécutable setuid. Par conséquent, il est uniquement sécurisé de définir le bit setuid (ou le bit setgid) sur un programme conçu pour disposer de ces autorisations.

C’est l’autre pièce du puzzle pour comprendre pourquoi les autorisations que S signifie ne sont pas des énigmes: la puissance conférée par le bit setuid n’atteint pas Cela revient à exécuter le programme en tant que propriétaire , même une fois que le programme a été autorisé à s'exécuter.

Vérifier UID et EUID avec une copie de id montre comment fonctionne setuid.

D'accord, je vais définir le bit setuid sur un exécutable qui n'est pas conçu pour cela, afin de montrer comment les ID utilisateur réels et efficaces sont affectés.

  • L'exécutable sera une copie du programme id qui, entre autres choses, indique ses identifiants d'utilisateur réels et effectifs. Bien que ce programme ne soit pas conçu pour être setuid, il n'est pas non plus conçu pour changer quoi que ce soit - sauf en produisant une sortie -, ce qui est raisonnablement sûr. Mais vous devriez toujours le supprimer après. (Votre copie. Pas l'original.)
  • Nous utilisons une copie, et non modifiant les autorisations sur l'original. Vous n'avez pas à utiliser Sudo ou à effectuer une action en tant qu'utilisateur root pour cela.
  • Pour l'exécuter en tant qu'autre utilisateur, vous avez besoin d'un deuxième compte utilisateur, mais vous pouvez utiliser su pour effectuer des actions en tant que cet utilisateur . (Par défaut, le compte root ne vous permet pas de vous connecter avec un mot de passe. Par conséquent, si vous faites une erreur et exécutez su sans indiquer le nom d'utilisateur que vous souhaitez utiliser, vous ne serez pas forcément devenu root à la place. Si vous voulez vraiment utiliser Sudo -u user au lieu de su user -c, vous pouvez le faire.)

Mon compte d'utilisateur principal s'appelle ek et mon deuxième compte est ek2. C'est bien si les vôtres sont différentes. Tout d'abord, en tant que ek, je copie id dans le répertoire actuel (qui se trouve quelque part dans mon répertoire personnel):

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

La copie est la propriété de l'utilisateur non root qui l'a copiée, mais les autorisations d'origine:

$ 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

Passer -n à id affiche des noms au lieu de numéros d'identification, -u indique l'utilisateur (et non d'autres informations telles que des groupes), et -r provoque l'affichage de l'ID utilisateur réel. Sans -r, -u indique l'ID utilisateur effectif. Ce comportement s’applique pleinement à la copie de id que je viens de réaliser.

Lorsque je l'exécute en tant qu'utilisateur de substitution, les ID utilisateur réel et effectif sont modifiés. Cela fait partie de la façon dont su et Sudo sont écrits et ne résulte pas simplement du fait que su est lui-même setuid root, bien que ce soit le cas. (C’est pourquoi j’ai utilisé passwd comme exemple d’exécutable typique de setuid, plutôt que su ou Sudo.) C’est notre ligne de base pour vérifier que id dans le répertoire actuel fonctionne comme prévu:

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

Maintenant, je crée cette copie locale de id setuid:

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

Maintenant, lorsque je l'exécute, son véritable ID utilisateur est toujours celui de l'utilisateur qui l'a exécuté, alors que son identifiant utilisateur effectif est celui de ek même lorsque ek2 l'exécute:

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

Maintenant, je retire les autorisations exécutables du propriétaire mais les laisse à tout le monde:

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

ek2 peut toujours l'exécuter comme avec l'ID utilisateur effectif de ek, même si ek ne peut l'exécuter:

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

Mais, comme indiqué, cela n'a pas donné le même résultat que ek qui l'a exécuté. ek2 ne peut pas vraiment faire ce que ek pourrait faire si ek était autorisé à exécuter le programme, à moins que le programme ne le permette.

(Ensuite, j'ai exécuté rm id pour supprimer le fichier. Ainsi, je n'aurais pas d'exécutable setuid inutile traînant dans mon répertoire personnel. Vous pouvez également désélectionner le bit setuid avec chmod -s id.)

2
Eliah Kagan

La sortie affiche S si setuid est défini, mais les autorisations des utilisateurs n'incluent pas l'exécution. Cependant, tant que groupe ou autre peut être exécuté, le bit setuid a une signification: si quelqu'un d'autre que le propriétaire exécute le fichier, il s'exécutera en tant que propriétaire, ce qui est le but recherché par setuid. Si le propriétaire pouvait exécuter le fichier, il serait de toute façon exécuté en tant qu'utilisateur. Ainsi, setuid n'a aucune incidence sur le propriétaire.

Voici une illustration simple:

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

C'est vraiment vrai. Normalement, il devrait s'agir de s lorsque le x est défini sur le fichier en question. Mais là où le bit d'exécution x a été supprimé, alors le s devient S pour vous informer que, bien que le setuid soit utilisé sur ce fichier, il n'a pas de jeu x.

Dans ce cas, cela ne sera même pas exécuté car la x n'est pas définie. Nous avons maintenant ce -r-Srwxr-x, ce qui signifie que o - d’autres peuvent encore exécuter ce script. Ainsi, lorsque vous utiliserez un autre utilisateur que owner, le script sera exécuté.

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.
1
George Udosen