Search code examples
pythonscapy

Modifying received packet src/dst using scapy


I am trying to sniff my wifi for received packets. When I receive an ftp packet, I reverse the source and destination (Mac address, IP address and ports) and then send them back again.

However when I check wireshark, I find that the modified packet sent has an error "[Malformed Packet] [ETHERNET FRAME CHECK SEQUENCE INCORRECT]" although I deleted the checksums before I send the packet back. Below is the function I defined to modify received packet src/dst:

def modify_packet(pkt):
    source_mac_address = pkt[Ether].src
    destination_mac_address = pkt[Ether].dst
    destination_address = pkt[IP].dst
    source_address = pkt[IP].src
    destination_port = pkt[TCP].dport
    source_port = pkt[TCP].sport


    pkt[Ether].dst = source_mac_address
    pkt[Ether].src = destination_mac_address
    pkt[IP].dst = source_address
    pkt[IP].src = destination_address
    pkt[TCP].dport = source_port
    pkt[TCP].sport =  destination_port

    del pkt[IP].chksum
    del pkt[TCP].chksum

    send(pkt)
return

Solution

  • Scapy has not implemented Ethernet checksums because they are unpredictable: as said on wireshark's doc

    Most Ethernet interfaces also either don't supply the FCS to Wireshark or other applications, or aren't configured by their driver to do so; therefore, Wireshark will typically only be given the green fields, although on some platforms, with some interfaces, the FCS will be supplied on incoming packets.

    If you know a packet has a checksum however, it probably exists as a Padding Layer at the end of the Scapy packet you are processing. If that is the case, you can probably remove it without much issues.

    You could try something like

    if Padding in pkt:
        pkt[Padding].underlayer.remove_payload()
    

    To remove it.

    Another note: you need to use sendp() instead of send() when you are dealing with layer 2 packets (in this case: the ethernet frame)