Automatický skener pro vyhledání aktivních hostitelů s Pythonem

Chcete vidět, jaké IP jsou aktivní v síti? Chtěli byste vědět, jak se program tohoto stylu provádí? Dnes vám to ukážu jak vytvořit program v pythonu 3, který bude skenovat síť v rozsahu IP adres, které uživatel poskytuje.

Pro tento úkol zautomatizujeme ping operačního systému.

Možnost 1 - Jednoduchý skener


Dal jsem tuto první možnost, protože je snazší ji pochopit a provést, než se pustím do něčeho složitějšího.

Kompletní program je následující:

 import os import sys platforma importu z datetime import datetime ip = vstup ("Zadejte IP:") děleno ip = ip.split ('.') zkuste: červená = dělené ip [0] + '.' + dělené ip [1 ] + '.' + ipDělené [2] + '.' start = int (vstup ("Zadejte počáteční číslo podsítě:")) end = int (zadejte ("Zadejte číslo, kde chcete ukončit tažení:")) kromě: print ("[!] Chyba") sys.exit (1) if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1" starttime = datetime.now () print ("[ * ] Provádí se skenování z ", červená + str (začátek)," do ", červená + str (konec)) pro podsíť v dosahu (začátek, konec + 1): adresa = červená + str (podsíť) odpověď = os .popen (ping + "" + adresa) pro řádek v response.readlines (): if ("ttl" in line.lower ()): print (address, "is active") break endtime = datetime.now () time = endTime - startTime print ("[*] Skenování trvalo% s"% času) 
[color = # a9a9a9] Kompletní kód [/ color]

Krok 1
Potřebujeme importovat některé knihovny pro náš program:

 import os import sys import platforma z datetime import datetime
[color = # a9a9a9] Knihovny [/ color]

Vysvětlení knihoven

  • vy: Potřebujeme, aby pingoval prostřednictvím operačního systému.
  • sys: Používám to k ukončení programu kvůli chybě ve vstupu uživatele.
  • plošina: Umožňuje nám poznat operační systém, kde program spouštíme, jeho použití nás činí platformově nezávislými.
  • čas schůzky: Používám to, abych poznal čas potřebný k provedení kontroly, pokud to nechcete vědět, můžete si to uložit.

Krok 2
V následující části kódu žádáme uživatele o potřebná data, jako je hostitel a rozsah podsítě. Máme také blok pokusu a odlovu, který v zásadě používám k řízenému ukončení programu, pokud IP vložená uživatelem není správná, první instrukce bloku způsobí chybu a pokud při dotazu na začátek a konec nevloží čísla, přeskočí chybu.

 ip = vstup („Zadejte IP:“) děleno ip = ip.split ('.') zkuste: síť = dělené ip [0] + '.' + dělené ip [1] + '.' + dělené ip [2 ] + '.' start = int (vstup ("Zadejte počáteční číslo podsítě:")) end = int (zadejte ("Zadejte číslo, kde chcete ukončit tažení:")) kromě: print ("[!] Chyba") sys.exit (1)
První příkaz v bloku try používám k vytvoření předpony sítě, což se bude hodit později.

Například na následujícím obrázku s daty, která vkládám, bychom naskenovali, abychom zjistili, zda jsou aktivní adresy od 192.168.0.190 do 192.168.0.199.

Krok 3
V další části kódu jsem zkontroloval pouze to, jaký operační systém se prostřednictvím funkce používá platform.system ().

 if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1"
Je to nutné, protože chceme poslat jeden balíček, a ve Windows se instrukce provádí pomocí -n a v unixu s -c.

Krok 4
Dále budu analyzovat následující fragment kódu:

 starttime = datetime.now () tisk ("[*] Skenování probíhá od", červená + str (začátek), "do", červená + str (konec)) pro podsíť v dosahu (začátek, konec + 1) : adresa = síť + str (podsíť) odpověď = os.popen (ping + "" + adresa) pro řádek v response.readlines (): if ("ttl" in line.lower ()): print (address, "is aktivní ") break endtime = datetime.now () time = endtime - starttime print (" [*] Skenování trvalo% s "% time)
V tomto kroku provádíme skutečnou funkčnost, takže než začnu, dostanu odpovídající čas:
 starttime = datetime.now ()
A namalujeme čáru na obrazovku, aby uživatel věděl, že probíhá skenování (a rozsah):
 tisk ("[*] Skenování probíhá z", červená + str (začátek), "do", červená + str (konec))
Pak vidíme for, který projde rozsah požadovaných IP adres, jeho první instrukce zřetězí chybějící čísla na předponu sítě, tedy pokud máme 192.168.0. pak pokud smyčka for přejde z 190 na 199, při prvním zadání adresy bude 192.168.0.190 a jak bude postupovat, 190 se změní, zbytek ponecháme. Poté dostaneme odpověď ping, která se provádí podle instrukce:
 os.popen (ping + "" + adresa)
Abychom věděli, zda je IP aktivní, zkontrolujeme, zda odpověď, kterou máme, obsahuje slovo ttl, Používám line.lower () protože to vypadá, že v Linuxu to vychází malými písmeny a ve Windows velkými písmeny, takže nemáme problémy.

V závěrečné části vše, co udělám, je opět získat čas a odpočívám v tomto novém čase s předchozím, abych namaloval čas, který mi zabral můj program.

Dále ukážu obrázek spuštění programu, protože vidíme, že je poněkud pomalý (52 sekund pro 19 adres), záleží také na výkonu počítače, ale tuto dobu lze zlepšit, pokud použijeme vlákna, takže nyní Program vytvořím pomocí „vláken Pythonu“.

Možnost 2 - Vláknový skener se závitem


Nyní spustíme podobný program, ale něco složitějšího, protože nyní bude práce rozdělena do několika vláken a nezůstane jen jedno zatížení, nakonec uvidíme, že čas se výrazně zkrátí, takže můžeme říci což je optimálnější verze.

Program je následující:

 import os import sys importní platforma importní vlákno, podproces z datetime import datetime IPXHILOS = 4 ip = vstup ("Zadejte IP:") rozdělené ip = ip.split ('.') zkuste: červená = dělené ip [0] + ' . ' + Dělená ip [1] +'. ' + Dělená ip [2] +'. ' start = int (vstup ("Zadejte počáteční číslo podsítě:")) end = int (zadejte ("Zadejte číslo, kde chcete ukončit tažení:")) kromě: print ("[!] Chyba") 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): pro podsíť v dosahu (self.start, self.fin): adresa = síť + str (podsíť) odpověď = os.popen (ping + "" + adresa) pro řádek v response.readlines (): if ("ttl" in line.lower ()): print (address, "is active") break startTime = datetime .now () tisk ("[*] Skenování probíhá od", síť + str (začátek), "do", síť + str (konec)) NumberIPs = konec-začátek numberThreads = int ((NumberIPs / IPXHILOS)) vlákna = [] try: for i in range (numberThreads): endAux = začátek + IPXTHREADS if (endAux> end): endAux = end thread = Thread (begin, endAux) thread.start () threads.append ( vlákno) začátek = finAux kromě Exceptio n so e: print ("[!] Chyba při vytváření vláken:", e) sys.exit (2) pro vlákno ve vláknech: thread.join () endtime = datetime.now () time = endtime - starttime print ("[ *] Skenování trvalo% s "% času) 
[color = # a9a9a9] Kompletní program [/ color]

Zde vám řeknu o pokynech, které se mění a jsou přidány (budu ignorovat části stejné jako v předchozím programu):

Importy, které používáme v předchozím programu, jsou pro nás platné, stačí přidat následující, které budou použity pro vlákna Pythonu.

 importování podprocesů, podproces
Používám proměnnou pro počet IP, které chci, aby každé vlákno zkontrolovalo, takže je přidáno na začátek programu:
 IPXTHREADS = 4
Požadavek uživatele na data a kontrola operačního systému zůstávají nedotčeny. V této show Vytvořím třídu s názvem Thread, která sahá od threading.Thread, tato třída přijímá jako parametry začátek a konec adres, se kterými bude každé vlákno fungovat, pak mám funkci run, která je nezbytná a musí se takto nazývat, postará se o provedení práce, když založ vlákno později, for se nemění:
 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): adresa = síť + str (podsíť) odpověď = os.popen (ping + "" + adresa) pro řádek v response.readlines (): if ("ttl" v line.lower () ): print (address, "is active") break
Nyní vysvětlíme část, kterou mám mimo třídu Vlákno.

Následující instrukci používám k tomu, abych poznal celkový počet IP, které mám, podle začátku a konce, které mi uživatel poskytne:

 NumberIPs = end-start
Jakmile to víme, můžeme vypočítat počet vláken, která budu potřebovat k práci:
 numberThreads = int ((NumberIPs / IPXTHREADS))
Budu potřebovat seznam, kam uložit každé vlákno, abych později mohl nechat hlavní vlákno čekat na dokončení úlohy:
 vlákna = []
Následující fragment kódu vytvoří vlákna a předá jim jejich pracovní sekci, proto si musíme „pohrát“ se začátkem a koncem každého vlákna, proto jsem vytvořil proměnnou finAux. Jakmile je vlákno vytvořeno, začíná na Start () a je přidán do seznamu vláken.
 zkus: pro i v rozsahu (numberThreads): endAux = začátek + IPXTHREADS if (endAux> end): endAux = end thread = Thread (začátek, endAux) thread.start () threads.append (vlákno) začátek = endAux kromě Výjimka jako e: print ("[!] Chyba při vytváření vláken:", e) sys.exit (2)
Dále vytvořím smyčku, jejímž účelem je počkat na dokončení vláken
 pro vlákno ve vláknech: thread.join () 
A nakonec čas zabere, odečte se od času, který jsem vzal před spuštěním, a zobrazí se na obrazovce, stejně jako předchozí program.

Pokud u tohoto programu provedeme stejný test jako dříve, uvidíme, že stejná práce trvá 6 sekund, jaký je rozdíl.

PoznámkaČas se může lišit v závislosti na výkonu vašeho počítače a proměnné IPXHILOS, přiřadím mu 4, pokud každému vláknu přiřadíte více práce, bude to trvat déle, pokud bude mít méně práce, bude to rychlejší, ale dávejte pozor, aby tam je limit počtu vláken, která můžeme vytvořit.

Můžeme věřit, že tento program nám dává 100% aktivních hostitelů?Odpověď zní ne, protože ping na hostiteli můžete zablokovat blokováním požadavků a / nebo odpovědí ICMP. Tím si můžete být jisti, že pokud vám řekne, že je aktivní, je. Existují i ​​jiné typy skenerů, například TCP, které můžete provádět s porty, které operační systém normálně nechává otevřený, a kombinace skenerů TCP a ping bude spolehlivější.

Nechám vám zip se 2 kódy:

codigos_ping_python.zip 1,38 kB 270 stažení

Líbil se vám tento návod a pomohl mu?Autora můžete odměnit stisknutím tohoto tlačítka, čímž mu dáte kladný bod
wave wave wave wave wave