Scanner de réseau Python

Le balayage des ports peut être défini comme une technique de surveillance, qui est utilisée afin de localiser les ports ouverts disponibles sur un hôte particulier. L'administrateur réseau, le testeur de pénétration ou un pirate informatique peuvent utiliser cette technique. Nous pouvons configurer le scanner de port en fonction de nos besoins pour obtenir le maximum d'informations du système cible.

Maintenant, considérez les informations que nous pouvons obtenir après avoir exécuté l'analyse de port -

  • Informations sur les ports ouverts.

  • Informations sur les services exécutés sur chaque port.

  • Informations sur le système d'exploitation et l'adresse MAC de l'hôte cible.

La numérisation des ports est comme un voleur qui veut entrer dans une maison en vérifiant chaque porte et fenêtre pour voir lesquelles sont ouvertes. Comme indiqué précédemment, la suite de protocoles TCP / IP, utilisée pour la communication sur Internet, est composée de deux protocoles à savoir TCP et UDP. Les deux protocoles ont de 0 à 65535 ports. Comme il est toujours conseillé de fermer les ports inutiles de notre système, il y a donc plus de 65000 portes (ports) à verrouiller. Ces 65535 ports peuvent être divisés dans les trois plages suivantes -

  • Ports système ou connus: de 0 à 1023

  • Ports utilisateur ou enregistrés: de 1024 à 49151

  • Ports dynamiques ou privés: tous> 49151

Scanner de port utilisant Socket

Dans notre chapitre précédent, nous avons discuté de ce qu'est une socket. Maintenant, nous allons construire un simple scanner de port en utilisant socket. Voici un script Python pour le scanner de port utilisant 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)

Lorsque nous exécutons le script ci-dessus, il vous demandera le nom d'hôte, vous pouvez fournir n'importe quel nom d'hôte comme le nom de n'importe quel site Web, mais soyez prudent car l'analyse des ports peut être considérée ou interprétée comme un crime. Nous ne devons jamais exécuter un scanner de port sur un site Web ou une adresse IP sans l'autorisation écrite explicite du propriétaire du serveur ou de l'ordinateur que vous ciblez. La numérisation des ports revient à se rendre chez quelqu'un et à vérifier ses portes et fenêtres. C'est pourquoi il est conseillé d'utiliser le scanner de port sur localhost ou sur votre propre site Web (le cas échéant).

Production

Le script ci-dessus génère la sortie suivante -

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

La sortie montre que dans la plage de 50 à 500 (comme indiqué dans le script), ce scanner de port a trouvé deux ports - les ports 135 et 445, ouverts. Nous pouvons modifier cette plage et vérifier les autres ports.

Scanner de ports utilisant ICMP (Live hosts in a network)

ICMP n'est pas une analyse de port, mais il est utilisé pour envoyer une requête ping à l'hôte distant pour vérifier si l'hôte est actif. Cette analyse est utile lorsque nous devons vérifier un certain nombre d'hôtes en direct dans un réseau. Cela implique l'envoi d'une demande ICMP ECHO à un hôte et si cet hôte est actif, il renverra une réponse ICMP ECHO.

Le processus ci-dessus d'envoi de la requête ICMP est également appelé scan ping, qui est fourni par la commande ping du système d'exploitation.

Concept de balayage ping

En fait, dans un sens ou dans un autre, le balayage ping est également connu sous le nom de balayage ping. La seule différence est que le balayage ping est la procédure permettant de rechercher la disponibilité de plusieurs machines dans une plage de réseau spécifique. Par exemple, supposons que nous voulions tester une liste complète d'adresses IP, puis en utilisant l'analyse ping, c'est-à-dire la commande ping du système d'exploitation, cela prendrait beaucoup de temps pour analyser les adresses IP une par une. C'est pourquoi nous devons utiliser un script de balayage ping. Voici un script Python pour trouver des hôtes en direct à l'aide du balayage ping -

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)

