Comment créer un scanner de réseau avec Scapy en Python

Par : TutorialsGrey, le 10 Juillet 2022

Un scanner de réseau est un élément important pour un administrateur de réseau ainsi que pour un Penetration Tester. Il permet à l'utilisateur de cartographier le réseau pour trouver les appareils qui sont connectés au même réseau.

Dans ce tutoriel, vous apprendrez à créer un simple scanner de réseau en utilisant les requêtes ARP et surveiller le réseau en utilisant la bibliothèque Scapy en Python.

 

Nous supposons que vous avez déjà installé Scapy. Si ce n'est pas le cas, n'hésitez pas de vous référer à la documentation officielle de Scapy.

Pour en revenir au sujet, il existe de nombreuses façons de scanner les ordinateurs d'un même réseau, mais nous allons utiliser l'une des méthodes les plus populaires, à savoir les requêtes ARP.

 

 

Tout d'abord, nous allons devoir importer les méthodes essentielles de Scapy :

from scapy.all import ARP, Ether, srp

Ensuite, nous allons devoir faire une requête ARP comme le montre l'image suivante :

Le scanner de réseau envoie une requête ARP demandant qui possède une adresse IP spécifique, disons "192.168.1.1", le propriétaire de cette adresse IP (la cible) répondra automatiquement qu'il est "192.168.1.1". Avec cette réponse, l'adresse MAC sera également incluse dans le paquet, ce qui nous permet de récupérer avec succès les adresses IP et MAC de tous les utilisateurs du réseau simultanément lorsque nous envoyons un paquet de diffusion (envoi d'un paquet à tous les appareils du réseau).

Notez que vous pouvez changer l'adresse MAC de votre machine. Donc gardez cela à l'esprit lorsque vous récupérez les adresses MAC, car elles peuvent changer d'un moment à l'autre si vous êtes dans un réseau public.

La réponse ARP est illustrée dans la figure suivante :

Alors, fabriquons ces paquets :

target_ip = "192.168.1.1/24"
# IP Address for the destination
# create ARP packet
arp = ARP(pdst=target_ip)
# create the Ether broadcast packet
# ff:ff:ff:ff:ff:ff MAC address indicates broadcasting
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
# stack them
packet = ether/arp

 

Remarque : Au cas où vous ne seriez pas familier avec la notation "/24" ou "/16" après l'adresse IP, il s'agit essentiellement d'une plage IP, par exemple, "192.168.1.1/24" est une plage allant de "192.168.1.0" à "192.168.1.255", veuillez lire plus sur la notation CIDR.

 

Maintenant que nous avons créé ces paquets, nous devons les envoyer en utilisant la fonction srp() qui envoie et reçoit des paquets au niveau de la couche 2. Nous avons fixé le timeout à 3 pour que le script ne soit pas bloqué :

result = srp(packet, timeout=3)[0]

Le résultat est maintenant une liste de paires au format (sent_packet, received_packet) ; itérons sur elles :

# a list of clients, we will fill this in the upcoming loop
clients = []

for sent, received in result:
    # for each response, append ip and mac address to `clients` list
    clients.append({'ip': received.psrc, 'mac': received.hwsrc})

Il ne nous reste plus qu'à afficher la liste que nous venons de remplir :

# print clients
print("Available devices in the network:")
print("IP" + " "*18+"MAC")
for client in clients:
    print("{:16}    {}".format(client['ip'], client['mac']))

 

Voici le code source complet de notre programme network_scanner.py :

from scapy.all import ARP, Ether, srp

target_ip = "192.168.1.1/24"
# IP Address for the destination
# create ARP packet
arp = ARP(pdst=target_ip)
# create the Ether broadcast packet
# ff:ff:ff:ff:ff:ff MAC address indicates broadcasting
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
# stack them
packet = ether/arp

result = srp(packet, timeout=3, verbose=0)[0]

# a list of clients, we will fill this in the upcoming loop
clients = []

for sent, received in result:
    # for each response, append ip and mac address to `clients` list
    clients.append({'ip': received.psrc, 'mac': received.hwsrc})

# print clients
print("Available devices in the network:")
print("IP" + " "*18+"MAC")
for client in clients:
    print("{:16}    {}".format(client['ip'], client['mac']))

Voici une capture d'écran de mon résultat dans mon réseau personnel :

 

 

Conclusion

Très bien, nous en avons terminé avec ce tutoriel, voyez comment vous pouvez l'améliorer et le rendre plus pratique pour remplacer d'autres outils d'analyse.

Si vous souhaitez scanner des réseaux WiFi proches, consultez ce tutoriel.

Et souvenez-vous, ne faites pas de copier-coller, écrivez vous-même le code pour mieux comprendre !