Ik “ben momenteel bezig met penetratietesten en programmeren in Python. Ik wil gewoon weten hoe ik een Linux-commando in Python zou uitvoeren. De commandos die ik wil uitvoeren zijn:
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
Als ik gewoon print
in Python en voer het uit in de terminal. Zal het hetzelfde doen als het uitvoeren alsof je het zelf typt en op Enter drukt?
Reacties
Antwoord
U kunt os.system()
als volgt gebruiken:
import os os.system("ls")
Of in jouw geval:
os.system("echo 1 > /proc/sys/net/ipv4/ip_forward") os.system("iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080")
Beter nog, je kunt de aanroep van het subproces gebruiken, het is veiliger, krachtiger en waarschijnlijk sneller:
from subprocess import call call("echo "I like potatos"", shell=True)
Of, zonder shell aan te roepen:
call(["echo", "I like potatos"])
Als u de uitvoer wilt vastleggen, is een manier om dit te doen als volgt:
import subprocess cmd = ["echo", "I like potatos"] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) o, e = proc.communicate() print("Output: " + o.decode("ascii")) print("Error: " + e.decode("ascii")) print("code: " + str(proc.returncode))
Ik raad ten zeerste aan om een timeout
in communicate
, en ook om de uitzonderingen vast te leggen die je kunt krijgen als je het aanroept. Dit is een zeer foutgevoelige code, dus u kunt verwachten dat fouten optreden en ze dienovereenkomstig afhandelen.
https://docs.python.org/3/library/subprocess.html
Reacties
- os.system is verouderd sinds versie 2.6. Subproces is de juiste module om te gebruiken.
- @binarysubstrate, verouderd omdat het niet wordt ondersteund of niet beschikbaar is? Ik ‘ heb onlangs gewerkt aan een machine met 2.7 (niet naar keuze), en
os.system
werkt nog steeds. - Als u
subprocess.call
gebruikt zoals aanbevolen, moet u mogelijkshell=True
specificeren … zie hier - Met Python 3.4 moet de shell = True worden opgegeven, anders werkt het call-commando niet. Standaard zal de aanroep proberen een bestand te openen dat gespecificeerd is door de string, tenzij de shell = True is ingesteld. Het lijkt er ook op dat in Python 3.5 de aanroep is vervangen door run
- Generieke POSIX-code zou waarschijnlijk
decode()
moeten aanroepen met charset vanLC_CTYPE
omgevingsvariabele.
Answer
Het eerste commando schrijft gewoon naar een bestand. Je zou dat niet “uitvoeren als een shell-commando omdat python
bestanden kan lezen en ernaar kan schrijven zonder de hulp van een shell:
with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1")
Het iptables
commando is iets dat je misschien extern wilt uitvoeren. De beste manier om dit te doen is door het subproces module .
import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"])
Merk op dat deze methode ook geen gebruik maakt van een shell, wat onnodige overhead is.
Antwoord
De snelste manier:
import os os.system("your command here")
Dit is niet de meest flexibele benadering ; als je meer controle over je proces nodig hebt dan “één keer uitvoeren, tot voltooiing, en blokkeren totdat het afsluit”, dan zou je in plaats daarvan de subprocess
module moeten gebruiken.
Answer
Als algemene regel kun je beter “python-bindingen gebruiken waar mogelijk (beter vangen van uitzonderingen, naast andere voordelen).
Voor het echo
commando, is het duidelijk beter om Python te gebruiken om in het bestand te schrijven zoals voorgesteld in het antwoord van @jordanm.
Voor de iptables
commando, misschien python-iptables
( PyPi-pagina , GitHub-pagina met beschrijving en document ) zou bieden wat je nodig hebt (ik heb je specifieke commando niet gecontroleerd).
Dit zou je afhankelijk maken van een externe lib, dus je moet de voordelen afwegen. Het gebruik van subprocessen werkt, maar als je de uitvoer wilt gebruiken, “zul je het zelf moeten ontleden, en moeten omgaan met uitvoerwijzigingen in toekomstige iptables
versies.
Opmerkingen
- Een ander ding om op te merken is dat unit testing code met
subprocess
oproepen minder nuttig is. Ja, je kunt de oproepen, maar de tests moeten aannames doen over de resultaten van de externe oproepen. - Je antwoord is meer als advies. Het OP heeft specifiek gevraagd hoe hij een Linux-systeemcommando kan uitvoeren vanuit python.
- @kapad Ja, maar hij gaf ook aan waarom hij dit wilde doen en ik stelde een alternatief voor.
Antwoord
Een python-versie van je shell. Wees voorzichtig, ik heb hem niet getest.
from subprocess import run def bash(command): run(command.split()) >>> bash("find / -name null") /dev/null /sys/fs/selinux/null /sys/devices/virtual/mem/null /sys/class/mem/null /usr/lib/kbd/consoletrans/null
Reacties
- String splitsen werkt alleen voor de eenvoudige gevallen. Gebruik voor het splitsen van commandos in shell-stijl
shlex.split
Answer
Als je deze opdracht na SSH in een ander systeem wilt uitvoeren, moet je misschien de module Paramiko gebruiken. Het is erg handig.
Als de uitvoering van het commando vanaf een lokale machine moet worden uitgevoerd, zullen os-modulefuncties nuttig zijn.
Homepage: https://www.paramiko.org/
Ontwikkeling: https://github.com/paramiko/paramiko
bash
was een opgeblazen shell …os.system
bevelen het gebruik van de module.