pythonscapypacketpenetration-testingip-fragmentation

Using Scapy to send Fragment Packets with random Offsets


I would like to send fragmented packets size of 8 bytes and a random starting offset. Also want to leave out the last fragmented packet.

So far I got everything except the fragment of

from scapy.all import *
from random import randint
dip="MY.IP.ADD.RESS"
payload="A"*250+"B"*500
packet=IP(dst=dip,id=12345,off=123)/UDP(sport=1500,dport=1501)/payload
frags=fragment(packet,fragsize=8)
print(packet.show())
for f in frags:
    send(f)

What does the above code do? It sends IP Fragment Packets size of 8 byte to a destination IP address.

I would like to send IP Fragment Packets with a random Frag Offset. I can't find anything about fragment() and the only field, I was able to edit was in IP packet instead of each fragmented IP packet.

Does someone have an idea to accomplish this?

Infos: Python2.7, latest version of scapy (pip)


Solution

  • If you want to generate "broken" fragment offset fields, you have to do that yourself. The scapy fragment() function is simple enough:

    def fragment(pkt, fragsize=1480):
        """Fragment a big IP datagram"""
        fragsize = (fragsize + 7) // 8 * 8
        lst = []
        for p in pkt:
            s = raw(p[IP].payload)
            nb = (len(s) + fragsize - 1) // fragsize
            for i in range(nb):
                q = p.copy()
                del(q[IP].payload)
                del(q[IP].chksum)
                del(q[IP].len)
                if i != nb - 1:
                    q[IP].flags |= 1
                q[IP].frag += i * fragsize // 8          # <---- CHANGE THIS
                r = conf.raw_layer(load=s[i * fragsize:(i + 1) * fragsize])
                r.overload_fields = p[IP].payload.overload_fields.copy()
                q.add_payload(r)
                lst.append(q)
        return lst
    

    Source: https://github.com/secdev/scapy/blob/652b77bf12499451b47609b89abc663aa0f69c55/scapy/layers/inet.py#L891

    If you change the marked code line above, you can set the fragment offset to whatever you want.