Scanner di rete Python

La scansione delle porte può essere definita come una tecnica di sorveglianza, utilizzata per individuare le porte aperte disponibili su un particolare host. L'amministratore di rete, il penetration tester o un hacker possono utilizzare questa tecnica. Possiamo configurare il port scanner in base alle nostre esigenze per ottenere il massimo delle informazioni dal sistema di destinazione.

Ora, considera le informazioni che possiamo ottenere dopo aver eseguito la scansione delle porte:

  • Informazioni sulle porte aperte.

  • Informazioni sui servizi in esecuzione su ciascuna porta.

  • Informazioni sul sistema operativo e l'indirizzo MAC dell'host di destinazione.

La scansione delle porte è proprio come un ladro che vuole entrare in una casa controllando ogni porta e finestra per vedere quali sono aperte. Come discusso in precedenza, la suite di protocolli TCP / IP, utilizzata per la comunicazione su Internet, è composta da due protocolli, ovvero TCP e UDP. Entrambi i protocolli hanno porte da 0 a 65535. Poiché è sempre consigliabile chiudere le porte non necessarie del nostro sistema, quindi essenzialmente, ci sono più di 65000 porte (porte) da bloccare. Queste 65535 porte possono essere suddivise nei seguenti tre intervalli:

  • Porte di sistema o note: da 0 a 1023

  • Porte utente o registrate: da 1024 a 49151

  • Porte dinamiche o private: tutte> 49151

Port Scanner utilizzando Socket

Nel nostro capitolo precedente, abbiamo discusso di cosa sia un socket. Ora costruiremo un semplice port scanner usando socket. Di seguito è riportato uno script Python per port scanner utilizzando socket -

from socket import *
import time
startTime = time.time()

if __name__ == '__main__':
   target = input('Enter the host to be scanned: ')
   t_IP = gethostbyname(target)
   print ('Starting scan on host: ', t_IP)
   
   for i in range(50, 500):
      s = socket(AF_INET, SOCK_STREAM)
      
      conn = s.connect_ex((t_IP, i))
      if(conn == 0) :
         print ('Port %d: OPEN' % (i,))
      s.close()
print('Time taken:', time.time() - startTime)

Quando eseguiamo lo script precedente, verrà richiesto il nome host, puoi fornire qualsiasi nome host come il nome di qualsiasi sito Web, ma fai attenzione perché la scansione delle porte può essere vista o interpretata come un crimine. Non dovremmo mai eseguire un port scanner su qualsiasi sito web o indirizzo IP senza un'esplicita autorizzazione scritta da parte del proprietario del server o del computer che stai prendendo di mira. La scansione delle porte è come andare a casa di qualcuno e controllarne porte e finestre. Questo è il motivo per cui è consigliabile utilizzare il port scanner su localhost o sul proprio sito Web (se presente).

Produzione

Lo script precedente genera il seguente output:

Enter the host to be scanned: localhost
Starting scan on host: 127.0.0.1
Port 135: OPEN
Port 445: OPEN
Time taken: 452.3990001678467

L'output mostra che nell'intervallo da 50 a 500 (come previsto nello script), questo port scanner ha trovato due porte: le porte 135 e 445, aperte. Possiamo modificare questo intervallo e verificare la presenza di altre porte.

Port Scanner utilizzando ICMP (host live in una rete)

ICMP non è una scansione delle porte, ma viene utilizzato per eseguire il ping dell'host remoto per verificare se l'host è attivo. Questa scansione è utile quando dobbiamo controllare un numero di host live in una rete. Implica l'invio di una richiesta ECHO ICMP a un host e se tale host è attivo, restituirà una risposta ECHO ICMP.

Il suddetto processo di invio della richiesta ICMP è anche chiamato scansione ping, fornito dal comando ping del sistema operativo.

Concetto di Ping Sweep

In realtà in un senso o nell'altro, il ping sweep è anche noto come ping sweeping. L'unica differenza è che lo sweeping del ping è la procedura per trovare più di una disponibilità della macchina in un intervallo di rete specifico. Ad esempio, supponiamo di voler testare un elenco completo di indirizzi IP, quindi utilizzando la scansione ping, ovvero il comando ping del sistema operativo, sarebbe molto dispendioso in termini di tempo scansionare gli indirizzi IP uno per uno. Questo è il motivo per cui dobbiamo usare lo script ping sweep. Di seguito è riportato uno script Python per trovare host live utilizzando il ping sweep -

import os
import platform

from datetime import datetime
net = input("Enter the Network Address: ")
net1= net.split('.')
a = '.'

net2 = net1[0] + a + net1[1] + a + net1[2] + a
st1 = int(input("Enter the Starting Number: "))
en1 = int(input("Enter the Last Number: "))
en1 = en1 + 1
oper = platform.system()

if (oper == "Windows"):
   ping1 = "ping -n 1 "
elif (oper == "Linux"):
   ping1 = "ping -c 1 "
else :
   ping1 = "ping -c 1 "
t1 = datetime.now()
print ("Scanning in Progress:")

for ip in range(st1,en1):
   addr = net2 + str(ip)
   comm = ping1 + addr
   response = os.popen(comm)
   
   for line in response.readlines():
      if(line.count("TTL")):
         break
      if (line.count("TTL")):
         print (addr, "--> Live")
         
t2 = datetime.now()
total = t2 - t1
print ("Scanning completed in: ",total)

Lo script sopra funziona in tre parti. Per prima cosa seleziona l'intervallo di indirizzi IP per eseguire il ping di scansione di scansione suddividendolo in parti. Segue l'uso della funzione, che selezionerà il comando per lo sweep del ping in base al sistema operativo, e per ultimo darà la risposta sull'host e sul tempo impiegato per completare il processo di scansione.

Produzione

Lo script precedente genera il seguente output:

Enter the Network Address: 127.0.0.1
Enter the Starting Number: 1
Enter the Last Number: 100

Scanning in Progress:
Scanning completed in: 0:00:02.711155

L'output precedente non mostra porte attive perché il firewall è attivo e anche le impostazioni in entrata ICMP sono disabilitate. Dopo aver modificato queste impostazioni, possiamo ottenere l'elenco delle porte attive nell'intervallo da 1 a 100 fornito nell'output.

Port Scanner tramite scansione TCP

Per stabilire una connessione TCP, l'host deve eseguire un handshake a tre vie. Segui questi passaggi per eseguire l'azione:

Step 1 − Packet with SYN flag set

In questo passaggio, il sistema che sta tentando di avviare una connessione inizia con un pacchetto con il flag SYN impostato.

Step 2 − Packet with SYN-ACK flag set

In questo passaggio, il sistema di destinazione restituisce un pacchetto con i set di flag SYN e ACK.

Step 3 − Packet with ACK flag set

Alla fine, il sistema di avvio restituirà un pacchetto al sistema di destinazione originale con il flag ACK impostato.

Tuttavia, la domanda che sorge qui è se possiamo eseguire la scansione delle porte utilizzando il metodo di richiesta e risposta echo ICMP (ping sweep scanner), allora perché abbiamo bisogno della scansione TCP? Il motivo principale alla base è che supponiamo che se disattiviamo la funzione di risposta ECHO ICMP o utilizziamo un firewall per i pacchetti ICMP, lo scanner di scansione ping non funzionerà e abbiamo bisogno della scansione TCP.

import socket
from datetime import datetime
net = input("Enter the IP address: ")
net1 = net.split('.')
a = '.'

net2 = net1[0] + a + net1[1] + a + net1[2] + a
st1 = int(input("Enter the Starting Number: "))
en1 = int(input("Enter the Last Number: "))
en1 = en1 + 1
t1 = datetime.now()

def scan(addr):
   s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   socket.setdefaulttimeout(1)
   result = s.connect_ex((addr,135))
   if result == 0:
      return 1
   else :
      return 0

