Automatyczny skaner do wyszukiwania aktywnych hostów za pomocą Pythona

Czy chcesz zobaczyć, które adresy IP są aktywne w sieci? Chcesz wiedzieć, jak realizowany jest program w tym stylu? Cóż, dzisiaj ci pokażę jak zrobić program w pythonie 3, który będzie skanował sieć w zakresie adresów IP dostarczonych przez użytkownika.

W tym celu zautomatyzujemy ping systemu operacyjnego.

opcja 1 - Prosty skaner


Postawiłem tę pierwszą opcję, ponieważ łatwiej ją zrozumieć i przeprowadzić, zanim przejdziemy do czegoś bardziej skomplikowanego.

Kompletny program wygląda następująco:

 import os import sys import platformy z datetime import datetime ip = input ("Wprowadź adres IP:") podzielony ip = ip.split ('.') try: red = podzielony ip [0] + '.' + podzielony ip [1 ] + ' . '+ ipDivided [2] +'. ' start = int (input ("Wprowadź numer początkowy podsieci:")) end = int (input ("Wprowadź numer, pod którym chcesz zakończyć przeglądanie:")) z wyjątkiem: print ("[!] Błąd" ) sys.exit (1) if (platform.system() == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1" starttime = datetime.now() print ("[ * ] Skanowanie jest wykonywane od ", czerwony + str (start)," do ", czerwony + str (end)) dla podsieci w zakresie (start, koniec + 1): adres = czerwony + str (podsieć) odpowiedź = os .popen (ping + "" + adres) dla linii w response.readlines (): if ("ttl" w line.lower()): print (adres, "jest aktywny") przerwa endtime = datetime.now() time = endTime - startTime print ("[*] skanowanie trwało% s"% czasu) 
[kolor = # a9a9a9] Pełny kod [/ kolor]

Krok 1
Do naszego programu potrzebujemy zaimportować kilka bibliotek:

 import systemu operacyjnego import sys platformę importu z datetime import datetime
[kolor = # a9a9a9] Biblioteki [/ kolor]

Wyjaśnienie bibliotek

  • Ty: Potrzebujemy go do pingowania systemu operacyjnego.
  • system: Używam go do zakończenia programu z powodu błędu w danych wejściowych użytkownika.
  • Platforma: Pozwala nam poznać system operacyjny, w którym uruchamiamy program, jego użycie czyni nas niezależnymi od platformy.
  • data i godzina: Używam go, aby poznać czas potrzebny na wykonanie skanowania, jeśli nie chcesz tego wiedzieć, możesz go zapisać.

Krok 2
W poniższym fragmencie kodu prosimy użytkownika o podanie niezbędnych danych, takich jak host i zakres podsieci. Mamy też blok try and catch, którego w zasadzie używam do zakończenia programu w kontrolowany sposób, jeśli IP wstawiony przez użytkownika nie jest poprawny, pierwsza instrukcja bloku da błąd, a jeśli przy pytaniu o początek a koniec nie wstawia numerów, to wyskoczy błąd.

 ip = input ("Wprowadź IP:") podzielony ip = ip.split ('.') try: network = podzielony ip [0] + '.' + podzielony ip [1] + '.' + podzielony ip [2 ] + '.' start = int (input ("Wprowadź numer początkowy podsieci:")) end = int (input ("Wprowadź numer, pod którym chcesz zakończyć przeglądanie:")) z wyjątkiem: print ("[!] Błąd" ) sys.exit (1)
Używam pierwszej instrukcji w bloku try, aby utworzyć prefiks sieci, który przyda się później.

Na przykład na poniższym obrazku z danymi, które wstawiam, przeskanujemy, aby sprawdzić, czy adresy od 192.168.0.190 do 192.168.0.199 są aktywne.

Krok 3
W dalszej części kodu sprawdzam tylko, który system operacyjny jest używany przez tę funkcję platforma.system ().

 if (platform.system() == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1"
Jest to konieczne, ponieważ chcemy wysłać pojedynczą paczkę, aw Windows instrukcje wykonuje się za pomocą -n, aw uniksie za pomocą -c.

Krok 4
Następnie przeanalizuję następujący fragment kodu:

 starttime = datetime.now () print ("[*] Skanowanie jest wykonywane od", czerwony + str (start), "do", czerwony + str (koniec)) dla podsieci w zakresie (start, koniec + 1) : adres = sieć + str (podsieć) odpowiedź = os.popen (ping + "" + adres) dla linii w response.readlines (): if ("ttl" w line.lower()): print (adres, "is active ") przerwa endtime = datetime.now () time = endtime - starttime print (" [*] Skan trwał% s "% czasu)
Na tym etapie wykonujemy prawdziwą funkcjonalność, więc przed rozpoczęciem otrzymuję odpowiedni czas:
 czas rozpoczęcia = datagodzina.teraz ()
I malujemy linię na ekran, aby użytkownik wiedział, że skan jest wykonywany (i zakres):
 print ("[*] Skan jest wykonywany z", red + str (start), "to", red + str (end))
Następnie widzimy for, który przejdzie przez zakres żądanych adresów IP, jego pierwsza instrukcja łączy brakujące liczby z prefiksem sieci, czyli jeśli mamy 192.168.0. wtedy jeśli pętla for przejdzie od 190 do 199, przy pierwszym wpisaniu adresu będzie to 192.168.0.190 iw miarę postępu 190 zostanie zmienione, resztę zachowamy. Następnie otrzymujemy odpowiedź ping, która jest realizowana przez instrukcję:
 os.popen (ping + "" + adres)
Aby wiedzieć, czy adres IP jest aktywny, sprawdzimy, czy otrzymana przez nas odpowiedź zawiera słowo ttl, Używam linia.dolna () bo wydaje się, że w Linuksie wychodzi małymi literami, a w Windows dużymi, więc nie mamy problemów.

W końcowej części wszystko, co robię, to znowu odzyskuję czas i odpoczywam ten nowy czas z poprzednim, aby namalować czas, który zajęło mojemu programowi.

Następnie pokazuję obraz wykonania programu, jak widać jest nieco powolny (52 sekundy dla 19 adresów) zależy to również od mocy komputera, ale ten czas można poprawić, jeśli użyjemy wątków, więc teraz Program zrobię za pomocą „wątków Pythona”.

Opcja 2 - wątkowy skaner Pythona


Teraz zamierzamy uruchomić podobny program, ale coś bardziej złożonego, ponieważ teraz praca zostanie podzielona na kilka wątków i nie tylko pozostanie jedno obciążenie, w końcu zobaczymy, że czas jest znacznie skrócony, więc możemy powiedzieć która jest bardziej optymalną wersją.

Program wygląda następująco:

 import os import sys import platformy import wątków, podproces z datetime import datetime IPXHILOS = 4 ip = input ("Wprowadź adres IP:") dzielony ip = ip.split ('.') try: red = podzielony ip [0] + ' .' + Podzielony ip [1] + '.' + Podzielony ip [2] + '.' start = int (input ("Wprowadź numer początkowy podsieci:")) end = int (input ("Wprowadź numer, pod którym chcesz zakończyć przeglądanie:")) z wyjątkiem: print ("[!] Błąd" ) sys.exit (1) if (platform.system() == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1" class Wątek (threading.Thread): def __init __ ( self, start, end): threading.Thread .__ init __ (self) self.start = start self.fin = end def run (self): dla podsieci w zakresie (self.start, self.fin): adres = sieć + str (podsieć) response = os.popen (ping + "" + adres) dla linii w response.readlines (): if ("ttl" in line.lower()): print (adres, "jest aktywny") break startTime = datetime .now () print ("[*] Skanowanie jest wykonywane od", sieć + str (początek), "do", sieć + str (koniec)) NumberIPs = end-begining numberThreads = int ((NumberIPs / IPXHILOS) ) threads = [] try: for i in range (numberThreads): endAux = początek + IPXTHREADS if (endAux> end): endAux = end thread = Thread (początek, endAux) thread.start() threads.append ( wątek) początek = finAux z wyjątkiem Wyjątku n tak e: print ("[!] Błąd podczas tworzenia wątków:", e) sys.exit (2) dla wątku w wątkach: thread.join() endtime = datetime.now() time = endtime - starttime print ("[ *] Skanowanie zajęło % s "% czasu) 
[kolor = # a9a9a9] Kompletny program [/ kolor]

Tutaj opowiem o instrukcjach, które się zmieniają i są dodawane (zignoruję części równe poprzedniemu programowi):

Importy, których używamy w poprzednim programie, są dla nas ważne, wystarczy dodać następujące, które będą używane dla wątków Pythona.

 importuj wątki, podproces
Używam zmiennej dla liczby adresów IP, które chcę sprawdzić każdy wątek, więc jest ona dodawana na początku programu:
 GWINT IPX = 4
Żądanie użytkownika dotyczące danych i kontrola systemu operacyjnego pozostają nienaruszone. W tym programie Tworzę klasę o nazwie Thread, która rozciąga się od threading.Thread, ta klasa otrzymuje jako parametry początek i koniec adresów z którymi każdy wątek będzie musiał pracować, potem mam funkcję run, która jest konieczna i ma być tak wywołana, zajmie się wykonaniem pracy, gdy my uruchom wątek później , for nie zmienia się:
 class Thread (threading.Thread): def __init __ (self, start, end): threading.Thread .__ init __ (self) self.start = start self.fin = end def run (self): dla podsieci w zakresie ( self.start , self.fin): adres = sieć + str (podsieć) response = os.popen (ping + "" + adres) dla linii w response.readlines(): if ("ttl" w line.lower()) ): print ( adres, "jest aktywny") break
Teraz wyjaśnimy część, którą mam poza zajęciami Wątek.

Korzystam z poniższej instrukcji, aby poznać liczbę adresów IP, które w sumie posiadam, zgodnie z początkiem i końcem, które podaje mi użytkownik:

 NumberIPs = koniec-początek
Teraz, gdy już to wiemy, możemy obliczyć liczbę wątków, które będę potrzebować do pracy:
 numberThreads = int ((LiczbaIP / IPXTHREADS))
Potrzebuję listy, w której przechowywać każdy wątek, aby później mógł wątek główny czekać na zakończenie zadania:
 wątki = []
Poniższy fragment kodu utworzy wątki i przekaże im sekcję pracy, w tym celu musimy „pobawić się” początkiem i końcem każdego wątku, dlatego stworzyłem zmienną finAux. Po utworzeniu wątku zaczyna się od początek () i zostanie dodany do listy wątków.
 try: for i in range (numberThreads): endAux = początek + IPXTHREADS if (endAux> end): endAux = koniec wątku = Thread (początek, endAux) thread.start() threads.append (thread) begin = endAux z wyjątkiem Wyjątku as e: print ("[!] Błąd podczas tworzenia wątków:", e) sys.exit (2)
Następnie tworzę pętlę, której celem jest oczekiwanie na zakończenie wątków
 dla wątku w wątkach: thread.join () 
I wreszcie, czas jest zajęty, zostałby odjęty od tego, który wziąłem przed uruchomieniem i jest wyświetlany na ekranie, tak jak w poprzednim programie.

Jeśli wykonamy ten sam test, co poprzednio z tym programem, zobaczymy, że wykonanie tej samej pracy zajmuje 6 sekund, co za różnica.

NotatkaCzas może się różnić w zależności od mocy twojego komputera i zmiennej IPXHILOS, przypisuję mu 4, jeśli przypiszesz więcej pracy do każdego wątku, potrwa to dłużej, jeśli ma mniej pracy, będzie szybciej, ale uważaj, aby tam to ograniczenie liczby wątków, które możemy utworzyć.

Czy możemy ufać, że ten program daje nam 100% aktywnych hostów?Odpowiedź brzmi: nie, ponieważ możesz zablokować ping na hoście, blokując żądania i / lub odpowiedzi ICMP, możesz być pewien, że jeśli powie ci, że jest aktywny, to tak. Istnieją inne typy skanerów, takie jak TCP, które można zrobić z portami, które normalnie system operacyjny pozostawia otwarte, a kombinacja skanerów TCP i ping będzie bardziej niezawodna.

Zostawiam ci zip z 2 kodami:

codigos_ping_python.zip 1.38 KB 270 pobrań

Podobał Ci się i pomógł ten samouczek?Możesz nagrodzić autora, naciskając ten przycisk, aby dać mu pozytywny punkt

Będziesz pomóc w rozwoju serwisu, dzieląc stronę ze swoimi znajomymi

wave wave wave wave wave