Partage
  • Partager sur Facebook
  • Partager sur Twitter

bug si pas de lecture de commande système

Sujet résolu
    7 février 2013 à 23:24:55

    Bonsoir.

    J'ai créé cette fonction:

    def thumb(path):
    
        """ Fct permettant de créer la miniature principale d'un fichier """
    
        name = path.split("/")[-1]
    
        try:
            cmd = os.popen("ffmpegthumbnailer -i \"{0}\" -o \"{1}_thumb.png\" > /dev/null".format(path, name))
            print(cmd.read())
            os.renames("{0}/{1}_thumb.png".format(os.getcwd(), name), "{0}/screens/{1}_thumb.png".format(os.getcwd(), name))
        except:
            print("Erreur lors de la génération de la miniature")
    

    Très simple, sur une distribution linux et avec le soft ffmpegthumbnailer, on créé une miniature d'une vidéo. Je fais comme ça car je n'ai pas à recoder quelque chose qui existe et qui marche.

    Seulement, j'ai un petit problème avec cette fonction: elle génère du bruit dans mon terminal. Trop de bruit quand je débugue en fait, à cause de la ligne:

    print(cmd.read())

    J'ai essayé de la supprimer, mais si je fais ça, mes miniatures ne sont plus générées correctement. Juste à cause de ça. Est-ce que vous auriez un moyen de rediriger le flux vers ailleurs que le terminal ?

    Bien à vous.


    • Partager sur Facebook
    • Partager sur Twitter
    http://maymayhem.fr/
      8 février 2013 à 13:22:32

      Deux solution :

      • Tu fais le read mais pas le print : remplace la ligne 9 par cmd.read() simplement
      • Tu peux effectivement rediriger la sortie standard. Par exemple un bout de code pour que les "print" soient redirigés dans un fichier :
      import sys
      saveout = sys.stdout            # on la conserve au cas où
      fsock = open('out.log', 'w')  # le fichier de log
      sys.stdout = fsock                 # a partir de là tous les 'print' seront écris dans le fichier
      
      • Partager sur Facebook
      • Partager sur Twitter
        8 février 2013 à 13:26:12

        Ou bien utiliser subprocess.Popen au lieu de os.popen (qui est deprecated), ce qui te permettra de gérer finement les flux d'IO du processus fils.

        • Partager sur Facebook
        • Partager sur Twitter
        Zeste de Savoir, le site qui en a dans le citron !
          8 février 2013 à 22:38:46

          En effet, enlever le print marche :)

          Nohar, quel est l'avantage d'utiliser subprocess par rapport au module os ? (Mis à part que os soit deprecated)

          • Partager sur Facebook
          • Partager sur Twitter
          http://maymayhem.fr/
            9 février 2013 à 10:14:33

            djipey a écrit:

            En effet, enlever le print marche :)

            Nohar, quel est l'avantage d'utiliser subprocess par rapport au module os ? (Mis à part que os soit deprecated)

            D'abord la sécurité. Par exemple :

            #!/usr/bin/env python3
            from sys import argv
            from os import popen
            print(popen("echo {}".format(argv[-1])).read())
            
            sudo monscript.py '`/bin/sh`'
            

            Si le programme s'exécute avec les droits root sans taper de mot de passe (en set-euid ou bien avec une entrée spéciale dans /etc/sudoers, ce qui est assez courant), je viens de faire une escalade de privilèges…

            Démonstration (commentée) :

            16:52 arnaud@umad(~)% whoami
            arnaud
            16:53 arnaud@umad(~)% sudo python3 -c 'from os import popen; from sys import argv; print(popen("echo {}".format(argv[-1])).read())' '`/bin/sh`'
            # À ce niveau, le programme "freeze" : je viens d'ouvrir un shell, je peux donc exécuter 
            # la commande que je veux. Ici, je vais simplement vérifier que l'exploit a fonctionné.
            whoami 
            # Entrée pour valider la commande, puis Ctrl + D pour quitter le shell
            # La commande "echo" dans l'appel à os.popen va maintenant afficher la sortie de "/bin/sh" 
            # ici, elle affiche le résultat de "whoami"
            root 
            # Bingo ! Je suis le maître du monde.
            

            J'aurais aussi pu cheater sur la variable d'environnement PATH, pour que "echo" exécute un shell ou autre chose. Quand tu exécutes un programme avec subprocess.Popen, tu peux facilement éviter ce genre de gag (en settant shell=False).

            Et puis subprocess te donne un contrôle beaucoup plus fin de l'exécution, des entrées/sorties, des erreurs, etc..

            -
            Edité par nohar 9 février 2013 à 17:52:36

            • Partager sur Facebook
            • Partager sur Twitter
            Zeste de Savoir, le site qui en a dans le citron !
              9 février 2013 à 18:55:51

              je ne comprends pas bien comment utiliser cet exploit.

              Chez moi:

              ╭─djipey-laptop ~  18:50:41
              ╰─$ sudo python3 -c 'from os import popen; from sys import argv; print(popen("echo {}".format(argv[-1])).read())' '`/bin/sh`'
              sh-4.2$ whoami
              sh-4.2$ exit
              [sudo] password for djipey: 
              sh-4.2# whoami
              sh-4.2# exit
              root
              

              Mon shell m'a demandé mon password, ce qui me paraît plutôt normal, mais je ne comprends pas bien ce que tu fais, donc je ne suis pas sûr. D'autre part, est-ce que ça concerne mon programme, ce problème de sécurité ? Parce que l'utilisateur final n'est pas sensé modifié les sources, non ? Et puis il ne pourrait pas, si elles ne sont pas dans son home.

              Est-ce que tu pourrais m'expliquer plus en profondeur s'il te plait ?

              • Partager sur Facebook
              • Partager sur Twitter
              http://maymayhem.fr/
                9 février 2013 à 19:33:17

                C'est une faille si le programme a besoin d'etre exécuté par n'importe qui mais qu'il doit utiliser les droits root. C'est le cas de beaucoup de scripts système appartenant a root et s' exécutant avec le flag set-euid ou des programmes déclarés dans /etc/sudoers avec l'option qui permet de les lancer avec les droits root sans que sudo ne leur demande un mot de passe. Dans ce cas, cette faille permet à virtuellement n'importe qui d'ouvrir un shell root sans avoir à taper le moindre mot de passe.

                Pas besoin de modifier la source puisque le '`/bin/sh`' est exécuté de façon prioritaire (en gros tu peux l'injecter n'importe où quelle que soit la commande de base, alors que dans un subprocess.Popen elle est inoffensive).

                Alors dans le contexte de ton programme le problème ne se pose peut être pas, mais c'est quand même un truc qu'il est important de garder a l'esprit : tu ne sais jamais si ton script ne sera pas un jour installé en seteuid chez quelqu'un.

                -
                Edité par nohar 10 février 2013 à 14:05:42

                • Partager sur Facebook
                • Partager sur Twitter
                Zeste de Savoir, le site qui en a dans le citron !
                  9 février 2013 à 20:20:14

                  Note que ce n'est pas la seule faille induite par les fonctions os.system et os.popen. Le fait qu'elles exécutent leurs arguments dans un shell ouvre la porte à beaucoup d'effets de bord potentiellement dangereux, comme par exemple la corruption de la variable PATH.

                  D'une façon générale, si tu as besoin d'exécuter un programme externe à ton script, moins tu reposes sur l'environnement, mieux c'est.

                  -
                  Edité par nohar 10 février 2013 à 14:06:26

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Zeste de Savoir, le site qui en a dans le citron !
                    10 février 2013 à 21:29:04

                    Merci à toi. Je vais changer ça.
                    • Partager sur Facebook
                    • Partager sur Twitter
                    http://maymayhem.fr/

                    bug si pas de lecture de commande système

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown