Automatische scanner om actieve hosts te vinden met Python

Wil je zien welke IP's actief zijn op een netwerk? Wilt u weten hoe een programma van deze stijl wordt uitgevoerd? Nou vandaag laat ik het je zien hoe maak je een programma in python 3 dat het netwerk scant? in een reeks IP's die de gebruiker verstrekt.

Voor deze taak gaan we de ping van het besturingssysteem automatiseren.

Optie 1 - Eenvoudige scanner


Ik plaats deze eerste optie, omdat het gemakkelijker te begrijpen en uit te voeren is, voordat ik in iets ingewikkelders stap.

Het volledige programma is als volgt:

 import os import sys import platform van datetime import datetime ip = input ("Enter the IP:") gedeeld ip = ip.split ('.') probeer: rood = gedeeld ip [0] + '.' + gedeeld ip [1 ] + ' . '+ ipDivided [2] +'. ' start = int (invoer ("Voer het startnummer van het subnet in:")) end = int (invoer ("Voer het nummer in waar u de sweep wilt beëindigen:")) behalve: print ("[!] Error") sys.exit (1) if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1" starttime = datetime.now () print ("[ * ] De scan wordt gemaakt van ", red + str (start)," tot ", red + str (end)) voor subnet in bereik (start, end + 1): adres = rood + str (subnet) response = os .popen (ping + "" + adres) voor regel in response.readlines (): if ("ttl" in line.lower ()): print (adres, "is actief") break endtime = datetime.now () tijd = endTime - startTime print ("[*] De scan duurde% s"% tijd) 
