Automatisk skanner för att hitta aktiva värdar med Python

Vill du se vilka IP -adresser som är aktiva i ett nätverk? Vill du veta hur ett program av denna stil genomförs? Idag visar jag dig hur man gör ett program i python 3 som skannar nätverket i en rad IP -adresser som användaren tillhandahåller.

För denna uppgif.webpt kommer vi att automatisera ping av operativsystemet.

Alternativ 1 - Enkel skanner


Jag lägger det här första alternativet, eftersom det är lättare att förstå och genomföra, innan jag går in i något mer komplicerat.

Det fullständiga programmet är följande:

 import os import sys importplattform från datetime import datetime ip = input ("Ange IP:") delad ip = ip.split ('.') try: red = dividerad ip [0] + '.' + delad ip [1 ] + '.' + ipDivided [2] + '.' start = int (input ("Ange startnumret för delnätet:")) end = int (input ("Ange det nummer där du vill avsluta svepet:")) utom: print ("[!] Error") sys.exit (1) if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1" starttime = datetime.now () print ("[ * * ] Skanningen görs från ", röd + str (start)," till ", röd + str (slut)) för delnät inom intervall (start, slut + 1): adress = röd + str (delnät) svar = os .popen (ping + "" + adress) för rad i response.readlines (): if ("ttl" i line.lower ()): print (adress, "är aktiv") break endtime = datetime.now () time = endTime - startTime print ("[*] Skanningen varade% s"% tid) 
[color = # a9a9a9] Komplett kod [/ color]

Steg 1
Vi måste importera några bibliotek för vårt program:

 import os import sys importplattform från datetime import datetime
[color = # a9a9a9] Bibliotek [/ color]

Förklaring till biblioteken

  • du: Vi behöver det för att pinga igenom operativsystemet.
  • sys: Jag använder den för att avsluta programmet på grund av ett fel i användarinmatningen.
  • plattform: Det tillåter oss att känna till operativsystemet där vi kör programmet, dess användning gör oss plattformsoberoende.
  • datum Tid: Jag använder den för att veta hur lång tid det tar att utföra skanningen. Om du inte vill veta det kan du spara den.

Steg 2
I följande kodbit ber vi användaren om nödvändiga data, till exempel värden och delnätintervallet. Vi har också ett försök och fånga block som jag i princip använder för att avsluta programmet på ett kontrollerat sätt, om IP: n som sätts in av användaren inte är korrekt, kommer den första instruktionen i blocket att ge ett fel, och om när jag ber om början och slutar det inte infoga siffror, det kommer att hoppa ett misstag.

 ip = input ("Ange IP:") delad ip = ip.split ('.') try: network = dividerad ip [0] + '.' + delad ip [1] + '.' + delad ip [2 ] + '.' start = int (input ("Ange startnumret för delnätet:")) end = int (input ("Ange det nummer där du vill avsluta svepet:")) utom: print ("[!] Error") sys.exit (1)
Jag använder det första uttalandet i försöksblocket för att skapa ett nätverksprefix, vilket kommer att vara användbart senare.

Till exempel i följande bild med data som jag sätter in skulle vi skanna för att se om adresserna från 192.168.0.190 till 192.168.0.199 är aktiva.

Steg 3
I nästa del av koden är det enda jag kontrollerar vilket operativsystem som används via funktionen platform.system ().

 if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1"
Detta är nödvändigt eftersom vi vill skicka ett enda paket, och i Windows görs instruktionen med -n och i unix med -c.

Steg 4
Därefter kommer jag att analysera följande kodavsnitt:

 starttime = datetime.now () print ("[*] Skanningen utförs från", röd + str (start), "till", röd + str (slut)) för delnät inom intervall (start, slut + 1) : address = network + str (subnet) response = os.popen (ping + "" + address) for line in response.readlines (): if ("ttl" in line.lower ()): print (address, "is active ") break endtime = datetime.now () time = endtime - starttime print (" [*] Skanningen varade% s "% tid)
I det här steget utför vi den sanna funktionaliteten, så innan jag börjar får jag motsvarande tid:
 starttid = datetime.now ()
Och vi målar en rad per skärm så att användaren vet att genomsökningen görs (och intervallet):
 print ("[*] Skanningen görs från", röd + str (start), "till", röd + str (slut))
Sedan ser vi en för, som kommer att gå igenom intervallet med önskade IP -adresser, dess första instruktion sammanfogar de saknade numren till nätverksprefixet, det vill säga om vi har 192.168.0. om för -slingan går från 190 till 199, första gången du anger adressen kommer den att vara 192.168.0.190 och när det fortskrider ändras 190, resten behåller vi. Då får vi ping -svaret, som utförs av instruktionen:
 os.popen (ping + "" + adress)
För att veta om IP -adressen är aktiv kontrollerar vi om svaret vi har innehåller ordet ttl, Jag använder line.lower () eftersom det verkar som om det kommer i Linux med små bokstäver och i Windows med stora bokstäver, så vi har inga problem.

I den sista delen är allt jag gör att få tiden igen, och jag vilar den här nya tiden med den förra för att måla den tid det tog för mitt program.

Därefter visar jag en bild av körningen av programmet, som vi kan se är det något långsamt (52 sekunder för 19 adresser) det beror också på datorns effekt, men den här tiden kan förbättras om vi använder trådar, så nu Jag kommer att göra programmet med hjälp av "Python -trådar".

Alternativ 2 - Gängad Python -skanner


Nu ska vi starta ett liknande program, men något mer komplext, eftersom arbetet nu kommer att delas upp på flera trådar och inte bara kommer en belastning att vara kvar, till slut kommer vi att se att tiden är kraftigt reducerad, så vi kan säga vilket är en mer optimal version.

Programmet är enligt följande:

 import os import sys import plattform import trådning, delprocess från datetime import datetime IPXHILOS = 4 ip = input ("Ange IP:") delad ip = ip.split ('.') try: red = dividerad ip [0] + ' . ' + Divided ip [1] +'. ' + Divided ip [2] +'. ' start = int (input ("Ange startnumret för delnätet:")) end = int (input ("Ange det nummer där du vill avsluta svepet:")) utom: print ("[!] Error") sys.exit (1) if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1" class Thread (threading.Thread): def __init __ ( self, start, end): threading.Thread .__ init __ (self) self.start = start self.fin = end def run (self): for subnet in range (self.start, self.fin): address = network + str (subnät) svar = os.popen (ping + "" + adress) för rad i response.readlines (): if ("ttl" i line.lower ()): print (adress, "är aktiv") bryt startTime = datetime .now () print ("[*] Skanningen utförs från", nätverk + str (början), "till", nätverk + str (slut)) NumberIPs = end-beginning numberThreads = int ((NumberIPs / IPXHILOS)) threads = [] försök: för i i intervallet (numberThreads): endAux = början + IPXTHREADS if (endAux> end): endAux = end thread = Thread (begin, endAux) thread.start () threads.append ( tråd) början = finAux utom Exceptio n så e: print ("[!] Fel vid skapande av trådar:", e) sys.exit (2) för tråd i trådar: thread.join () endtime = datetime.now () time = endtime - starttime print ("[ *] Skanningen tog% s "% tid) 
[color = # a9a9a9] Komplett program [/ color]

Här kommer jag att berätta om instruktioner som ändras och läggs till (jag kommer att ignorera delarna som är lika med föregående program):

Den import som vi använder i det föregående programmet är giltig för oss, vi behöver bara lägga till följande, som kommer att användas för Python -trådarna.

 importtråd, delprocess
Jag använder en variabel för antalet IP -adresser som jag vill att varje tråd ska kontrollera, så den läggs till i början av programmet:
 IPXTHREADS = 4
Användarförfrågan för data och kontroll av operativsystemet förblir intakt. I denna show Jag skapar en klass som heter Thread som sträcker sig från threading.Thread, denna klass får som parametrar start och slut på adresserna som varje tråd måste arbeta med, då har jag en körfunktion, som är nödvändig och måste kallas så här, den kommer att ta hand om arbetet när vi starta tråden senare, för ändras inte:
 class Thread (threading.Thread): def __init __ (self, start, end): threading.Thread .__ init __ (self) self.start = start self.fin = end def run (self): for subnet in range ( self.start, self.fin): address = network + str (subnet) response = os.popen (ping + "" + address) for line in response.readlines (): if ("ttl" in line.lower () ): print (adress, "är aktiv") paus
Nu ska vi förklara den del som jag har utanför lektionen Tråd.

Jag använder följande instruktion för att veta hur många IP -adresser jag har totalt, beroende på början och slutet som användaren ger mig:

 NumberIPs = slutstart
Nu när vi vet detta kan vi beräkna antalet trådar som jag kommer att behöva arbeta:
 numberThreads = int ((NumberIPs / IPXTHREADS))
Jag behöver en lista där jag ska lagra varje tråd, så att jag senare kan få huvudtråden att vänta tills jobbet är klart:
 trådar = []
Följande kodfragment kommer att skapa trådarna och skicka dem till deras arbetsavsnitt, för detta måste vi "spela" med början och slutet av varje tråd, det är därför jag har skapat variabeln finAux. När tråden är skapad börjar den med Start () och läggs till i trådlistan.
 försök: för i i intervallet (numberThreads): endAux = början + IPXTHREADS if (endAux> end): endAux = end thread = Thread (begin, endAux) thread.start () threads.append (thread) beginning = endAux utom Undantag som e: print ("[!] Fel vid skapande av trådar:", e) sys.exit (2)
Därefter skapar jag en slinga vars syfte är att vänta på att trådarna ska slutföras
 för tråd i trådar: thread.join () 
Och slutligen, det tar tid, den skulle subtraheras från den jag tog innan jag startade och den visas på skärmen, precis som föregående program.

Om vi ​​gör samma test som tidigare med det här programmet ser vi att det tar 6 sekunder att göra samma jobb, vilken skillnad.

NoteraTiden kan variera beroende på kraften på din dator och variabeln IPXHILOS, jag tilldelar den en 4, om du tilldelar mer arbete till varje tråd kommer det att ta längre tid, om den har mindre arbete blir det snabbare, men var försiktig så att det finns är en gräns för antalet trådar vi kan skapa.

Kan vi lita på att detta program ger oss 100% av de aktiva värdarna?Svaret är nej, eftersom du kan blockera pingen på en värd genom att blockera ICMP -förfrågningar och / eller svar, vad du kan vara säker på är att om det berättar att det är aktivt, så är det. Det finns andra typer av skannrar, till exempel TCP som du kan göra med portarna som ett operativsystem normalt lämnar öppna, och kombinationen av TCP- och ping -skannrarna blir mer pålitlig.

Jag lämnar dig en zip med de två koderna:

codigos_ping_python.zip 1.38K 270 nedladdningar

Gillade du och hjälpte denna handledning?Du kan belöna författaren genom att trycka på den här knappen för att ge honom en positiv poäng

Du kommer att bidra till utvecklingen av webbplatsen, dela sidan med dina vänner

wave wave wave wave wave