def run1():
   for ip in range(st1,en1):
      addr = net2 + str(ip)
      if (scan(addr)):
         print (addr , "is live")
         
run1()
t2 = datetime.now()
total = t2 - t1
print ("Scanning completed in: " , total)

Lo script sopra funziona in tre parti. Seleziona l'intervallo di indirizzi IP per eseguire il ping di scansione di scansione suddividendolo in parti. Questo è seguito dall'uso di una funzione per la scansione dell'indirizzo, che utilizza ulteriormente il socket. Successivamente, fornisce la risposta sull'host e sul tempo impiegato per completare il processo di scansione. Il risultato = s. L'istruzione connect_ex ((addr, 135)) restituisce un indicatore di errore. L'indicatore di errore è 0 se l'operazione riesce, altrimenti è il valore della variabile errno. Qui abbiamo usato la porta 135; questo scanner funziona per il sistema Windows. Un'altra porta che funzionerà qui è 445 (Microsoft-DSActive Directory) e di solito è aperta.

Produzione

Lo script precedente genera il seguente output:

Enter the IP address: 127.0.0.1
Enter the Starting Number: 1
Enter the Last Number: 10

127.0.0.1 is live
127.0.0.2 is live
127.0.0.3 is live
127.0.0.4 is live
127.0.0.5 is live
127.0.0.6 is live
127.0.0.7 is live
127.0.0.8 is live
127.0.0.9 is live
127.0.0.10 is live
Scanning completed in: 0:00:00.230025

Port scanner filettato per aumentare l'efficienza

Come abbiamo visto nei casi precedenti, la scansione delle porte può essere molto lenta. Ad esempio, è possibile vedere il tempo impiegato per la scansione delle porte da 50 a 500, mentre si utilizza lo scanner per porte socket, è 452.3990001678467. Per migliorare la velocità possiamo usare il threading. Di seguito è riportato un esempio di port scanner che utilizza il threading:

import socket
import time
import threading

from queue import Queue
socket.setdefaulttimeout(0.25)
print_lock = threading.Lock()

target = input('Enter the host to be scanned: ')
t_IP = socket.gethostbyname(target)
print ('Starting scan on host: ', t_IP)

def portscan(port):
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   try:
      con = s.connect((t_IP, port))
      with print_lock:
         print(port, 'is open')
      con.close()
   except:
      pass

def threader():
   while True:
      worker = q.get()
      portscan(worker)
      q.task_done()
      
q = Queue()
   startTime = time.time()
   
for x in range(100):
   t = threading.Thread(target = threader)
   t.daemon = True
   t.start()
   
for worker in range(1, 500):
   q.put(worker)
   
q.join()
print('Time taken:', time.time() - startTime)

Nello script sopra, dobbiamo importare il modulo di threading, che è integrato nel pacchetto Python. Stiamo usando il concetto di threadlock,thread_lock = threading.Lock()per evitare più modifiche alla volta. Fondamentalmente, threading.Lock () consentirà a un singolo thread di accedere alla variabile alla volta. Quindi, non si verifica una doppia modifica.

Successivamente, definiamo una funzione threader () che recupererà il lavoro (porta) dal ciclo worker for. Quindi viene chiamato il metodo portscan () per connettersi alla porta e stampare il risultato. Il numero di porta viene passato come parametro. Una volta completata l'attività, viene chiamato il metodo q.task_done ().

Ora, dopo aver eseguito lo script precedente, possiamo vedere la differenza di velocità per la scansione da 50 a 500 porte. Ci sono voluti solo 1.3589999675750732 secondi, che è molto meno di 452.3990001678467, tempo impiegato dallo scanner della porta socket per la scansione dello stesso numero di porte di localhost.

Produzione

Lo script precedente genera il seguente output:

Enter the host to be scanned: localhost
Starting scan on host: 127.0.0.1
135 is open
445 is open
Time taken: 1.3589999675750732