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.
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 :
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.
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
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
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.
Pour réaliser ce qui suit, il faut :
Cela peut se faire ainsi :
sudo aptitude install john rar unrar
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 :
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).
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...