Scanner automat pentru a găsi gazde active cu Python

Doriți să vedeți ce adrese IP sunt active într-o rețea? Doriți să știți cum se desfășoară un program de acest stil? Ei bine, azi vă arăt cum se face un program în Python 3 care va scana rețeaua într-o gamă de adrese IP pe care utilizatorul le furnizează.

Pentru această sarcină vom automatiza ping-ul sistemului de operare.

Opțiunea 1 - Scanner simplu


Am pus această primă opțiune, deoarece este mai ușor de înțeles și de realizat, înainte de a intra în ceva mai complicat.

Programul complet este după cum urmează:

 import os import sys platforma de import din datetime import datetime ip = input ("Enter the IP:") shared ip = ip.split ('.') try: red = shared ip [0] + '.' + shared ip [1 ] + '.' + ipDivided [2] + '.' start = int (input ("Introduceți numărul de pornire al subrețele:")) end = int (input ("Introduceți numărul unde doriți să încheiați măturarea:")) cu excepția: print ("[!] Error") sys.exit (1) if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1" starttime = datetime.now () print ("[* ] Scanarea se face de la ", roșu + str (start)," până la ", roșu + str (sfârșit)) pentru subrețea din interval (început, sfârșit + 1): adresă = roșu + str (subrețea) răspuns = os .popen (ping + "" + adresa) pentru linie în răspuns.readlines (): if ("ttl" în linie.lower ()): print (adresa, "este activ") break endtime = datetime.now () time = endTime - startTime print ("[*] scanarea a durat% s"% timp) 
