Comment utiliser capsh: j'essaie d'exécuter un ping non privilégié, avec des capacités minimales

13

J'expérimente des capacités, sur Debian Gnu / Linux.

J'ai copié / bin / ping dans mon répertoire de travail actuel. Comme prévu, cela ne fonctionne pas, il était à l'origine root setuid.

Je donne ensuite à mon ping les capacités minimales (pas root) en faisant sudo /sbin/setcap cap_net_raw=ep ./ping, et mon ping fonctionne, comme prévu.

Ensuite, sudo /sbin/setcap -r ./pingpour révoquer cette capacité. Cela ne fonctionne plus comme prévu.

J'essaie maintenant de faire fonctionner ping avec capsh.

capsh n'a pas de privilèges, je dois donc l'exécuter en tant que root, mais ensuite supprimer root et donc tous les autres privilèges.

Je pense que j'ai aussi besoin secure-keep-caps, ce n'est pas documenté dans capsh, mais c'est dans le manuel des capacités. J'ai obtenu les numéros de bits /usr/include/linux/securebits.h. Ils semblent corrects, car la sortie de --printmontre que ces bits sont corrects.

Je tripote depuis des heures, jusqu'à présent je l'ai.

sudo /sbin/capsh --keep=1 --secbits=0x10 --caps="cap_net_raw+epi" == --secbits=0x10 --user=${USER} --print -- -c "./ping localhost"

Cependant les pingerreurs avec ping: icmp open socket: Operation not permitted, c'est ce qui se passe quand il ne possède pas la capacité. Aussi les --printspectacles Current: =p cap_net_raw+i, ce n'est pas suffisant dont nous avons besoin e.

sudo /sbin/capsh --caps="cap_net_raw+epi" --print -- -c "./ping localhost"définira la capacité à Current: = cap_net_raw+eipcela est correct, mais nous laisse comme root.

Édition-1

J'ai essayé sudo /sbin/capsh --keep=1 --secbits=0x11 --caps=cap_net_raw+epi --print -- -c "touch zz; ./ping -c1 localhost;"

Cela produit:

