Scanner automatico per trovare host attivi con Python

Vuoi vedere quali IP sono attivi su una rete? Vuoi sapere come si svolge un programma di questo stile? Bene oggi te lo mostro come creare un programma in python 3 che analizzerà la rete in una gamma di IP forniti dall'utente.

Per questo compito automatizzeremo il ping del sistema operativo.

opzione 1 - Scanner semplice


Metto questa prima opzione, perché è più facile da capire e da realizzare, prima di addentrarci in qualcosa di più complicato.

Il programma completo è il seguente:

 import os import sys import platform from datetime import datetime ip = input ("Inserisci l'IP:") diviso ip = ip.split ('.') try: rosso = diviso ip [0] + '.' + diviso ip [1 ] + ' . '+ ipDivid [2] +'. ' start = int (input ("Inserisci il numero iniziale della sottorete:")) end = int (input ("Inserisci il numero in cui vuoi terminare lo sweep:")) tranne: print ("[!] Error" ) sys.exit (1) if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1" starttime = datetime.now () print ("[ * ] La scansione viene eseguita da ", rosso + str (inizio)," a ", rosso + str (fine)) per la sottorete nell'intervallo (inizio, fine + 1): indirizzo = rosso + str (sottorete) risposta = 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 ("[*] La scansione è durata% s"% tempo) 