Le script ci-dessus fonctionne en trois parties. Il sélectionne d'abord la plage d'adresses IP pour effectuer une analyse ping par balayage en la divisant en plusieurs parties. Ceci est suivi de l'utilisation de la fonction, qui sélectionne la commande pour le balayage ping en fonction du système d'exploitation, et enfin, il donne la réponse sur l'hôte et le temps nécessaire pour terminer le processus d'analyse.

Production

Le script ci-dessus génère la sortie suivante -

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

La sortie ci-dessus n'affiche aucun port en direct car le pare-feu est activé et les paramètres entrants ICMP sont également désactivés. Après avoir modifié ces paramètres, nous pouvons obtenir la liste des ports actifs dans la plage de 1 à 100 fournie dans la sortie.

Scanner de port utilisant le scan TCP

Pour établir une connexion TCP, l'hôte doit effectuer une négociation à trois. Suivez ces étapes pour effectuer l'action -

Step 1 − Packet with SYN flag set

Au cours de cette étape, le système qui tente d'établir une connexion démarre avec un paquet dont l'indicateur SYN est défini.

Step 2 − Packet with SYN-ACK flag set

Dans cette étape, le système cible renvoie un paquet avec des ensembles d'indicateurs SYN et ACK.

Step 3 − Packet with ACK flag set

Enfin, le système initiateur renverra un paquet au système cible d'origine avec l'indicateur ACK défini.

Néanmoins, la question qui se pose ici est de savoir si nous pouvons effectuer une analyse de port en utilisant la méthode de demande et de réponse d'écho ICMP (scanner de balayage ping), alors pourquoi avons-nous besoin d'une analyse TCP? La raison principale derrière cela est que si nous désactivons la fonction de réponse ICMP ECHO ou si nous utilisons un pare-feu pour les paquets ICMP, le scanner de balayage ping ne fonctionnera pas et nous avons besoin d'un scan 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)

Le script ci-dessus fonctionne en trois parties. Il sélectionne la plage d'adresses IP pour effectuer une analyse ping par balayage en la divisant en plusieurs parties. Ceci est suivi par l'utilisation d'une fonction pour scanner l'adresse, qui utilise en outre le socket. Plus tard, il donne la réponse sur l'hôte et le temps nécessaire pour terminer le processus d'analyse. Le résultat = s. L'instruction connect_ex ((addr, 135)) renvoie un indicateur d'erreur. L'indicateur d'erreur est 0 si l'opération réussit, sinon, c'est la valeur de la variable errno. Ici, nous avons utilisé le port 135; ce scanner fonctionne pour le système Windows. Un autre port qui fonctionnera ici est 445 (Microsoft-DSActive Directory) et est généralement ouvert.

Production

Le script ci-dessus génère la sortie suivante -

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

Scanner de ports filetés pour une efficacité accrue

Comme nous l'avons vu dans les cas ci-dessus, l'analyse des ports peut être très lente. Par exemple, vous pouvez voir que le temps nécessaire pour analyser les ports de 50 à 500, tout en utilisant le scanner de port de socket, est 452,3990001678467. Pour améliorer la vitesse, nous pouvons utiliser le filetage. Voici un exemple de scanner de port utilisant le filetage -

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)

Dans le script ci-dessus, nous devons importer le module de threading, qui est intégré dans le package Python. Nous utilisons le concept de blocage de filetage,thread_lock = threading.Lock()pour éviter plusieurs modifications à la fois. Fondamentalement, threading.Lock () permettra à un seul thread d'accéder à la variable à la fois. Par conséquent, aucune double modification ne se produit.

Plus tard, nous définissons une fonction threader () qui récupérera le travail (port) de la boucle worker for. Ensuite, la méthode portscan () est appelée pour se connecter au port et imprimer le résultat. Le numéro de port est passé en paramètre. Une fois la tâche terminée, la méthode q.task_done () est appelée.

Maintenant, après avoir exécuté le script ci-dessus, nous pouvons voir la différence de vitesse pour analyser 50 à 500 ports. Cela n'a pris que 1,3589999675750732 secondes, ce qui est très inférieur à 452,3990001678467, temps pris par le scanner de port socket pour analyser le même nombre de ports de l'hôte local.

Production

Le script ci-dessus génère la sortie suivante -

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