Executer sudo dans un programme c++

Version imprimable

  • 04/10/2012, 14h27
    ternel
    D'une manière générale, la gestion des droits n'est pas l'affaire du programme, mais de l'admin qui l'a installé.

    Ce n'est pas une bidouille quelconque dans le code qui sera valable, aussi "belle" soit-elle.
  • 04/10/2012, 14h29
    Obsidian
    Citation:

    Envoyé par Emmanuel Deloget Voir le message
    Une autre solution serait de mettre l'owner/group à root:root et de rajouter le bit setuid sur le programme - de cette manière, il n'aura pas besoin de faire de sudo.

    C'est ce que l'on a dit plus haut, mais j'aimerais être sûr que c'est parfaitement justifié avant de lui faire prendre l'habitude d'y recourir (même si c'est toujours mieux qu'un « system("sudo"); »).

    Si c'était un tout petit utilitaire console, à la limite, mais il parle d'une application graphique avec des boutons, etc. qui s'appuie probablement elle-même sur un framework particulier pour les générer facilement. Lancer tout cela sous root de manière systématique et transparente, ça me dérange un peu.
  • 05/10/2012, 12h01
    Emmanuel Deloget
    Citation:

    Envoyé par leternel Voir le message
    D'une manière générale, la gestion des droits n'est pas l'affaire du programme, mais de l'admin qui l'a installé.

    Ce n'est pas une bidouille quelconque dans le code qui sera valable, aussi "belle" soit-elle.

    C'est à la fois vrai, à la fois faux. Si c'était complètement vrai alors le programme sudo n'aurait pas de fichier de configuration : c'est bien le programme qui, une fois sa configuration lue, décide quoi faire (même si le fichier en question est défini par l'administrateur, c'est le programme qui prends ses décisions). Mais en même temps, sudo (et les programmes/mécanismes similaires sur d'autres OS, telle l'impersonnation sur Windows) fait un peu figure d'exception.

    Citation:

    Envoyé par Obsidian Voir le message
    C'est ce que l'on a dit plus haut, mais j'aimerais être sûr que c'est parfaitement justifié avant de lui faire prendre l'habitude d'y recourir (même si c'est toujours mieux qu'un « system("sudo"); »).

    Si c'était un tout petit utilitaire console, à la limite, mais il parle d'une application graphique avec des boutons, etc. qui s'appuie probablement elle-même sur un framework particulier pour les générer facilement. Lancer tout cela sous root de manière systématique et transparente, ça me dérange un peu.

    Au final, il faut savoir ce que tu veux :)

    Si tu distribuait ton programme, ça serait un gros NON tout de suite. La plupart des framework graphiques sont trop important et cachent de nombreux problèmes de sécurité (buffer overflow exploitables, etc...). Mais si tu le garde pour toi uniquement, alors tu as cette possibilité - parce qu'utiliser un vecteur d'attaque ne peut se faire que si le vecteur d'attaque est connu, et en le gardant pour toi, tu n'a aucune chance qu'un attaquant puisse le découvrir.

    Tu peut en outre conditionner l'exécution du programme, en testant l'uid et le gid de celui qui lance le programme (un process possède un uid, un gid, un euid (effective uid) et un egid (effective gid)).

    Code:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <unistd.h>
    #include <stdio.h>
    #include <sys/types.h>
     
    int main()
    {
    	uid_t uid, euid;
    	gid_t gid, egid;
     
    	uid = getuid();
    	euid = geteuid();
     
    	gid = getgid();
    	egid = getegid();
     
    	printf("uid = %d ; euid = %d\ngid = %d ; egid = %d\n", 
    		uid, euid, gid, egid);
     
    	return 0;
    }


    Code:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    $ gcc -o getuid getuid.c
    $ ls -l
    -rwxr-xr-x 1 edt  edt  7364 oct.   5 11:52 getuid*
    -rw-r--r-- 1 edt  edt   286 oct.   5 11:52 getuid.c
    $ ./getuid
    uid = 2039 ; euid = 2039
    gid = 2039 ; egid = 2039
    $ sudo su
    # chown root:root getuid
    # chmod +s getgid
    # exit
    $ ls -l
    -rwsr-sr-x 1 root root 7364 oct.   5 11:52 getuid*
    -rw-r--r-- 1 edt  edt   286 oct.   5 11:52 getuid.c
    $ ./getuid
    uid = 2039 ; euid = 0
    gid = 2039 ; egid = 0


    Bref, en testant l'uid et le gid du lanceur du programme, tu peux très simplement restreindre l'utilisation de ton programme, dès les premières lignes de main(), et donc priver un pirate de la possibilité d'exécuter ton programme (sauf s'il parvient à le lancer depuis ton compte, auquel cas, il peut l'exécuter comme s'il était toi).
  • 05/10/2012, 13h19
    Obsidian
    Citation:

    Envoyé par Emmanuel Deloget Voir le message
    Si tu distribuait ton programme, ça serait un gros NON tout de suite. La plupart des framework graphiques sont trop important et cachent de nombreux problèmes de sécurité (buffer overflow exploitables, etc...).

    Je crois qu'on voit les choses de la même façon.

    Citation:

    Mais si tu le garde pour toi uniquement, alors tu as cette possibilité - parce qu'utiliser un vecteur d'attaque ne peut se faire que si le vecteur d'attaque est connu, et en le gardant pour toi, tu n'a aucune chance qu'un attaquant puisse le découvrir.
    Mouais, je ne tablerais pas trop là-dessus. Si j'ai envie d'écrire un rootkit, il me suffit de lancer un « find » à la racine « / » cherchant les fichiers ordinaires disposant à la fois du bit w pour l'utilisateur en cours et du bit s. Ça se fait en une ligne que je tairai volontairement. Si j'en trouve un, il suffit d'écrire dedans pour gagner l'identité de la victime. Et comme ces bits sont généralement utilisés justement pour passer root, un chmod mal écrit suffit à introduire une faille.

    Cela dit, ça reste quand même la manière la plus propre de le faire.

    Citation:

    Bref, en testant l'uid et le gid du lanceur du programme, tu peux très simplement restreindre l'utilisation de ton programme, dès les premières lignes de main(), et donc priver un pirate de la possibilité d'exécuter ton programme (sauf s'il parvient à le lancer depuis ton compte, auquel cas, il peut l'exécuter comme s'il était toi).
    Moi, sous Linux, j'utilise plutôt les capabilities, qui me permettent ensuite de redescendre de root à l'utilisateur normal tout en conservant des pouvoirs sur certains domaines prédéfinis, comme CAP_NET_BIND_SERVICE qui permet de continuer à utiliser les ports réseau inférieurs à 1024 même en tant qu'utilisateur ordinaire. Pour configurer les interfaces, il suffit d'obtenir CAP_NET_ADMIN. Mais on est sous Mac OS X.

    Ce que je veux dire ici, c'est qu'un tel système, même s'il est basé sur Unix pour l'exécution des softs, s'appuie massivement sur son interface graphique et sur le framework des couches supérieures et qu'en principe, on demande à l'utilisateur si on doit vraiment faire telle ou telle action. Par exemple : « accéder aux données de géolocalisation ». Et si l'on veut faire un programme qui sera installé durablement, même si ce n'est que pour soi, autant se renseigner sur les méthodes en usage sur le système cible.

    GNOME, qui prend Mac OS comme modèle, propose déjà « pkexec » qui est un sudo graphique. Mais il y a aussi des modes spéciaux avec des curseurs à glissières permettant de « déverrouiller » certaines parties des applications, etc.

    Pour Mac OS, je pense qu'il doit y avoir derrière le lien que je lui ai donné la manière « officielle » de demander des droits au système qui, lui même, va poser à la question à l'utilisateur et lui proposer de « toujours l'autoriser », etc. L'avantage est que le système peut ensuite facilement révoquer ces permissions, soit sur demande explicite, soit automatiquement au vu d'informations nouvelles, comme la publication d'une liste de failles, etc.
  • 14/10/2012, 15h00
    Catskan
    Bonjour à tous,

    Tout d'abord, veuillez m'excuser pour ce message si tardif mais j'ai eu pas mal de boulot pour mes études alors difficile d'avoir du temps pour moi ;).
    Ayant lu vos réponses, pour lesquelles je vous remercie grandement, je pense abandonné cette idée de programme. Bien trop compliqué pour le moment de gérer toutes les permissions et tout ça (Je suis encore assez débutant dans la programmation et j'ai un peu de mal).
    Je garde ce topic précieusement qui m'être utile dans un futur programme :).

    Je vous en remercie encore d'avance :).