[color = # a9a9a9] Codice completo [/ color]

Passo 1
Abbiamo bisogno di importare alcune librerie, per il nostro programma:

 import os import sys import platform from datetime import datetime
[color = # a9a9a9] Librerie [/ color]

Spiegazione delle biblioteche

  • tu: Ne abbiamo bisogno per eseguire il ping attraverso il sistema operativo.
  • sistema: Lo uso per terminare il programma a causa di un errore nell'input dell'utente.
  • piattaforma: Ci permette di conoscere il sistema operativo in cui eseguiamo il programma, il suo utilizzo ci rende indipendenti dalla piattaforma.
  • appuntamento: Lo uso per sapere il tempo necessario per eseguire la scansione, se non vuoi saperlo puoi salvarlo.

Passo 2
Nel seguente pezzo di codice chiediamo all'utente i dati necessari, come l'host e l'intervallo di sottorete. Abbiamo anche un blocco try and catch che sostanzialmente utilizzo per terminare il programma in modo controllato, se l'IP inserito dall'utente non è corretto, la prima istruzione del blocco darà un errore, e se alla richiesta dell'inizio e alla fine non inserisce numeri, salterà un errore.

 ip = input ("Inserisci l'IP:") ip diviso = ip.split ('.') try: network = ip diviso [0] + '.' + ip diviso [1] + '.' + ip diviso [2 ] + '. ' start = int (input ("Inserisci il numero iniziale della sottorete:")) end = int (input ("Inserisci il numero in cui vuoi terminare lo sweep:")) tranne: print ("[!] Error" ) sys.exit (1)
Uso la prima istruzione nel blocco try per creare un prefisso di rete, che sarà utile in seguito.

Ad esempio nell'immagine seguente con i dati che inserisco faremmo una scansione per vedere se gli indirizzi da 192.168.0.190 a 192.168.0.199 sono attivi.

Passaggio 3
Nella parte successiva del codice l'unica cosa che controllo è quale sistema operativo viene utilizzato attraverso la funzione piattaforma.sistema ().

 if (platform.system() == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1"
Ciò è necessario perché vogliamo inviare un singolo pacchetto e in Windows l'istruzione viene eseguita con -n e in unix con -c.

Passaggio 4
Successivamente analizzerò il seguente frammento di codice:

 starttime = datetime.now () print ("[*] La scansione viene eseguita da", rosso + str (inizio), "a", rosso + str (fine)) per la sottorete nell'intervallo (inizio, fine + 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 (" [*] La scansione è durata% s "% tempo)
Questo passaggio è dove eseguiamo la vera funzionalità, quindi prima di iniziare ottengo il tempo corrispondente:
 ora di inizio = datetime.now ()
E dipingiamo una linea per schermata in modo che l'utente sappia che la scansione è stata eseguita (e l'intervallo):
 print ("[*] La scansione è in corso da", red + str (inizio), "a", red + str (fine))
Quindi vediamo un for, che passerà attraverso l'intervallo di indirizzi IP desiderati, la sua prima istruzione concatena i numeri mancanti al prefisso di rete, cioè se abbiamo 192.168.0. quindi se il ciclo for va da 190 a 199, la prima volta che si inserisce l'indirizzo sarà 192.168.0.190 e man mano che avanza il 190 verrà modificato, il resto lo teniamo. Quindi otteniamo la risposta ping, che viene eseguita dall'istruzione:
 os.popen (ping + "" + indirizzo)
Per sapere se l'IP è attivo controlleremo se la risposta che abbiamo contiene la parola ttl, Io uso riga.inferiore () perché sembra che in Linux esca in minuscolo e in Windows in maiuscolo, quindi non abbiamo problemi.

Nella parte finale, tutto ciò che faccio è ottenere di nuovo il tempo, e riposo questo nuovo tempo con quello precedente per dipingere il tempo impiegato per il mio programma.

Successivamente mostro un'immagine dell'esecuzione del programma, come possiamo vedere è un po' lento (52 secondi per 19 indirizzi) dipende anche dalla potenza del PC, ma questa volta può essere migliorato se utilizziamo i thread, quindi ora Farò il programma usando i " thread Python ".

Opzione 2 - Scanner Python filettato


Ora avvieremo un programma simile, ma qualcosa di più complesso, poiché ora il lavoro sarà diviso tra più thread e non rimarrà solo un carico, alla fine vedremo che il tempo è notevolmente ridotto, quindi possiamo dire che è una versione più ottimale.

Il programma è il seguente:

 import os import sys import platform import threading, subprocess from datetime import datetime IPXHILOS = 4 ip = input ("Inserisci l'IP:") diviso ip = ip.split ('.') try: red = diviso ip [0] + ' .' + IP diviso [1] + '.' + IP diviso [2] + '.' start = int (input ("Inserisci il numero iniziale della sottorete:")) end = int (input ("Inserisci il numero in cui vuoi terminare lo sweep:")) tranne: 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): per sottorete nell'intervallo (self.start, self.fin): indirizzo = rete + str (subnet) response = os.popen (ping + "" + address) for line in response.readlines(): if ("ttl" in line.lower()): print (address, "is active") break startTime = datetime .now () print ("[*] La scansione viene eseguita da", network + str (inizio), "to", network + str (fine)) NumberIPs = end-begining numberThreads = int ((NumberIPs / IPXHILOS) ) threads = [] try: for i nell'intervallo (numberThreads): endAux = inizio + IPXTHREADS if (endAux> end): endAux = end thread = Thread (beginning, endAux) thread.start () threads.append ( thread) inizio = finAux tranne Exceptio n so e: print ("[!] Errore durante la creazione dei thread:", e) sys.exit (2) per il thread nei thread: thread.join () endtime = datetime.now () time = endtime - starttime print ("[ *] La scansione ha richiesto% s "% tempo) 
[color = # a9a9a9] Programma completo [/ color]

Qui ti parlerò delle istruzioni che cambiano e vengono aggiunte (ignorerò le parti uguali al programma precedente):

Le importazioni che utilizziamo nel programma precedente sono valide per noi, dobbiamo solo aggiungere quanto segue, che verrà utilizzato per i thread Python.

 importare thread, sottoprocesso
Uso una variabile per il numero di IP che voglio che ogni thread controlli, quindi viene aggiunta all'inizio del programma:
 IPXTHREADS = 4
La richiesta di dati da parte dell'utente e il controllo del sistema operativo rimangono intatti. In questo spettacolo Creo una classe chiamata Thread che si estende da threading.Thread, questa classe riceve come parametri l'inizio e la fine degli indirizzi con cui ogni thread dovrà lavorare, quindi ho una funzione run, che è necessaria e deve essere chiamata così, si occuperà di fare il lavoro quando avvia il thread più tardi, il for non cambia:
 class Thread (threading.Thread): def __init __ (self, start, end): threading.Thread .__ init __ (self) self.start = start self.fin = end def run (self): per sottorete nell'intervallo ( self.start , self.fin): address = network + str (subnet) response = os.popen (ping + "" + address) for line in response.readlines(): if ("ttl" in line.lower() ): print ( indirizzo, "è attivo") break
Ora spiegheremo la parte che ho al di fuori della classe Filo.

Uso le seguenti istruzioni per conoscere il numero di IP che ho in totale, in base all'inizio e alla fine che l'utente mi dà:

 NumberIPs = fine-inizio
Ora, una volta che lo sappiamo, possiamo calcolare il numero di thread di cui avrò bisogno per lavorare:
 numberThreads = int ((NumberIPs / IPXTHREADS))
Avrò bisogno di un elenco in cui archiviare ogni thread, in modo che in seguito possa fare in modo che il thread principale attenda il completamento del lavoro:
 discussioni = []
Il seguente frammento di codice creerà i thread e passerà loro la loro sezione di lavoro, per questo dobbiamo "giocare" con l'inizio e la fine di ogni thread, ecco perché ho creato la variabile finAux. Una volta creato, il thread inizia con cominciare () e viene aggiunto all'elenco dei thread.
 prova: for i nell'intervallo (numberThreads): endAux = inizio + IPXTHREADS if (endAux> end): endAux = fine thread = Thread (inizio, endAux) thread.start () threads.append (thread) inizio = endAux tranne Eccezione come e: print ("[!] Errore durante la creazione dei thread:", e) sys.exit (2)
Quindi creo un ciclo il cui scopo è aspettare che i thread finiscano
 per thread in thread: thread.join () 
E infine, il tempo è preso, verrebbe sottratto da quello che ho preso prima di iniziare e viene mostrato sullo schermo, proprio come il programma precedente.

Se facciamo lo stesso test di prima con questo programma vediamo che ci vogliono 6 secondi per fare lo stesso lavoro, che differenza.

NotaIl tempo può variare a seconda della potenza del tuo PC e della variabile IPXHILOS, io gli assegno un 4, se assegni più lavoro ad ogni thread ci vorrà più tempo, se ha meno lavoro sarà più veloce, ma attenzione che ci è un limite al numero di thread che possiamo creare.

Possiamo fidarci che questo programma ci dia il 100% degli host attivi?La risposta è no, dal momento che puoi bloccare il ping su un host bloccando le richieste e/o le risposte ICMP, quello di cui puoi essere certo è che se ti dice che è attivo, lo è. Ci sono altri tipi di scanner, come TCP che puoi fare con le porte che un sistema operativo normalmente lascia aperte, e la combinazione degli scanner TCP e ping sarà più affidabile.

Vi lascio uno zip con i 2 codici:

codigos_ping_python.zip 1.38K 270 download

Ti è piaciuto e hai aiutato questo Tutorial?Puoi premiare l'autore premendo questo pulsante per dargli un punto positivo
wave wave wave wave wave