Bonjour,
Je souhaite que les users unix puissent exécuter un script sans pouvoir le lire ce qui n'est pas possible en bash.
Je veux donc faire un wrapper en c qui va appeler un bash.
Si vous avez une idée, merci de revenir vers moi.
Merci d'avance.
Version imprimable
Bonjour,
Je souhaite que les users unix puissent exécuter un script sans pouvoir le lire ce qui n'est pas possible en bash.
Je veux donc faire un wrapper en c qui va appeler un bash.
Si vous avez une idée, merci de revenir vers moi.
Merci d'avance.
Bonjour,
Pourquoi ne voulez-vous pas que vous utilisateurs puissent lire les sources de votre script shell ?
Sinon, un simple appel à system() devrait vous suffire.
Tu devrais pouvoir utiliser les setuid/setgid pour mettre à un programme un UID/GID qui a accès aux scripts en lecture/exécution...
...et ce programme pourra lancer les scripts avec "system" ou la famille des "exec" (execvp, execve, etc...)
Faire bien attention au programme pour qu'il traite uniquement des cas et copie les arguments aux scripts !
Ca va être un gros if/else if/else avec des strcmp, et un cas par défaut d'erreur, puis de la copie de paramètres.
Bref, voilà mon idée...
Pour éviter le if/else if/else, je crois me souvenir que l'on me parlait de tableau de pointeurs sur fonctions... mais je n'y ai jamais vraiment bien réfléchi, donc je ne vais pas me lancer sur un terrain dont je ne suis pas sûr (mais libre aux autres de mieux te l'expliquer s'il est correct ! :P)
Bon courage !
EDIT : Voilà ! Tu as eu ta revanche Neckara !
Merci pour vos retours.
En effet, system peut le faire, mais je dois lui passer des variables au script C qui doit les transmètre au script exécuté via system() et je ne connais pas ces variables.
Et vu que la demande n'est pas de moi, je ne sais pas pourquoi les utilisateurs ne doivent pas lire le script.
Cordialement.
Si ton programme ne fait qu'exécuter un script, regarder du côté de exec serait en effet la meilleure solution.
Dans le cas de system, pas de chance, il va falloir écrire soit-même les arguments dans la commande passée à system.
Sinon, pour récupérer les arguments passé à l'exécutable, rien de plus simple :
Avec :Code:
1
2
3
4 int main(int argc, char ** argv) { }
argc : le nombre d'arguments
argv : les arguments passés à l'exécutable
argv[0] : la commande entrée par l'utilisateur pour lancer l'exécutable.
Pour récupérer les variables d'environnement : getenv !
Donc pour résumer :
- 1 UID ou 1 GID qui a le droit de lire/exécuter les scripts
- le programme C aura le setuid ou setgid dans le chmod d'activé + chown avec l'utilisateur en question
- le programme C contiendra system/exec pour exécuter
- le programme C contiendra getenv pour récupérer des variables précises de l'environnement, OU le 3e argument de main qui contient déjà l'environnement courant
Le mieux sera de restreindre les possibilités du programme avec if/else if/else et strcmp, pour éviter les classiques failles où l'on demandera un "/bin/rm -rf" par des moyens détournés (ou autre chose...)
EDIT : le 3e argument de main :
Code:int main(int argc, char **argv, char **env)
Merci.
Je vais voir de ce côté.
Je reviendrai par là au cas ou.
Cordialement.
Le fait de mettre simplement les droits d'exécution sans les droits de lecture, ça ne marche pas sous *n*x?
Avec les scripts je ne crois pas vu qu'il faut lire le fichier pour que sh/bash/ksh/[...] l'interprète.
Si l'utilisateur ne peut pas le lire, le programme lancé par cet utilisateur ne pourra pas non plus du coup.Citation:
Le fait de mettre simplement les droits d'exécution sans les droits de lecture, ça ne marche pas sous *n*x?
Au pire tu peux toujours crypter ton script puis le décrypter dans ton programme avant de l'exécuter.
Chiffrer/Déchiffrer ne servira à rien hormis perdre encore plus de temps et devoir faire des tas de choses complexes (où et comment sauvegarder la clé de chiffrement... parce qu'elle sera dans le binaire ou partagée avec les utilisateurs... donc totalement inutile).
Il faut simplement utiliser les droits.
Imperio a raison. Un programme exécuté par un utilisateur aura les mêmes droits que cet utilisateur.
Lancer un script revient à lancer un shell (avec les droits de l'utilisateur) qui interprétera ce script. Si l'utilisateur ne peut lire le contenu du script, le shell ne le pourra pas non plus ...
Ensuite on peut exécuter un programme avec des droits différents mais c'est un poil plus compliqué à gérer et à sécuriser.
Je ne savais pas du tout que c'était possible. La commande sudo le fait bien après tout, mais je ne me suis jamais vraiment posé la question du "comment ?".
Je pense qu'il est possible de crypter / décrypter un fichier à partir d'un programme de telle façon qu'il serait très difficile de retrouver l'algo utiliser dans l'exécutable. Malheureusement ce n'est pas un domaine que je maîtrise donc ce ne sont que des suppositions de ma part.Citation:
Envoyé par Metalman
Tu peux essayer de t'en tirer avec un setuid, le programme ne sera plus exécuté avec les privilèges de l'utilisateur mais avec ceux du propriétaire du fichier. Ce n'est pas une solution à recommander, du moins à mon avis.
EDIT:
Mais la première faille est de vouloir cacher quelque chose à ce point.
Selon les raisons ça peut ou non être une bonne idée.
Donc comme dis dans *TOUS* mes posts précédents :
- SetUID le programme codé qui appellera un shell
- Limiter les scripts appelés avec des comparaisons de noms de scripts pour EMPÊCHER d'autres applications d'être lancées
Et cacher un "algo" ou une "clé" pour "limiter", ça amène toujours des problèmes de stockages de clés, d'algos, etc...
La sécurité avec les chiffrements ça n'est pas du joujou.
(j'ai eu ma formation là dessus pour savoir au moins quand ne pas chiffrer et toutes les conséquences qui vont avec les chiffrements)
Et l'edit de Kwariz est en effet une excellente question.
Cela signifie qu'il faudra fournir le mot de passe de l'utilisateur visé, pas très pratique... Autant lancé l'exécutable en avec sudo dans ce cas-là... Mais si on peut lancer l'exécutable avec sudo ça signifie qu'on peut aussi lire le script (ba oui, il suffit d'être root pour avoir accès à son contenu du coup). Après un petit chmod et tout est réglé... Bref, c'est foireux cette histoire.
Je n'arrive pas à en comprendre l'intérêt non plus à vrai dire mais il doit bien avoir une bonne raison.
Non... le SetUID prends les droits du proprio de l'exécutable.... pas besoin de donner son pass ou de sudo
Depuis le man de setuid: "setuid() sets the effective user ID of the calling process."
Donc ce ne sont pas les droits du proprio de l'exécutable mais bien de celui qui lance l'exécutable. Cela n'aurait aucun sens sinon, il suffirait de lancer n'importe quelle commande (rm par exemple) qui appartiendrait à root et on peut tout supprimer ? Ce serait foireux.
Pas la fonction, celui du chmod : http://fr.wikipedia.org/wiki/Setuid
EDIT : Et c'est la même chose pour la fonction dans tous les cas...
EDIT2 : et ta dernière remarque est justement la raison pour laquelle rm n'est ni en setuid, ni en setgid
par exemple avec rm :
Tout le monde a le droit de lire et exécuter ce programme. Si je le lance, il s'exécutera avec mes droits.Code:
1
2 > ls -l /usr/bin/rm -rwxr-xr-x 1 root root 60408 Jan 27 09:28 /usr/bin/rm
En revanche avec passwdle setuid bit est positionné : si je lance passwd il s'exécutera avec les droits root (normal il doit modifier des fichiers systèmes).Code:
1
2 > ls -l /usr/bin/passwd -rwsr-xr-x 1 root shadow 51328 Feb 5 15:58 /usr/bin/passwd
Je connaissais pas du tout ! Je comprends mieux maintenant... C'est vachement dangereux ce truc ! 8O Cependant le problème reste si le fichier n'est lisible que pour le root et que l'utilisateur peut devenir root. Dans tous les cas je ne vois pas du tout à quoi ça pourrait lui servir...
Ce qu'on lui propose, mais c'est à BIEN réfléchir :
- Il créer un exécutable qui appartient à un utilisateur (non-root) qui aura le droit de lire les scripts (les scripts appartiendront donc à un utilisateur virtuel)
- Cet exécutable appartiendra à un groupe dont tous les gens, qui ont besoin d'exécuter des scripts, appartiennent (en groupes secondaires)
- Exécutable en SetUID + Autorisé pour le groupe UNIQUEMENT + Limitation des commandes passées (pour n'autoriser QUE les scripts référencés)
Le problème reste celui que kwariz soulève : quelle est la réelle raison de cacher la lecture des scripts aux utilisateurs ?
EDIT : On n'est pas obligé de SetUID avec root dans tous les cas
EDIT2 : mais attention, on propose du chmod... avec les ACL il y a peut être moyen de faire mieux...
Comme c'est la mode des petits dessins...
J'ai résumé ma proposition avec un ajout "utile" :
- Une application (le fameux wrapper C) qui servira de "proxy de scripts".
L'utilisateur virtuel sera le propriétaire, et "groupe_lecture" sera son groupe.
Le chmod 4750 permet :
- 4 => SetUID, on va devenir l'utilisateur virtuel à l'exécution
- 7 => Tous les droits pour l'utilisateur virtuel sur sa propre application
- 5 => Le groupe_lecture peut lancer cette application
- 0 => Le reste ne peut rien faire
- Les scripts, seront possédés par l'utilisateur virtuel, et auront comme groupe "groupe_ecriture". Seuls les membres de ce groupe pourront écrire dans les scripts. Le dossier de scripts sera évidemment avec les même droits.
Le chmod 1570 permet :
- 1 => StickyBit, seul le propriétaire peut supprimer le fichier (mais on peut le vider quand même il me semble... à vous d'avoir un FS à journalisation dans ce cas, ou des backups réguliers), et uniquement le proprio ! Pas le groupe.
- 5 => L'utilisateur virtuel ne pourra pas écrire dedans (ça ne sert pas tellement, mais on peut surveiller des comportements anormaux si ce droit change sans que cela n'ait été prévu)
- 7 => Le groupe_ecriture peut tout faire dessus, amis le sticky bit empêche la suppression (à vous de mettre en place un système bien organisé autour pour faire des demandes de suppression/ajout)
- 0 => Le reste ne peut rien faire
Les groupes :
- groupe_lecture contiendra tous les gens qui ont besoin d'exécuter les scripts sans les lire (bon ok, le nom est mal choisi), et pourquoi pas ceux qui les écrivent.
- groupe_ecriture contiendra uniquement ceux qui peuvent écrire les scripts
Pour le programme de "proxy de scripts", il faudra de préférence écrire en dur dedans les scripts autorisés, ou lire depuis une liste les scripts autorisés (donc liste en chmod 500 + fopen en O_RDONLY dessus), et n'exécuter QUE les scripts disponibles avec le moins d'intéractions utilisateurs possibles.
Par exemple :
./proxy_de_scripts script.sh "mes arguments"
ou
./proxy_de_scripts script.sh arg1 arg2
Et il suffira de recréer la liste d'arguments et la passer à exec.
Voilà.
Si quelqu'un a mieux, qu'il le propose.