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 ?
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
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..
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 ?
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.
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.
× 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.