Robot AntiARP
Un peu de programmation evenementielle. Comme vous avez pu le constater, l'ARP cache Poisonning constitue l'un de mes outils de prise de position d'homme du millieu. En effet, sachant qu'il est très difficile de créer des tables ARP statiques (ce n'est quasiment jamais effectué), j'ai eu l'idée de programmer un robot détectant les abérations dans les comunications ARP. Voici comment j'ai procédé.
Tout d'abord un bref récapitulatif du protocole ARP. Chaque ordinateur dispose d'un cache ARP associant à chaque adresse IP du réseau, l'adresse machine (MAC) du systeme correspondant. On peut voir le cache ARP très facilement en tapant:
root@iZyNumeriC:~# arp -a
iZyDigitaL.home (192.168.1.10) à 00:0e:9b:c4:f0:dd [ether] sur wlan0
HSIB.home (192.168.1.1) à 00:1f:95:58:fc:98 [ether] sur wlan0
Les tables ARP se mettent à jour, en général de manière dyamique par le biais de messages ARP. Par exemple:
La machine A voudrait savoir à qui appartient l'IP 192.168.1.11. Elle envoie un paquet ARP demandant "Qui possède l'adresse 192.168.1.11, répondez moi à l'adresse 192.168.1.1.10 (via mon adresse MAC : aa:aa:aa:aa:aa:aa)".
La machine B possède l'adresse 192.168.1.11. Elle envoie donc un paquet ARP à la machine A, à l'adresse IP / MAC indiquée dans le paquet, et met à jour son cache ARP en faisant corespondre aa:aa:aa:aa:aa:aa à l'adresse 192.168.1.10.
Le principe de l'ARP spoofing est simple. Supposons que cette fois, je veuille corrompre leur machine à l'aide de mon ordinateur i (192.168.1.12). J'envoie un paquet "Qui est 192.168.1.11, répondez à 192.168.1.10 à l'adresse machine "cc:cc:cc:cc:cc:cc". COmme ça la cible associera l'adresse IP de B à mon adresse machine ! etc... Astucieux et très facile à réaliser. Comment contrer ça. Voici un exemple de robot rudimentaire.
Tout d'abord, créons une fonction retournant le protocole du paquet et l'IP source:
def isARP(paquet):
try:
return paquet[ARP].psrc
except:
return 99
Commençons le script : nous avons besoin d'un seul parametre, l'adresse IP du routeur
if __name__ == '__main__':
if len(sys.argv) < 2:
print 'Syntaxe : !/.py <ip_routeur>'
exit(0)
ipR = sys.argv[1] #ip du routeur
Puis nous alons tenter de récuperer l'adresse machine du routeur. Scapy integre une fonction getmacbyip(ip) effectuant cette tâche. Cependant, si notre cache est déjà corrompu, le script sera erroné et donc inutile. On envoie donc un PING pour vérifier (facilement bloqué, mais bon, pas grand monde ne pense a installer un anti arp spoofer)
print 'Raffraichissement du cache ARP'
send(IP(dst = ipR)/ICMP(type = 'echo-request'))
macR = getmacbyip(ipR) #mac du routeur
On démarre la boucle conditionelle, le code semble suffisament commenté:
while 1:
a = sniff(count = 1, filter = 'host ' + ipR)[0]
source = isARP(a)
if source != 99 and source == ipR: #Si le paquet semble venir du routeur
macP = a[Ether].src #Récupération de l'adresse mac source
if macP != macR: #On compare avec le routeur
print 'Attention, spoofing ARP détécté de la part de ' + source + ' [' + macP + ']'
send(IP(dst = ipR)/ICMP(type = 'echo-request')) #On tente d'envoyer un ping pour récuperer l'ip
time.sleep(1) #On attend la réponse
sendp(Ether(dst = getmacbyip(ip))/ARP(op = 'who-has',pdst = ipR)) #On tente de réactualiser le cache ARP du routeur
Le code final sera donc :
#-*-coding:Utf-8-*-
from scapy.all import *
import sys,time
#-----------------------------------------
# Sigma NetMonitor
# by iZy_TeH_PariaH
# version : python 2.6
# 23 aout 2009
# Ubuntu
#contact : dreamofanolife@hotmail.fr
#-----------------------------------------
def isARP(paquet):
try:
return paquet[ARP].psrc
except:
return 99
if __name__ == '__main__':
if len(sys.argv) < 2:
print 'Syntaxe : !/.py <ip_routeur>'
exit(0)
ipR = sys.argv[1] #ip du routeur
print 'Raffraichissement du cache ARP'
send(IP(dst = ipR)/ICMP(type = 'echo-request'))
macR = getmacbyip(ipR) #mac du routeur
print 'Sécurisation de ' + ipR + ' ['+ macR + ']'
while 1:
a = sniff(count = 1, filter = 'host ' + ipR)[0]
source = isARP(a)
if source != 99 and source == ipR: #Si le paquet semble venir du routeur
macP = a[Ether].src #Récupération de l'adresse mac source
if macP != macR: #On compare avec le routeur
print 'Attention, spoofing ARP détécté de la part de ' + source + ' [' + macP + ']'
send(IP(dst = ipR)/ICMP(type = 'echo-request')) #On tente d'envoyer un ping pour récuperer l'ip
time.sleep(1) #On attend la réponse
sendp(Ether(dst = getmacbyip(ip))/ARP(op = 'who-has',pdst = ipR)) #On tente de réactualiser le cache ARP du routeur
Tout d'abord un bref récapitulatif du protocole ARP. Chaque ordinateur dispose d'un cache ARP associant à chaque adresse IP du réseau, l'adresse machine (MAC) du systeme correspondant. On peut voir le cache ARP très facilement en tapant:
root@iZyNumeriC:~# arp -a
iZyDigitaL.home (192.168.1.10) à 00:0e:9b:c4:f0:dd [ether] sur wlan0
HSIB.home (192.168.1.1) à 00:1f:95:58:fc:98 [ether] sur wlan0
Les tables ARP se mettent à jour, en général de manière dyamique par le biais de messages ARP. Par exemple:
La machine A voudrait savoir à qui appartient l'IP 192.168.1.11. Elle envoie un paquet ARP demandant "Qui possède l'adresse 192.168.1.11, répondez moi à l'adresse 192.168.1.1.10 (via mon adresse MAC : aa:aa:aa:aa:aa:aa)".
La machine B possède l'adresse 192.168.1.11. Elle envoie donc un paquet ARP à la machine A, à l'adresse IP / MAC indiquée dans le paquet, et met à jour son cache ARP en faisant corespondre aa:aa:aa:aa:aa:aa à l'adresse 192.168.1.10.
Le principe de l'ARP spoofing est simple. Supposons que cette fois, je veuille corrompre leur machine à l'aide de mon ordinateur i (192.168.1.12). J'envoie un paquet "Qui est 192.168.1.11, répondez à 192.168.1.10 à l'adresse machine "cc:cc:cc:cc:cc:cc". COmme ça la cible associera l'adresse IP de B à mon adresse machine ! etc... Astucieux et très facile à réaliser. Comment contrer ça. Voici un exemple de robot rudimentaire.
Tout d'abord, créons une fonction retournant le protocole du paquet et l'IP source:
def isARP(paquet):
try:
return paquet[ARP].psrc
except:
return 99
Commençons le script : nous avons besoin d'un seul parametre, l'adresse IP du routeur
if __name__ == '__main__':
if len(sys.argv) < 2:
print 'Syntaxe : !/.py <ip_routeur>'
exit(0)
ipR = sys.argv[1] #ip du routeur
Puis nous alons tenter de récuperer l'adresse machine du routeur. Scapy integre une fonction getmacbyip(ip) effectuant cette tâche. Cependant, si notre cache est déjà corrompu, le script sera erroné et donc inutile. On envoie donc un PING pour vérifier (facilement bloqué, mais bon, pas grand monde ne pense a installer un anti arp spoofer)
print 'Raffraichissement du cache ARP'
send(IP(dst = ipR)/ICMP(type = 'echo-request'))
macR = getmacbyip(ipR) #mac du routeur
On démarre la boucle conditionelle, le code semble suffisament commenté:
while 1:
a = sniff(count = 1, filter = 'host ' + ipR)[0]
source = isARP(a)
if source != 99 and source == ipR: #Si le paquet semble venir du routeur
macP = a[Ether].src #Récupération de l'adresse mac source
if macP != macR: #On compare avec le routeur
print 'Attention, spoofing ARP détécté de la part de ' + source + ' [' + macP + ']'
send(IP(dst = ipR)/ICMP(type = 'echo-request')) #On tente d'envoyer un ping pour récuperer l'ip
time.sleep(1) #On attend la réponse
sendp(Ether(dst = getmacbyip(ip))/ARP(op = 'who-has',pdst = ipR)) #On tente de réactualiser le cache ARP du routeur
Le code final sera donc :
#-*-coding:Utf-8-*-
from scapy.all import *
import sys,time
#-----------------------------------------
# Sigma NetMonitor
# by iZy_TeH_PariaH
# version : python 2.6
# 23 aout 2009
# Ubuntu
#contact : dreamofanolife@hotmail.fr
#-----------------------------------------
def isARP(paquet):
try:
return paquet[ARP].psrc
except:
return 99
if __name__ == '__main__':
if len(sys.argv) < 2:
print 'Syntaxe : !/.py <ip_routeur>'
exit(0)
ipR = sys.argv[1] #ip du routeur
print 'Raffraichissement du cache ARP'
send(IP(dst = ipR)/ICMP(type = 'echo-request'))
macR = getmacbyip(ipR) #mac du routeur
print 'Sécurisation de ' + ipR + ' ['+ macR + ']'
while 1:
a = sniff(count = 1, filter = 'host ' + ipR)[0]
source = isARP(a)
if source != 99 and source == ipR: #Si le paquet semble venir du routeur
macP = a[Ether].src #Récupération de l'adresse mac source
if macP != macR: #On compare avec le routeur
print 'Attention, spoofing ARP détécté de la part de ' + source + ' [' + macP + ']'
send(IP(dst = ipR)/ICMP(type = 'echo-request')) #On tente d'envoyer un ping pour récuperer l'ip
time.sleep(1) #On attend la réponse
sendp(Ether(dst = getmacbyip(ip))/ARP(op = 'who-has',pdst = ipR)) #On tente de réactualiser le cache ARP du routeur