TransWikia.com

Forge UDP checksum

Server Fault Asked by wullxz on November 4, 2021

We’re having some IPSec connection problems that seem connected to the UDP checksum beeing (incorrectly) set with some ISPs.
To investigate further, I want to reproduce the error within a controlled environment.
Now, I do not know what the ISP does exactly so I’d like to manipulate UDP packets directly to reproduce a given scenario (UDP checksum missing, set correctly and set incorrectly).

The client: A linux machine with some tools (perl, iptables, gnu tools, bash, tcpdump)
The server: A freeBSD based machine with almost no tools (bash, pf, tcpdump)

I want to test how the server reacts with different UDP checksum situations.
Since it doesn’t have much tools, I figured the easiest way to reproduce these situations would be from the linux client.
I know there is the possibility to set the UDP checksum using the mangle table.
That only allows me to correctly set the UDP checksum.

How do I forge the UDP checksum of packets to be either nonexistent, correctly set or incorrectly set?

Any ideas on how to reproduce these scenarios – maybe in a different way – are also welcome in the comments.

One Answer

I found a way to hook a python script into the mangle table and alter the packets using that python script. The performance is understandably quite slow but for a testing purpose sufficient.

The python3 script looks like this (using scapy and NetfilterQueue):

from netfilterqueue import NetfilterQueue as nfqueue
from scapy.all import *
import os

iptablesr = 'iptables -t mangle -A POSTROUTING -p udp --dport 4500 -j NFQUEUE --queue-num 1'
print("Adding iptable rules: ")
print(iptablesr)
os.system(iptablesr)
def alter_callback(packet):
  print("=======================")
  pkt = IP(packet.get_payload())
  pkt.show2()

  udp = pkt.getlayer(UDP)

  del pkt.chksum
  #del udp.chksum
  udp.chksum = 0x111 # set udp checksum to something else

  pkt.show2()

  print("=======================")
  packet.set_payload(bytes(pkt))
  packet.accept()

def main():
  q = nfqueue()
  q.bind(1, alter_callback)
  try:
    q.run()
  except KeyboardInterrupt:
    q.unbind()
    print("Flushing iptables.")
    os.system("iptables -t mangle -F")

if __name__ == "__main__":
  main()

Answered by wullxz on November 4, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP