Automatisk scanner til at finde aktive værter med Python

Vil du gerne se, hvilke IP'er der er aktive på et netværk? Vil du gerne vide, hvordan et program af denne stil udføres? I dag viser jeg dig det hvordan man laver et program i python 3, der vil scanne netværket i en række IP'er, som brugeren angiver.

Til denne opgave vil vi automatisere ping af operativsystemet.

Mulighed 1 - Enkel scanner


Jeg satte denne første mulighed, fordi den er lettere at forstå og udføre, før jeg går ind i noget mere kompliceret.

Det komplette program er som følger:

 import os import sys import platform fra datetime import datetime ip = input ("Indtast IP:") delt ip = ip.split ('.') try: red = divideret ip [0] + '.' + delt ip [1 ] + '.' + ipDivided [2] + '.' start = int (input ("Indtast startnummeret på undernet:")) end = int (input ("Indtast det nummer, hvor du vil afslutte fejningen:")) undtagen: print ("[!] Fejl") sys.exit (1) if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1" starttime = datetime.now () print ("[ * * ] Scanningen foretages fra ", rød + str (start)," til ", rød + str (slut)) for subnet i området (start, slut + 1): adresse = rød + str (subnet) respons = os .popen (ping + "" + adresse) for linje i response.readlines (): if ("ttl" i line.lower ()): print (adresse, "er aktiv") break endtime = datetime.now () time = endTime - startTime print ("[*] Scanningen varede% s"% tid) 
[color = # a9a9a9] Komplet kode [/ color]

Trin 1
Vi skal importere nogle biblioteker til vores program:

 import os import sys import platform fra datetime import datetime
[color = # a9a9a9] Biblioteker [/ color]

Forklaring af bibliotekerne

  • du: Vi har brug for det til at pinge gennem operativsystemet.
  • sys: Jeg bruger det til at afslutte programmet på grund af en fejl i brugerinputet.
  • platform: Det giver os mulighed for at kende operativsystemet, hvor vi kører programmet, dets anvendelse gør os platformuafhængige.
  • dato tid: Jeg bruger det til at vide, hvor lang tid det tager at udføre scanningen, hvis du ikke vil vide det, kan du gemme det.

Trin 2
I det følgende stykke kode beder vi brugeren om de nødvendige data, såsom værten og subnetområdet. Vi har også en prøve -og -fang -blok, som jeg stort set bruger til at afslutte programmet på en kontrolleret måde, hvis IP'en indsat af brugeren ikke er korrekt, vil den første instruktion i blokken give en fejl, og hvis jeg beder om begyndelsen og slut det indsætter ikke tal, det vil springe en fejl.

 ip = input ("Indtast IP:") delt ip = ip.split ('.') prøv: netværk = delt ip [0] + '.' + delt ip [1] + '.' + delt ip [2 ] + '.' start = int (input ("Indtast startnummeret på undernet:")) end = int (input ("Indtast det nummer, hvor du vil afslutte fejningen:")) undtagen: print ("[!] Fejl") sys.exit (1)
Jeg bruger den første sætning i prøveblokken til at oprette et netværksprefiks, som vil være nyttigt senere.

For eksempel i det følgende billede med de data, jeg indsætter, ville vi scanne for at se, om adresserne fra 192.168.0.190 til 192.168.0.199 er aktive.

Trin 3
I den næste del af koden er det eneste, jeg kontrollerer, hvilket operativsystem der bruges gennem funktionen platform.system ().

 if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1"
Dette er nødvendigt, fordi vi vil sende en enkelt pakke, og i Windows udføres instruktionen med -n og i unix med -c.

Trin 4
Dernæst vil jeg analysere følgende kodestykke:

 starttime = datetime.now () print ("[*] Scanningen udføres fra", rød + str (start), "til", rød + str (slut)) for undernet i området (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 (" [*] Scanningen varede% s "% tid)
Dette trin er, hvor vi udfører den sande funktionalitet, så før jeg starter får jeg den tilsvarende tid:
 starttid = datetime.now ()
Og vi maler en linje pr. Skærm, så brugeren ved, at scanningen udføres (og området):
 print ("[*] Scanningen foretages fra", rød + str (start), "til", rød + str (slut))
Derefter ser vi en for, som vil gå igennem området med ønskede IP -adresser, dens første instruktion sammenkæder de manglende numre til netværkspræfikset, det vil sige, hvis vi har 192.168.0. så hvis for -løkken går fra 190 til 199, første gang du indtaster adressen, vil den være 192.168.0.190, og efterhånden som den skrider frem, vil 190 blive ændret, resten beholder vi. Så får vi ping -svaret, som udføres af instruktionen:
 os.popen (ping + "" + adresse)
For at vide, om IP -adressen er aktiv, kontrollerer vi, om det svar, vi har, indeholder ordet ttl, Jeg bruger line.lower () fordi det ser ud til, at det i Linux kommer ud med små bogstaver og i Windows i store bogstaver, så vi har ingen problemer.

I den sidste del er alt, hvad jeg gør, at få tiden igen, og jeg hviler denne nye tid med den forrige for at male den tid, det tog for mit program.

Dernæst viser jeg et billede af programmets udførelse, som vi kan se, det er noget langsomt (52 sekunder for 19 adresser), det afhænger også af pc'ens strøm, men denne gang kan forbedres, hvis vi bruger tråde, så nu Jeg vil lave programmet ved hjælp af "Python -tråde".

Mulighed 2 - Gevindet Python -scanner


Nu skal vi starte et lignende program, men noget mere komplekst, da arbejdet nu vil blive delt mellem flere tråde og ikke kun vil en belastning forblive, i sidste ende vil vi se, at tiden er stærkt reduceret, så vi kan sige hvilket er en mere optimal version.

Programmet er som følger:

 import os import sys import platform import threading, delproces fra datetime import datetime IPXHILOS = 4 ip = input ("Indtast IP:") delt ip = ip.split ('.') try: red = divideret ip [0] + ' . ' + Opdelt ip [1] +'. ' + Opdelt ip [2] +'. ' start = int (input ("Indtast startnummeret på undernet:")) end = int (input ("Indtast det nummer, hvor du vil afslutte fejningen:")) undtagen: print ("[!] Fejl") 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 (subnet) respons = os.popen (ping + "" + adresse) for linje i response.readlines (): hvis ("ttl" i line.lower ()): print (adresse, "er aktiv") pause startTime = datetime .now () print ("[*] Scanningen udføres fra", netværk + str (begyndelse), "til", netværk + str (slut)) NumberIPs = end-beginning numberThreads = int ((NumberIPs / IPXHILOS)) threads = [] prøv: for i in range (numberThreads): endAux = begin + IPXTHREADS if (endAux> end): endAux = end thread = Thread (begin, endAux) thread.start () threads.append ( tråd) begyndelse = finAux undtagen Exceptio n så e: print ("[!] Fejl ved oprettelse af tråde:", e) sys.exit (2) for tråd i tråde: thread.join () endtime = datetime.now () time = endtime - starttime print ("[ *] Scanningen tog% s "% tid) 
[color = # a9a9a9] Komplet program [/ color]

Her vil jeg fortælle dig om instruktioner, der ændres og tilføjes (jeg vil ignorere de dele, der er lig med det forrige program):

Den import, vi bruger i det forrige program, er gyldig for os, vi behøver kun at tilføje følgende, som vil blive brugt til Python -trådene.

 importtråd, delproces
Jeg bruger en variabel til antallet af IP'er, som jeg vil have hver tråd til at kontrollere, så den tilføjes i starten af ​​programmet:
 IPXTHREADS = 4
Brugeranmodningen om data og kontrol af operativsystemet forbliver intakt. I dette show Jeg opretter en klasse kaldet Thread, der strækker sig fra threading.Thread, denne klasse modtager som parametre start og slutning på de adresser, som hver tråd skal arbejde med, så har jeg en køringsfunktion, som er nødvendig og skal kaldes sådan, den tager sig af at udføre arbejdet, når vi start tråden senere, for ændres ikke:
 class Thread (threading.Thread): def __init __ (self, start, end): threading.Thread .__ init __ (self) start. 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 (adresse, "er aktiv") pause
Nu skal vi forklare den del, jeg har uden for klassen Tråd.

Jeg bruger følgende instruktion til at kende antallet af IP'er, jeg har i alt, i henhold til begyndelsen og slutningen, som brugeren giver mig:

 NumberIPs = slut-start
Nu når vi ved dette, kan vi beregne antallet af tråde, som jeg skal bruge:
 numberThreads = int ((NumberIPs / IPXTHREADS))
Jeg skal bruge en liste, hvor jeg kan gemme hver tråd, så jeg senere kan få hovedtråden til at vente på, at jobbet er færdigt:
 tråde = []
Det følgende kodefragment vil oprette trådene og videregive dem til deres arbejdssektion, for dette skal vi "lege" med begyndelsen og slutningen af ​​hver tråd, derfor har jeg oprettet variablen finAux. Når tråden er oprettet, starter den med Start () og tilføjes til trådlisten.
 prøv: for i inden for rækkevidde (numberThreads): endAux = begyndelse + IPXTHREADS if (endAux> end): endAux = end thread = Thread (begin, endAux) thread.start () threads.append (thread) beginning = endAux undtagen Undtagelse som e: print ("[!] Fejl ved oprettelse af tråde:", e) sys.exit (2)
Dernæst opretter jeg en loop, hvis formål er at vente på, at trådene er færdige
 til tråd i tråde: thread.join () 
Og endelig, tiden er taget, den ville blive trukket fra den, jeg tog før start, og den vises på skærmen, ligesom det forrige program.

Hvis vi laver den samme test som før med dette program, ser vi, at det tager 6 sekunder at udføre det samme job, hvilken forskel.

BemærkTiden kan variere afhængigt af strømmen på din pc og variablen IPXHILOS, jeg tildeler den en 4, hvis du tildeler mere arbejde til hver tråd, vil det tage længere tid, hvis den har mindre arbejde, vil det være hurtigere, men pas på, at der er en grænse for antallet af tråde, vi kan oprette.

Kan vi stole på, at dette program giver os 100% af de aktive værter?Svaret er nej, da du kan blokere pinget på en vært ved at blokere ICMP -anmodninger og / eller svar, kan du være sikker på, at hvis det fortæller dig, at det er aktivt, er det det. Der er andre typer scannere, f.eks. TCP, som du kan gøre med de porte, som et operativsystem normalt lader åbne, og kombinationen af ​​TCP- og ping -scannerne vil være mere pålidelig.

Jeg efterlader dig et postnummer med de 2 koder:

codigos_ping_python.zip 1,38K 270 downloads

Kan du lide og hjælpe denne vejledning?Du kan belønne forfatteren ved at trykke på denne knap for at give ham et positivt punkt

Du vil bidrage til udviklingen af ​​hjemmesiden, at dele siden med dine venner

wave wave wave wave wave