Comment utiliser capsh: Jessaie dexécuter un ping sans privilège, avec des capacités minimales
On février 13, 2021 by adminJexpérimente des capacités, sur Debian Gnu / Linux.
Jai copié / bin / ping dans mon répertoire de travail actuel. Comme prévu, cela ne fonctionne pas, cétait à lorigine setuid root.
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.
Puis sudo /sbin/setcap -r ./ping
pour révoquer cette capacité. Cela ne fonctionne plus comme prévu.
Jessaie maintenant de faire fonctionner le ping en utilisant capsh
.
capsh
na pas de privilèges, donc je dois lexécuter en tant que root, mais ensuite supprimer root et donc tous les autres privilèges.
Je pense que jai également besoin de secure-keep-caps
, cela nest pas documenté dans capsh
, mais cest dans la capacité Manuel. Jai obtenu les nombres de bits de /usr/include/linux/securebits.h
. Ils semblent corrects, car la sortie de --print
montre que ces bits sont corrects.
Je joue depuis des heures, jusquà présent, je lai.
sudo /sbin/capsh --keep=1 --secbits=0x10 --caps="cap_net_raw+epi" == --secbits=0x10 --user=${USER} --print -- -c "./ping localhost"
Cependant ping
erreurs avec ping: icmp open socket: Operation not permitted
, cest ce qui arrive quand il nen a pas la capacité. De plus, le --print
affiche Current: =p cap_net_raw+i
, ce nest pas suffisant, nous avons besoin de e
.
sudo /sbin/capsh --caps="cap_net_raw+epi" --print -- -c "./ping localhost"
définira la capacité sur Current: = cap_net_raw+eip
cest correct, mais nous laisse comme root
.
Edit-1
Jai maintenant 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 comme secure-noroot: yes
Mais la seconde nest pas Current: = cap_net_raw+eip
Edit-2
Si je mets ==
avant le --print
, cest maintenant montre Current: = cap_net_raw+i
, ce qui explique lerreur précédente, mais pas pourquoi nous perdons la capacité lors du changement de root, je pensais que secure-keep-caps
devrait corrige ça.
Edit-3
Daprès ce que je peux voir, je perds Effective (e) et Permitted (p), quand exec est appelé. Cest normal, mais jai pensé que les casquettes sécurisées devraient empêcher leur perte. Est-ce que je manque quelque chose?
Edit-4
Jai fait plus de recherches, et jai relu le manuel. Il semble que normalement les capacités e
et p
sont perdues lorsque: vous passez de lutilisateur root
(ou appliquer secure-noroot
, faisant ainsi de root un utilisateur normal), ceci peut être remplacé par secure-keep-caps
; lorsque vous appelez exec
, pour autant que je sache, cest un invariant.
Pour autant que je sache, cela fonctionne selon le manuel. Pour autant que je sache, il ny a aucun moyen de faire quoi que ce soit dutile avec capsh
. Pour autant que je sache, pour utiliser les capacités, vous devez: utiliser les capacités des fichiers ou avoir un programme prenant en charge les capacités, qui nutilise pas exec
. Donc pas de wrapper privilégié.
Ma question est donc de savoir ce qui me manque, à quoi sert capsh
.
Edit-5
Jai ajouté une réponse concernant les capacités ambiantes. Peut-être que capsh
peut également être utilisé avec des capacités héritées, mais pour être utiles, elles devraient être définies sur le fichier exécutable. Je ne vois pas comment capsh peut faire quelque chose dutile sans capacités ambiantes, ou pour autoriser des capacités héritées.
Versions:
-
capsh
du packagelibcap2-bin
version1:2.22-1.2
- avant edit-3 Jai récupéré le dernier
capsh
degit://git.debian.org/collab-maint/libcap2.git
et a commencé à lutiliser. -
uname -a
Linux richard-laptop 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux
User-land est 32 bits.
Commentaires
Réponse
Les capacités sont des propriétés de processus. Traditionnellement, il y a trois ensembles:
- Capacités autorisées ( p ): capacités qui peuvent être « activé » dans le processus en cours.
- Capacités effectives ( e ): capacités actuellement utilisables dans le processus actuel.
- Capacités héréditaires ( i ): capacités de fichier qui peuvent ê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 na aucun effet notable. (Lensemble des capacités pouvant être héritées est normalement vide.) Avec setcap cap_net_raw+ep ping
, vous activez ces capacités par défaut pour tout utilisateur exécutant ce programme.
Malheureusement, ces capacités sont liées au exécuté et ne sont pas conservés après lexécution dun nouveau processus enfant. Linux 4.3 a introduit les Capacités ambiantes qui permettent dhériter des capacités par les processus enfants. (Voir aussi Transformation des capacités pendant execve () dans capacités (7) .)
En jouant avec fonctionnalités, notez ces pièges:
- Lors du passage de lutilisateur root à non root, les capacités effectives et autorisées sont supprimées (voir Effet des changements dID utilisateur sur les capacités dans capacités (7) ). Vous pouvez utiliser loption
--keep=1
decapsh
pour éviter deffacer les ensembles. - Lensemble des capacités ambiantes est effacé lorsque changer les ID dutilisateur ou de groupe. Solution: ajoutez les fonctionnalités ambiantes après modification de lID utilisateur, mais avant dexécuter un processus enfant.
- Une fonctionnalité ne peut être ajoutée quaux fonctionnalités ambiantes défini sil fait déjà partie de lensemble des capacités autorisées et héritables.
Depuis la libcap 2.26, le programme capsh
a acquis la possibilité de modifier les capacités ambiantes via des options telles que --addamb
( commit ). Notez que lordre des options est significatif. Exemple dutilisation:
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 loption --print
nimporte où dans le capsh
et voir létat actuel de ses capacités.
Remarque: cap_setpcap
est nécessaire pour --addamb
tandis que cap_setuid,cap_setgid
sont nécessaires pour loption --user
.
Commentaires
- Quel numéro de version spécifique de libcap depuis capsh –addamb? Les notes de version 2.32 mentionnaient de nouvelles fonctionnalités de capsh, mais les mots étaient vagues.
- @ 把 友情 留 在 无 盐 Lorsque la réponse a été écrite à lorigine, seul git master la supportait. Depuis lors, libcap 2.26 a été publié avec le support de loption
--addamb
. Jai mis à jour la réponse en conséquence. - Malheureusement, ces capacités sont liées au fichier exécuté et ne sont pas conservées après lexécution dun nouveau processus enfant. – par processus enfant Je pense normalement à
fork(2)
, qui hérite des capacités. Seulexecve(2)
‘ nhérite pas des fonctionnalités, mais il ne crée ‘ pas un enfant traiter. Est-ce que je me trompe? - Citant
man capabiltiies
: Un enfant créé viafork(2)
hérite des copies de son parent ‘.
Réponse
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 essaiera de souligner le problème que lensemble des capacités ambiantes résout.
Lorsque vous exécutez sudo capsh --user=<some_user> --
Il y a 2 appels système dintérêt qui entraînent le recalcul des capacités (et potentiellement la suppression):
-
setuid
: selonman capabilities
:
SECBIT_KEEP_CAPS La définition de cet indicateur autorise un thread qui a un ou plusieurs 0 UID pour conserver ses capacités lorsquil fait passer tous ses UID à une valeur différente de zéro. Si cet indicateur nest pas défini, un tel commutateur UID entraîne la perte de toutes les fonctionnalités du thread.
En dautres termes, dans notre commande capsh
ci-dessus, nous devons nous assurer que SECBIT_KEEP_CAPS est défini pendant setuid
appel système. Sinon, toutes les capacités sont perdues. Cest ce que fait le --keep=1
. Alors maintenant, la commande devient sudo capsh --user=<some_user> --keep=1 --
-
execve
: Si nous utilisez loption--keep=1
, tous les ensembles de capacités (effectifs, autorisés, héritables) sont conservés jusquà lappel systèmeexecve
, maisexecve
entraîne également le recalcul des capacités (pour les utilisateurs non root), et dans une manière pas si évidente.En bref, avant lajout de lensemble des capacités ambiantes , pour quune capacité soit dans un thread « s » permise » défini après un appelexecve
, soit:- Le fichier doit avoir cette capacité dans son ensemble « autorisé » . peut être fait avec
setcap cap_net_raw+p /bin/bash
. Cela rend tout l exercice inutile puisque les ensembles de capacités du thread (autres que le jeu de limites) nont plus aucun effet. - Le fichier et le thread doivent avoir cette capacité dans leurs ensembles « héritables » . Vous pensez peut-être que
setcap cap_net_raw+i
ferait laffaire, mais il savère queexecve
entraîne la suppression des autorisations héritables dun thread lorsquil est appelé par un utilisateur non privilégié (ce que nous sommes actuellement grâce àsetuid
). Il ny a donc aucun moyen de satisfaire cette condition en tant quutilisateur non privilégié.
- Le fichier doit avoir cette capacité dans son ensemble « autorisé » . peut être fait avec
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 dun execve
, sans avoir à compter sur les capacités des fichiers.
Réponse
Il peut y avoir un bogue / une fonctionnalité dans le noyau. Il y a eu une discussion:
- https://bugzilla.altlinux.org/show_bug.cgi?id=16694
- http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-03/5224.html
Je nai aucune idée, si quelque chose a été d un, pour le réparer.
Ne vous méprenez pas – le comportement actuel est sécurisé. Mais il « est tellement sûr quil gêne les 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.
Réponse
Un léger ajustement de la réponse de Lekensteyn donne un appel plus court pour les noyaux récents:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw -- \ -c "./ping -c1 localhost"
Remarque: En fonction de votre fichier sudoers, cela peut créer un désordre dans votre environnement (par exemple changer HOME). capsh changera votre uid, mais il ne fera rien pour annuler les changements denvironnement de sudo.
Alors, que se passe-t-il ici? Jetons un œil:
-
sudo /usr/sbin/capsh
: Nous commençons en tant que root, qui a toutes les capacités dans ses ensembles effectifs (peut le faire) et autorisés (peut ajouter cela à effectif), mais rien dans les autres ensembles . Nous allons couvrir ces autres ensembles dans un instant. -
--keep=1
: Pour des raisons de sécurité (lisez: héritage), les capacités nhéritent normalement pas de root- > commutateurs dID non root. Cet indicateur active une fonctionnalité, connue sous le nom deSECBIT_KEEP_CAPS
, qui autorise cela. Il convient de noter quil est automatiquement effacé lors de lexécution , ce qui est une bonne idée. -
--user=$USER
: Maintenant que nous ne perdrons pas toutes nos capacités sur le changement dUID, nous abandonnons la racine. Grâce àSECBIT_KEEP_CAPS
, nous conservons les privilèges de type root, ce qui nous permet de jouer encore plus avec nos capacités. -
--inh=cap_net_raw
: Ceci ajoute notre capacité cible à lensemble héritable, car vous ne pouvez pas « rendre une capacité ambiante (voir lélément suivant) si elle » nest pas héritable. -
--addamb=cap_net_raw
: Même si nous « avons demandéSECBIT_KEEP_CAPS
,execve
dun binaire non privilégié (pas de setuid / setgid / setcap) sera toujours effacez nos capacités, ce qui nentraîne aucun privilège. Linux 4.3 a ajouté lensemble ambiant, qui est rajouté aux ensembles effectifs et autorisés lors de lexécution de binaires non privilégiés. Parfait! -
-- -c ...
: Après avoir tout configuré, nous exécutons bash avec ces arguments. Les ensembles de capacités sont effacés (car bash nest pas privilégié), lensemble ambiant est rajouté, et le tour est joué! Nous avons lautorisation nécessaire pour faire open raw sockets.
Vous pouvez vérifier cela en utilisant le argument à capsh, ce qui le fait sexécuter avec le reste de la ligne de commande:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw == --print Current: = cap_net_raw+eip
Ce qui signifie que nous avons cap_net_raw comme efficace (peut le faire), héritable (peut le transmettre aux processus enfants) et autorisé (sont autorisés à lobtenir). Et aucune autre fonctionnalité dans aucune de celles-ci.
Pour plus dinformations sur les fonctionnalités et leur fonctionnement, le mieux est de consulter la page de manuel capabilities (7) . Plus précisément len-tête Transformation of capabilities during execve()
.
Commentaires
- Quentendez-vous par Ceci est fait tôt, car il nécessite un certain nombre de fonctionnalités supplémentaires qui peuvent ‘ t disparaître jusquà ce que ‘ soit terminé. ?Dans votre cas, vous exécutez en tant que » root « , donc même ainsi
--user
nétait pas ‘ t changé, vous ‘ auriez-vous encore les capacités nécessaires plus tard? - Merci de lavoir signalé! Une version précédente de cette ligne de commande supprimait explicitement privs, il était donc nécessaire de setuid avant cela. Maintenant que les privs sont supprimés implicitement dans le cadre de exec, cela ‘ nest pas nécessaire.
capsh
du repo collab-maint ne vous aurait pas donné le « dernier »capsh
, le paquet Debian ne prend toujours pas en charge capacités ambiantes. Upstream 2.27 fait.capsh
, en labsence dambiance (comme cétait à lorigine). Quest-ce que je rate. Il doit avoir une utilisation.