Jag studerar för närvarande penetrationstest och Python-programmering. Jag vill bara veta hur jag skulle gå till med att köra ett Linux-kommando i Python. Kommandona jag vill utföra är:
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
Om jag bara använder print
i Python och kör det i terminalen kommer det att göra samma sak som att köra det som om du själv skrev det och tryck Enter ?
Kommentarer
Svar
Du kan använda os.system()
, så här:
import os os.system("ls")
Eller i ditt fall:
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")
Ännu bättre, du kan använda underprocessens samtal, det är säkrare, kraftfullare och troligtvis snabbare:
from subprocess import call call("echo "I like potatos"", shell=True)
Eller utan att anropa skal:
call(["echo", "I like potatos"])
Om du vill fånga utdata är ett sätt att göra det så här:
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))
Jag rekommenderar att du ställer in en timeout
i communicate
, och även för att fånga de undantag du kan få när du ringer till det. Detta är en mycket felbenägen kod, så du kan förvänta dig att fel inträffar och hantera dem i enlighet därmed.
https://docs.python.org/3/library/subprocess.html
Kommentarer
- os.system har upphört sedan version 2.6. Delprocess är rätt modul att använda.
- @binarysubstrate, utfas som inte stöds eller inte tillgängligt? Jag ’ har nyligen arbetat på maskin med 2,7 (inte av val) och
os.system
fungerar fortfarande. - Om du använder
subprocess.call
som rekommenderat kan du behöva angeshell=True
… se här - Med Python 3.4 måste shell = True anges annars kommer kommandot call inte att fungera. Som standard försöker samtalet öppna en fil som anges av strängen såvida inte shell = True är inställt. Det ser också ut som att i Python 3.5-samtal ersätts med körning
- Generisk POSIX-kod borde troligen ringa
decode()
med teckenuppsättning frånLC_CTYPE
miljövariabel.
Svar
Det första kommandot skriver helt enkelt till en fil. Du skulle inte köra det som ett skalkommando eftersom python
kan läsa och skriva till filer utan hjälp av ett skal:
with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1")
iptables
-kommandot är något du kanske vill utföra externt. Det bästa sättet att göra detta är att använda underprocessmodul .
import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"])
Observera att den här metoden inte heller använder ett skal, vilket är onödigt overhead.
Svar
Det snabbaste sättet:
import os os.system("your command here")
Detta är inte det mest flexibla tillvägagångssättet ; om du behöver mer kontroll över din process än att ”köra den en gång, till slutförande och blockera tills den går ut”, ska du istället använda subprocess
-modulen.
Svar
Som en allmän regel skulle du bättre använda pythonbindningar när det är möjligt (bättre undantagsfångning, bland andra fördelar.)
För echo
-kommandot är det uppenbarligen bättre att använda python för att skriva i filen som föreslås i @jordanms svar.
För iptables
-kommando, kanske python-iptables
( PyPi-sida , GitHub-sida med beskrivning och dokument ) skulle ge det du behöver (jag kollade inte ditt specifika kommando).
Detta skulle göra att du är beroende av en extern lib, så du måste väga fördelarna. Att använda delprocess fungerar, men om du vill använda utdata måste du analysera den själv och hantera utdataändringar i framtida iptables
-versioner.
Kommentarer
- En annan sak att notera är att enhetstestkod med
subprocess
samtal är mindre användbar. Ja, du kan spotta ut samtal, men testerna måste göra antaganden om resultaten på de externa samtalen. - Ditt svar är mer som råd. OP har specifikt frågat hur han kan köra ett linux-systemkommando från python.
- @kapad Ja, men han specificerade också varför han ville göra det och jag föreslog ett alternativ.
Svar
En pythonversion av ditt skal. Var försiktig, jag har inte testat den.
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
Kommentarer
- Strängdelning fungerar bara för enkla fall. För kommandosplitning i skalstil använder du
shlex.split
Svar
Om du vill utföra detta kommando i något annat system efter SSH kan du behöva använda modulen med namnet Paramiko. Det är väldigt användbart.
Om kommandokörningen måste göras från en lokal maskin kommer OS-modulfunktioner att vara till hjälp.
Hemsida: https://www.paramiko.org/
Utveckling: https://github.com/paramiko/paramiko
bash
var ett uppblåst skal …os.system
rekommenderar att du användersubprocess
-modul.