touch: cannot touch `zz': Permission denied
ping: icmp open socket: Operation not permitted

La première erreur est attendue car secure-noroot: yes Mais la seconde n'est pasCurrent: = cap_net_raw+eip

Edit-2

Si je mets ==avant le --print, il apparaît maintenant Current: = cap_net_raw+i, ce qui explique l'erreur précédente, mais pas pourquoi nous perdons des capacités lors du passage hors de root, je pensais que cela secure-keep-capsdevrait résoudre ce problème.

Edit-3

D'après ce que je peux voir, je perds Efficace (e) et Autorisé (p), lorsque exec est appelé. C'est prévu, mais je pensais que les bouchons de sécurité devraient empêcher leur perte. Suis-je en train de manquer quelque chose.

Edit-4

J'ai fait plus de recherches et relu le manuel. Il semble que normalement eet les pcapacités soient perdues lorsque: vous changez d'utilisateur root(ou appliquez secure-noroot, faisant ainsi de root un utilisateur normal), cela peut être remplacé par secure-keep-caps; quand vous appelez exec, autant que je sache, c'est un invariant.

Pour autant que je sache, cela fonctionne selon le manuel. Autant que je sache, il n'y a aucun moyen de faire quoi que ce soit d'utile capsh. Pour autant que je sache, pour utiliser les capacités, vous devez: utiliser des capacités de fichier ou avoir un programme prenant en charge les capacités, qui n'utilise pas exec. Aucun wrapper privilégié donc.

Alors maintenant, ma question est de savoir ce qui me manque, à quoi ça sert capsh.

Edit-5

J'ai ajouté une réponse concernant les capacités ambiantes. Peut-être capshpeut-être également être utilisé avec des capacités héritées, mais pour être utiles, celles-ci devront être définies sur le fichier exécutable. Je ne vois pas comment capsh peut faire quelque chose d'utile sans les capacités ambiantes, ou pour permettre des capacités héritées.


Versions:

  • capshà partir de la libcap2-binversion du package1:2.22-1.2
  • avant edit-3 Je saisis la dernière à capshpartir git://git.debian.org/collab-maint/libcap2.gitet commencé à l' utiliser.
  • uname -a Linux richard-laptop 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux L'utilisateur-terre est 32 bits.
ctrl-alt-delor
la source
1
Avez-vous essayé l'exemple de Lekensteyn avec une version en amont ultérieure ? Obtenir capshle dépôt collab-maint ne vous aurait pas donné la «dernière» capsh, le paquet Debian ne supporte toujours pas les capacités ambiantes. En amont 2.27 fait.
Stephen Kitt
1
@StephenKitt bon à savoir, mais la question initiale est de savoir à quoi sert capsh, en l'absence de température ambiante (comme c'était le cas à l'origine). Qu'est-ce que je rate. Il doit avoir une utilité.
ctrl-alt-delor

Réponses:

11

Les capacités sont les propriétés des processus. Traditionnellement, il existe trois ensembles:

  • Capacités autorisées ( p ): capacités qui peuvent être "activées" dans le processus en cours.
  • Capacités efficaces ( e ): capacités actuellement utilisables dans le processus actuel.
  • Capacités héritables ( i ): capacités de fichiers pouvant être héritées.

Les programmes exécutés en tant que root ont toujours toutes les capacités autorisées et efficaces, donc "ajouter" plus de capacités n'a aucun effet notable. (L'ensemble des capacités héritables est normalement vide.) Avec setcap cap_net_raw+ep pingvous activez ces capacités par défaut pour tout utilisateur exécutant ce programme.

Malheureusement, ces capacités sont liées au fichier exécuté et ne sont pas conservées après l'exécution d'un nouveau processus enfant. Linux 4.3 a introduit des capacités ambiantes qui permettent aux capacités d'être héritées par les processus enfants. (Voir aussi Transformation des capacités pendant execve () dans les capacités (7) .)

Tout en jouant avec les capacités, notez ces pièges:

  • Lorsque vous changez l'utilisateur de root en non root, les capacités effectives et autorisées sont effacées (voir Effet des changements d'ID utilisateur sur les capacités dans les capacités (7) ). Vous pouvez utiliser l' --keep=1option de capshpour éviter d'effacer les ensembles.
  • L'ensemble des capacités ambiantes est effacé lors du changement des ID utilisateur ou groupe. Solution: ajoutez les fonctionnalités ambiantes après avoir modifié l'ID utilisateur, mais avant d' exécuter un processus enfant.
  • Une capacité ne peut être ajoutée à l'ensemble de capacités ambiantes que si elle se trouve déjà dans l'ensemble de capacités autorisé et héritable.

Le capshprogramme de libcap 2.25 n'a pas encore la possibilité de modifier les capacités ambiantes, mais les versions ultérieures ajoutent de nouvelles options. Notez que l'ordre des options est important. Exemple d'utilisation:

sudo capsh --caps="cap_net_raw+eip cap_setpcap,cap_setuid,cap_setgid+ep" \
    --keep=1 --user=nobody --addamb=cap_net_raw -- \
    -c "./ping -c1 127.0.0.1"

Astuce: vous pouvez ajouter l' --printoption n'importe où dans la capshligne de commande et voir son état actuel des capacités.

Remarque: cap_setpcapest nécessaire pour --addambtandis que cap_setuid,cap_setgidsont nécessaires pour l' --useroption.

Lekensteyn
la source
6

La réponse de Lekensteyn semble exacte et complète, mais je vais essayer de fournir une autre explication sous un angle différent qui tentera de souligner le problème résolu par les capacités ambiantes.

Lorsque vous exécutez sudo capsh --user=<some_user> --Il y a 2 appels système d'intérêt qui entraînent le recalcul (et potentiellement la suppression) des capacités:

  1. setuid: Selon man capabilities:

SECBIT_KEEP_CAPS La définition de cet indicateur permet à un thread qui a un ou plusieurs 0 UID de conserver ses capacités lorsqu'il bascule tous ses UID vers une valeur différente de zéro. Si cet indicateur n'est pas défini, un tel commutateur UID fait perdre au thread toutes ses capacités.

En d'autres termes, dans notre capshcommande ci-dessus, nous devons nous assurer que SECBIT_KEEP_CAPS est défini lors de l' setuidappel système. Sinon, toutes les capacités sont perdues. C'est ce que --keep=1fait. Alors maintenant, la commande devientsudo capsh --user=<some_user> --keep=1 --

  1. execve: Si nous utilisons l' --keep=1option, tous les ensembles de capacités (efficaces, autorisés, héritables) sont conservés jusqu'à l' execveappel système, mais execveentraînent également le recalcul des capacités (pour les utilisateurs non root) et de manière moins évidente. En bref, avant l'ajout de l'ensemble de capacités ambiantes , pour qu'une capacité soit dans l'ensemble "autorisé" d'un thread après un execveappel, soit:

    • Le fichier doit avoir cette capacité dans son ensemble "autorisé" . Cela peut être fait avec setcap cap_net_raw+p /bin/bash. Faire cela rend l'ensemble de l'exercice inutile car les ensembles de capacités du thread (autres que l'ensemble de délimitation) n'ont plus aucun effet.
    • Le fichier et le thread doivent avoir cette capacité dans leurs ensembles "héritables" . Vous pouvez penser que setcap cap_net_raw+icela ferait l'affaire, mais il s'avère que execveles autorisations héritables d'un thread sont supprimées lorsqu'il est appelé par des utilisateurs non privilégiés (ce que nous remercions actuellement setuid). Il n'y a donc aucun moyen de satisfaire à cette condition en tant qu'utilisateur non privilégié.

Les capacités ambiantes introduites dans Linux 4.3 permettent à un thread de conserver ses capacités même après un setuidà un utilisateur non privilégié suivi d'un execve, sans avoir à compter sur des capacités de fichier.

catanman
la source
2

Il peut y avoir un bug / fonctionnalité dans le noyau. Il y a eu quelques discussions:

Je n'ai aucune idée, si quelque chose a été fait, de le réparer.

Ne vous méprenez pas - le comportement actuel est sécurisé. Mais c'est tellement sûr qu'il fait obstacle à des choses qui devraient sembler fonctionner.

Edit: Selon http://man7.org/linux/man-pages/man7/capabilities.7.html, il y a un nouvel ensemble de capacités Ambient (depuis Linux 4.3). Il semble que cela permettra ce qui est nécessaire.

ctrl-alt-delor
la source