[kleur = # a9a9a9] Volledige code [/ kleur]

Stap 1
We moeten enkele bibliotheken importeren voor ons programma:

 import os import sys import platform van datetime import datetime
[kleur = # a9a9a9] Bibliotheken [/ kleur]

Uitleg van de bibliotheken

  • jij: We hebben het nodig om door het besturingssysteem te pingen.
  • sys: Ik gebruik het om het programma te beëindigen vanwege een fout in de gebruikersinvoer.
  • platform: Het stelt ons in staat om het besturingssysteem te kennen waarop we het programma uitvoeren, het gebruik ervan maakt ons platformonafhankelijk.
  • datum Tijd: Ik gebruik het om te weten hoe lang het duurt om de scan uit te voeren. Als je het niet wilt weten, kun je het opslaan.

Stap 2
In het volgende stukje code vragen we de gebruiker om de benodigde gegevens, zoals de host en het subnetbereik. We hebben ook een try-and-catch-blok dat ik in principe gebruik om het programma op een gecontroleerde manier te beëindigen, als het door de gebruiker ingevoerde IP-adres niet correct is, geeft de eerste instructie van het blok een foutmelding, en als er om het begin wordt gevraagd en einde het voegt geen nummers in, het zal een fout maken.

 ip = invoer ("Enter the IP:") gedeeld ip = ip.split ('.') probeer: netwerk = gedeeld ip [0] + '.' + gedeeld ip [1] + '.' + gedeeld ip [2 ] + '. ' start = int (invoer ("Voer het startnummer van het subnet in:")) end = int (invoer ("Voer het nummer in waar u de sweep wilt beëindigen:")) behalve: print ("[!] Error") sys.exit (1)
Ik gebruik de eerste instructie in het try-blok om een ​​netwerkvoorvoegsel te maken, wat later nuttig zal zijn.

In de volgende afbeelding met de gegevens die ik invoeg, zouden we bijvoorbeeld scannen om te zien of de adressen van 192.168.0.190 tot 192.168.0.199 actief zijn.

Stap 3
In het volgende deel van de code controleer ik alleen welk besturingssysteem wordt gebruikt via de functie platform.systeem ().

 if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1"
Dit is nodig omdat we een enkel pakket willen versturen, en in Windows gebeurt de instructie met -n en in unix met -c.

Stap 4
Vervolgens zal ik het volgende codefragment analyseren:

 starttime = datetime.now () print ("[*] De scan wordt uitgevoerd vanaf", rood + str (start), "to", rood + str (end)) voor subnet binnen bereik (start, einde + 1) : adres = netwerk + str (subnet) response = os.popen (ping + "" + adres) voor regel in response.readlines (): if ("ttl" in line.lower ()): print (adres, "is actief ") pauze eindtijd = datetime.now () tijd = eindtijd - starttijd print (" [*] De scan duurde% s "% tijd)
In deze stap voeren we de echte functionaliteit uit, dus voordat ik begin, krijg ik de bijbehorende tijd:
 starttijd = datumtijd.nu ()
En we schilderen een lijn per scherm zodat de gebruiker weet dat de scan wordt gedaan (en het bereik):
 print ("[*] De scan wordt gemaakt van", rood + str (start), "to", rood + str (end))
Dan zien we een for, dat door het bereik van gewenste IP-adressen gaat, de eerste instructie voegt de ontbrekende nummers samen met het netwerkvoorvoegsel, dat wil zeggen, als we 192.168.0 hebben. als de for-lus dan van 190 naar 199 gaat, zal de eerste keer dat u het adres invoert 192.168.0.190 zijn en naarmate het vordert, zal de 190 worden gewijzigd, de rest houden we. Dan krijgen we de ping-respons, die wordt uitgevoerd door de instructie:
 os.popen (ping + "" + adres)
Om te weten of het IP actief is, zullen we controleren of het antwoord dat we hebben het woord bevat ttl, Ik gebruik lijn.lager () omdat het lijkt dat het in Linux in kleine letters en in Windows in hoofdletters uitkomt, dus we hebben geen problemen.

In het laatste deel is alles wat ik doe weer de tijd krijgen, en ik rust deze nieuwe tijd uit met de vorige om de tijd te schilderen die nodig was voor mijn programma.

Vervolgens laat ik een afbeelding zien van de uitvoering van het programma, zoals we kunnen zien, is het wat traag (52 seconden voor 19 adressen) het hangt ook af van de kracht van de pc, maar deze keer kan worden verbeterd als we threads gebruiken, dus nu Ik zal het programma maken met behulp van de " Python threads ".

Optie 2 - Python-scanner met schroefdraad


Nu gaan we een soortgelijk programma starten, maar iets ingewikkelder, omdat het werk nu over verschillende threads wordt verdeeld en er niet alleen één lading overblijft, uiteindelijk zullen we zien dat de tijd aanzienlijk wordt verkort, dus we kunnen zeggen wat een meer optimale versie is.

Het programma is als volgt:

 import os import sys import platform import threading, subproces van datetime import datetime IPXHILOS = 4 ip = invoer ("Enter the IP:") gedeeld ip = ip.split ('.') probeer: rood = gedeeld ip [0] + ' .' + Verdeeld ip [1] + '.' + Verdeeld ip [2] + '.' start = int (invoer ("Voer het startnummer van het subnet in:")) end = int (invoer ("Voer het nummer in waar u de sweep wilt beëindigen:")) behalve: 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): voor subnet binnen bereik (self.start, self.fin): adres = netwerk + str (subnet) response = os.popen (ping + "" + adres) voor regel in response.readlines (): if ("ttl" in line.lower ()): print (adres, "is actief") break startTime = datetime .now () print ("[*] De scan wordt uitgevoerd vanaf", netwerk + str (begin), "naar", netwerk + str (eind)) NumberIPs = end-begin numberThreads = int ((NumberIPs / IPXHILOS) ) threads = [] probeer: voor i binnen bereik (numberThreads): endAux = begin + IPXTHREADS if (endAux> end): endAux = end thread = Thread (begin, endAux) thread.start () threads.append ( thread) begin = finAux behalve Exceptio n so e: print ("[!] Fout bij het maken van threads:", e) sys.exit (2) voor thread in threads: thread.join () endtime = datetime.now () time = endtime - starttime print ("[ *] De scan duurde% s "% tijd) 
[kleur = # a9a9a9] Compleet programma [/ kleur]

Hier ga ik je vertellen over instructies die veranderen en worden toegevoegd (ik ga de delen negeren die gelijk zijn aan het vorige programma):

De imports die we in het vorige programma gebruiken, zijn geldig voor ons, we hoeven alleen het volgende toe te voegen, dat zal worden gebruikt voor de Python-threads.

 import threading, subproces
Ik gebruik een variabele voor het aantal IP's dat ik elke thread wil laten controleren, dus deze wordt aan het begin van het programma toegevoegd:
 IPXTHREADS = 4
Het gebruikersverzoek om gegevens en de controle van het besturingssysteem blijven intact. In deze show Ik maak een klasse met de naam Thread die zich uitstrekt van threading.Thread, deze klasse ontvangt als parameters het begin en einde van de adressen waarmee elke thread zal moeten werken, dan heb ik een run-functie, die nodig is en zo moet worden aangeroepen, deze zal ervoor zorgen dat het werk wordt gedaan wanneer we start de thread later, de for verandert niet:
 class Thread (threading.Thread): def __init __ (self, start, end): threading.Thread .__ init __ (self) self.start = start self.fin = end def run (self): voor subnet in bereik ( self.start , self.fin): adres = netwerk + str (subnet) response = os.popen (ping + "" + adres) voor regel in response.readlines (): if ("ttl" in line.lower () ): print (adres, "is actief") break
Nu gaan we het deel uitleggen dat ik buiten de les heb Draad.

Ik gebruik de volgende instructie om het aantal IP's te kennen dat ik in totaal heb, volgens het begin en het einde dat de gebruiker me geeft:

 NumberIPs = eind-start
Als we dit eenmaal weten, kunnen we het aantal threads berekenen dat ik nodig heb om te werken:
 numberThreads = int ((NumberIPs / IPXTHREADS))
Ik heb een lijst nodig waar ik elke thread moet opslaan, zodat ik later de hoofdthread kan laten wachten tot de taak is voltooid:
 draden = []
Het volgende codefragment gaat de threads maken en hun werksectie doorgeven, hiervoor moeten we "spelen" met het begin en einde van elke thread, daarom heb ik de variabele finAux gemaakt. Zodra de thread is gemaakt, begint deze met begin () en wordt toegevoegd aan de draadlijst.
 probeer: voor i binnen bereik (numberThreads): endAux = begin + IPXTHREADS if (endAux> end): endAux = end thread = Thread (begin, endAux) thread.start () threads.append (thread) begin = endAux behalve uitzondering als e: print ("[!] Fout bij het maken van threads:", e) sys.exit (2)
Vervolgens maak ik een lus waarvan het doel is om te wachten tot de threads zijn voltooid
 voor draad in draden: thread.join () 
En tot slot, de tijd die nodig is, wordt afgetrokken van de tijd die ik nam voordat ik begon en het wordt op het scherm weergegeven, net als het vorige programma.

Als we met dit programma dezelfde test doen als voorheen, zien we dat het 6 seconden duurt om hetzelfde werk te doen, wat een verschil.

OpmerkingDe tijd kan variëren afhankelijk van het vermogen van uw pc en de variabele IPXHILOS, ik wijs het een 4 toe, als u meer werk aan elke thread toewijst, duurt het langer, als het minder werk heeft, zal het sneller zijn, maar wees voorzichtig dat er is een limiet op het aantal threads dat we kunnen maken.

Kunnen we erop vertrouwen dat dit programma ons 100% van de actieve hosts geeft?Het antwoord is nee, aangezien je de ping op een host kunt blokkeren door ICMP-verzoeken en/of -reacties te blokkeren, kun je er zeker van zijn dat als het je vertelt dat het actief is, het dat ook is. Er zijn andere soorten scanners, zoals TCP die u kunt gebruiken met de poorten die een besturingssysteem normaal open laat, en de combinatie van de TCP- en ping-scanners zal betrouwbaarder zijn.

Ik laat je een zip met de 2 codes:

codigos_ping_python.zip 1.38K 270 downloads

Vond je deze Tutorial leuk en heb je eraan geholpen?Je kunt de auteur belonen door op deze knop te drukken om hem een ​​positief punt te geven

U zal helpen de ontwikkeling van de site, het delen van de pagina met je vrienden

wave wave wave wave wave