Nov 24, 2024

Wiki

Python

Aide

edit SideBar

Search

Commands


Présentation du module

Le module commands permet de travailler avec les valeurs de retour des résultats d'exécutions de fichiers (sous Unix). Ce module a été amélioré pour donner le module subprocess.

Le module commands contient trois fonctions permettant de travailler avec des commandes shell : exécution, et retour du status code.

Source : PyMOTW.

getstatusoutput()

Fonctionnement

La fonction getstatusoutput() exécute une commande shell, et renvoie son retour, ainsi que son code de sortie : stdout et stderr.

Le code de sortie est composé de 16 bits :

  • L'octet de droite contient le numéro du signal qui a tué le processus.
  • Si cet octet est nul, alors l'octet de gauche est le code de sortie (exit status) de la commande.
  • Enfin, si un fichier core a été créé, le bit de poids fort de l'octet de droite est fixé à 1.

Exemple

On suppose avoir produit le code suivant, dans le fichier exemple.py :

  from commands import *

  def run_command(cmd):
      print 'Running: " cmd
      status, text = getstatusoutput(cmd)
      exit_code = status >> 8
      signal_num = status % 256
      print 'Signal:  signal_num
      print 'Exit  :  exit_code
      print 'Core? :  bool(exit_code / 256)
      print 'Output:'
      print text
      print

  run_command('ls -l *.py')
  run_command('ls -l *.notthere')
  run_command('echo "WAITING TO BE KILLED"; read input')

This example runs 2 commands which exit normally, and a third which blocks waiting to be killed from another shell. (Don't simply use Ctrl-C as the interpreter will intercept that signal. Use ps and grep in another window to find the read process and send it a signal with kill.)

  python commands_getstatusoutput.py
  Running: "ls -l *.py"
  Signal: 0
  Exit  : 0
  Core? : False
  Output:
  -rw-r--r--   1 dhellman  dhellman  1191 Oct 21 09:41 __init__.py
  -rw-r--r--   1 dhellman  dhellman  1321 Oct 21 09:48 commands_getoutput.py
  -rw-r--r--   1 dhellman  dhellman  1265 Oct 21 09:50 commands_getstatus.py
  -rw-r--r--   1 dhellman  dhellman  1626 Oct 21 10:10 commands_getstatusoutput.py

  Running: "ls -l *.notthere"
  Signal: 0
  Exit  : 1
  Core? : False
  Output:
  ls: *.notthere: No such file or directory

  Running: "echo "WAITING TO BE KILLED"; read input"
  Signal: 1
  Exit  : 0
  Core? : False  
  Output:
  WAITING TO BE KILLED

In this example, I used "kill -HUP $PID" to kill the read process.

getoutput()

If the exit code is not useful for your application, you can use getoutput() to receive only the text output from the command.

  from commands import *

  text = getoutput('ls -l *.py')
  print 'ls -l *.py:'
  print text
  print

  text = getoutput('ls -l *.notthere')
  print 'ls -l *.py:'
  print text
  $ python commands_getoutput.py      
  ls -l *.py:
  -rw-r--r--   1 dhellman  dhellman  1191 Oct 21 09:41 __init__.py
  -rw-r--r--   1 dhellman  dhellman  1321 Oct 21 09:48 commands_getoutput.py
  -rw-r--r--   1 dhellman  dhellman  1265 Oct 21 09:50 commands_getstatus.py
  -rw-r--r--   1 dhellman  dhellman  1626 Oct 21 10:10 commands_getstatusoutput.py

  ls -l *.py:
  ls: *.notthere: No such file or directory

getstatus()

Contrary to what you might expect, getstatus() does not run a command and return the status code. Instead, it's argument is a filename which is combined with "ls -ld" to build a command to be run by getoutput(). The text output of the command is returned.

  from commands import *

  status = getstatus('commands_getstatus.py')
  print 'commands_getstatus.py:', status
  status = getstatus('notthere.py')
  print 'notthere.py:', status
  status = getstatus('$filename')
  print '$filename:', status

As you notice from the output, the $ character in the argument to the last call is escaped so the environment variable name is not expanded.

  python commands_getstatus.py
  commands_getstatus.py: -rw-r--r--   1 dhellman  dhellman  1387 Oct 21 10:19 commands_getstatus.py
  notthere.py: ls: notthere.py: No such file or directory
  $filename: ls: $filename: No such file or directory

Exemple d'utilisation

On suppose posséder une archive rar, du nom de archiveCryptee.rar, et qui est protégée par un mot de passe.

Le but, ici, est de "faire sauter" ledit mot de passe, par une attaque de type dictionnaire.

Pré-requis

Pour réaliser ce qui suit, il faut :

  • avoir de quoi créer des archives rar, et désarchiver,
  • avoir un dictionnaire de mots de passes courants.

Cela peut se faire ainsi :

  sudo aptitude install john rar unrar

Création de l'archive cryptée

On suppose posséder un fichier texte archiveCryptee.txt, que l'on va archiver avec le mot de passe wonder :

  rar a -pwonder archiveCryptee.rar archiveCryptee.txt

On rappelle que, dans ce qui précède :

  • l'option a signifie : ajouter à l'archive,
  • l'option -p signifie que l'on souhaite protéger l'archive par un mot de passe (que l'on concatène à -p, comme ci-dessus).

Pour décompresser, en connaissant le mot de passe, il suffit de taper :

  unrar x -pwonder archiveCryptee.rar

(si l'option -p n'est pas présente, le mot de passe sera demandé avant la décompression).

Décompression

On suppose maintenant ne plus se souvenir du mot de passe. On va donc tester plein de mots de passe différents, en espérant tomber sur le bon.

Pour ce faire, on suppose posséder un fichier texte contenant l'ensemble des mots de passe à tester. Par exemple, celui obtenu avec l'installation de john :

  /usr/share/john/password.lst

On utilise le fait que la commande

  unrar x -pmauvais archiveCryptee.rar

se termine par une erreur (code de sortie différent de 0), quand on passe un mauvais mot de passe en argument.

Le principe du script est alors le suivant : tant que la ligne de commande ci-dessus renvoie un code de sortie différent de 0, tester le mot de passe suivant...

  >>> from commands import *
  >>> mdp = open('/usr/share/john/password.lst','r').readlines()
  >>> for k in range(len(mdp)):
  ...    status, text = getstatusoutput('unrar x -p'\
                           + mdp[k].replace('\n','')\
                           + ' archiveCryptee.rar')
  ...    exit_code = status >> 8
  ...    if exit_code!=0:
  ...        print "echec avec : "+mdp[k]
  ...    else :
  ...        print "REUSSI : "+mdp[k]
  ...        break

En fait, ça marche pas tout à fait...

Page Actions

Recent Changes

Group & Page

Back Links