[color = # a9a9a9] Cod complet [/ color]

Pasul 1
Trebuie să importăm câteva biblioteci pentru programul nostru:

 import os import sys platformă de import din datetime import datetime
[color = # a9a9a9] Biblioteci [/ color]

Explicația bibliotecilor

  • tu: Avem nevoie să facem ping prin sistemul de operare.
  • sys: Îl folosesc pentru a termina programul din cauza unei erori la intrarea utilizatorului.
  • platformă: Ne permite să cunoaștem sistemul de operare în care rulăm programul, utilizarea acestuia ne face independenți de platformă.
  • datetime: Îl folosesc pentru a ști timpul necesar pentru efectuarea scanării, dacă nu doriți să o știți, o puteți salva.

Pasul 2
În următoarea bucată de cod îi cerem utilizatorului datele necesare, cum ar fi gazda și gama de subrețele. De asemenea, avem un bloc de încercare și capturare pe care îl folosesc practic pentru a termina programul într-un mod controlat, dacă IP-ul introdus de utilizator nu este corect, prima instrucțiune a blocului va da o eroare și dacă la cererea pentru început și la sfârșit nu introduce numere, va sari o greșeală.

 ip = input ("Enter the IP:") shared ip = ip.split ('.') try: network = shared ip [0] + '.' + shared ip [1] + '.' + shared ip [2 ] + '.' start = int (input ("Introduceți numărul de pornire al subrețele:")) end = int (input ("Introduceți numărul unde doriți să încheiați măturarea:")) cu excepția: print ("[!] Error") sys.exit (1)
Folosesc prima declarație din blocul try pentru a crea un prefix de rețea, care va fi util mai târziu.

De exemplu, în următoarea imagine cu datele pe care le inserez, am scana pentru a vedea dacă adresele de la 192.168.0.190 la 192.168.0.199 sunt active.

Pasul 3
În următoarea parte a codului, singurul lucru pe care îl verific este sistemul de operare utilizat prin funcție platform.system ().

 if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1"
Acest lucru este necesar deoarece vrem să trimitem un singur pachet, iar în Windows instrucțiunea se face cu -n și în unix cu -c.

Pasul 4
În continuare voi analiza următorul fragment de cod:

 starttime = datetime.now () print ("[*] Scanarea se efectuează de la", roșu + str (start), "până la", roșu + str (sfârșit)) pentru subrețea în interval (start, sfârșit + 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 - printtime print (" [*] Scanarea a durat% s "% timp)
Acest pas este locul în care realizăm adevărata funcționalitate, așa că înainte de a începe obțin timpul corespunzător:
 starttime = datetime.now ()
Și pictăm o linie pe ecran, astfel încât utilizatorul să știe că scanarea este efectuată (și intervalul):
 print ("[*] Scanarea se face de la", roșu + str (start), "până la", roșu + str (sfârșit))
Apoi vedem un pentru, care va trece prin gama de adrese IP dorite, prima sa instrucțiune concatenează numerele lipsă la prefixul rețelei, adică dacă avem 192.168.0. atunci dacă bucla for merge de la 190 la 199, prima dată când introduceți adresa va fi 192.168.0.190 și pe măsură ce progresează, 190 va fi modificat, restul îl păstrăm. Apoi obținem răspunsul ping, care este efectuat de instrucțiunea:
 os.popen (ping + "" + adresă)
Pentru a ști dacă IP-ul este activ, vom verifica dacă răspunsul pe care îl avem conține cuvântul ttl, Eu folosesc line.lower () pentru că se pare că în Linux iese cu litere mici și în Windows cu majuscule, deci nu avem probleme.

În partea finală, tot ce fac este să obțin din nou timp și mă odihnesc cu noul timp anterior cu cel anterior pentru a picta timpul necesar programului meu.

În continuare arăt o imagine a execuției programului, deoarece putem vedea că este oarecum lent (52 de secunde pentru 19 adrese) depinde și de puterea computerului, dar de data aceasta poate fi îmbunătățită dacă folosim fire, așa că acum Voi face programul folosind „firele Python”.

Opțiunea 2 - Scaner Python filetat


Acum vom începe un program similar, dar ceva mai complex, deoarece acum lucrarea va fi împărțită în mai multe fire și nu va rămâne o singură încărcare, la final vom vedea că timpul este mult redus, așa că putem spune care este o versiune mai optimă.

Programul este după cum urmează:

 import os import sys platformă de import threading de import, subproces de la datetime import datetime IPXHILOS = 4 ip = input ("Enter the IP:") shared ip = ip.split ('.') try: red = shared ip [0] + ' . '+ Ip divizat [1] +'. '+ Ip divizat [2] +'. ' start = int (input ("Introduceți numărul de pornire al subrețele:")) end = int (input ("Introduceți numărul unde doriți să încheiați măturarea:")) cu excepția: print ("Eroare [!]") sys.exit (1) if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1" clasă Thread (threading.Thread): def __init __ ( self, start, end): threading.Thread .__ init __ (self) self.start = start self.fin = end def run (self): pentru subrețea în interval (self.start, self.fin): adresa = rețea + str (subrețea) răspuns = os.popen (ping + "" + adresă) pentru linie în răspuns.readlines (): if ("ttl" în linie.lower ()): print (adresa, "este activ") pauză startTime = datetime .now () print ("[*] Scanarea se efectuează de la", rețea + str (început), "până la", rețea + str (sfârșit)) / IPXHILOS)) threads = [] try: for i in range (numberThreads): endAux = begin + IPXTHREADS if (endAux> end): endAux = end thread = Thread (begin, endAux) thread.start () threads.append ( fir) început = finAux cu excepția Exceptio n so e: print ("[!] Eroare la crearea firelor:", e) sys.exit (2) pentru firul din fire: thread.join () endtime = datetime.now () time = endtime - starttime print ("[ *] Scanarea a durat% s "% timp) 
[color = # a9a9a9] Program complet [/ color]

Aici vă voi spune despre instrucțiunile care se schimbă și se adaugă (voi ignora părțile egale cu programul anterior):

Importurile pe care le folosim în programul anterior sunt valabile pentru noi, trebuie doar să adăugăm următoarele, care vor fi utilizate pentru firele Python.

 filetare import, subproces
Folosesc o variabilă pentru numărul de IP-uri pe care vreau să le verifice fiecare thread, așa că este adăugat la începutul programului:
 IPXTHREADS = 4
Cererea utilizatorului pentru date și verificarea sistemului de operare rămân intacte. În acest spectacol Creez o clasă numită Thread care se extinde de la threading.Thread, această clasă primește ca parametri începutul și sfârșitul adreselor cu care va trebui să lucreze fiecare fir, apoi am o funcție de rulare, care este necesară și trebuie numită astfel, se va ocupa de a face treaba atunci când porniți firul mai târziu, for nu se schimbă:
 clasă Thread (threading.Thread): def __init __ (self, start, end): threading.Thread .__ init __ (self) self.start = start self.fin = final def run (self): pentru subrețea în intervalul ( self.start, self.fin): address = network + str (subnet) response = os.popen (ping + "" + address) for line in response.readlines (): if ("ttl" in line.lower () ): print (adresa, "este activ") pauză
Acum vom explica partea pe care o am în afara orelor de curs Fir.

Folosesc următoarea instrucțiune pentru a cunoaște numărul de IP-uri pe care le am în total, în funcție de începutul și sfârșitul pe care mi le oferă utilizatorul:

 NumberIPs = end-start
Acum, odată ce știm acest lucru, putem calcula numărul de fire pe care va trebui să le lucrez:
 numberThreads = int ((NumberIPs / IPXTHREADS))
Voi avea nevoie de o listă unde să stochez fiecare fir, pentru ca mai târziu să pot face ca firul principal să aștepte finalizarea lucrării:
 fire = []
Următorul fragment de cod va crea firele și le va transmite secțiunea de lucru, pentru aceasta trebuie să „jucăm” cu începutul și sfârșitul fiecărui fir, de aceea am creat variabila finAux. Odată creat firul, începe cu start () și este adăugat la lista de fire.
 try: for i in range (numberThreads): endAux = început + IPXTHREADS if (endAux> end): endAux = end thread = Thread (început, endAux) thread.start () threads.append (thread) început = endAux cu excepția Exception ca e: print ("[!] Eroare la crearea firelor:", e) sys.exit (2)
Apoi creez o buclă al cărei scop este să aștepte terminarea firelor
 pentru fir în fire: thread.join () 
Și, în sfârșit, timpul este luat, ar fi scăzut din cel pe care l-am luat înainte de a începe și este afișat pe ecran, la fel ca programul anterior.

Dacă facem același test ca înainte cu acest program, vedem că durează 6 secunde pentru a face aceeași treabă, ce diferență.

NotăTimpul poate varia în funcție de puterea PC-ului și de variabila IPXHILOS, îi atribui un 4, dacă atribuiți mai multă lucrare fiecărui fir va dura mai mult, dacă are mai puțină muncă va fi mai rapid, dar aveți grijă ca acolo este o limită a numărului de fire pe care le putem crea.

Putem avea încredere că acest program ne oferă 100% din gazdele active?Răspunsul este nu, deoarece puteți bloca ping-ul pe o gazdă blocând cererile și / sau răspunsurile ICMP, ceea ce puteți fi sigur este că, dacă vă spune că este activ, este. Există alte tipuri de scanere, cum ar fi TCP, pe care le puteți face cu porturile pe care un sistem de operare le lasă în mod normal deschise, iar combinația dintre scanerele TCP și ping va fi mai fiabilă.

Vă las un zip cu cele 2 coduri:

codigos_ping_python.zip 1,38K 270 de descărcări

V-a plăcut și ați ajutat acest tutorial?Puteți recompensa autorul apăsând acest buton pentru a-i oferi un punct pozitiv

Vei ajuta la dezvoltarea site-ului, partajarea pagina cu prietenii

wave wave wave wave wave