Breaking a 5G Core Network From the Inside
TL;DR — Ella Networks Core is an open-source 5G core written in Go, designed for private deployments like factories, warehouses, and stadiums. I found four vulnerabilities: a privilege escalation from NetworkManager to Admin via database restore, a self-deadlock in SCTP connection handling that freezes the entire control plane, and two nil pointer dereferences in NAS/NGAP message handlers that crash the process from crafted radio messages. No authentication required for the DoS attacks.
background
5G core networks are the brains behind cellular connectivity. They handle everything — subscriber authentication, session management, mobility, and routing. When a phone connects to a cell tower, the core network decides whether to let it on, what bandwidth it gets, and where its traffic goes.
Ella Core (ellanetworks/core on GitHub) takes the traditional 5G architecture — which normally involves dozens of microservices communicating over HTTP — and compresses it into a single Go binary. One process runs all network functions: AMF, SMF, UPF, AUSF, NSSF. Data lives in embedded SQLite. The eBPF-based data plane claims 10+ Gbps with sub-1ms latency.
It's small, fast, and designed for environments where a full 5G core would be overkill. Factories, farms, private campus networks. The kind of deployments where "restart the 5G core" means every connected device goes dark.
CVE-2026-33906: privilege escalation via database restore
Ella Core has three RBAC roles: Admin, NetworkManager, and ReadOnly. NetworkManager gets about 50 permissions covering subscriber management, radio configuration, and network operations. What it shouldn't get is PermBackup and PermRestore. But it did.
The restore endpoint accepts a SQLite file upload, validates that it's a valid database, and replaces the production database entirely. The attack:
- NetworkManager calls the backup endpoint — gets the current SQLite database
- Opens it offline, changes their own role from NetworkManager (3) to Admin (1) in the users table
- Uploads the tampered database via the restore endpoint
- The endpoint accepts it — it's a valid SQLite file
- NetworkManager is now Admin
The fix was a single line — removing PermBackup, PermRestore from the NetworkManager role.
// Before:
PermBackup, PermRestore, PermSupportBundle,
// After:
PermSupportBundle,
One line. The difference between "network operator" and "god mode."
CVE-2026-33904: SCTP deadlock freezes the control plane
In 5G, the radio base station (gNB) connects to the AMF over SCTP on the N2 interface. SCTP generates notifications when connections change state — associations forming, shutting down, aborting. The AMF must handle these to track which radios are connected.
The vulnerable handler in HandleSCTPNotification:
func HandleSCTPNotification(conn *sctp.SCTPConn, notification sctp.Notification) {
amf := amfContext.AMFSelf()
ran, ok := amf.FindRadioByConn(conn)
if !ok { return }
amf.Mutex.Lock() // acquires global AMF mutex
for _, amfRan := range amf.Radios {
// ...
amf.RemoveRadio(ran) // RemoveRadio also tries to lock amf.Mutex
} // DEADLOCK
amf.Mutex.Unlock()
}
amf.Mutex.Lock() grabs the global mutex. amf.RemoveRadio() internally tries to grab the same mutex. Self-deadlock. The entire AMF control plane hangs. No new registrations, no handovers, no session management. Every subscriber on the network is frozen.
The trigger is an SCTP notification — which happens whenever a radio connects or disconnects. No authentication needed. SCTP operates below the application layer.
The fix moved radio cleanup to a deferred function in the connection serve loop, running outside any mutex:
defer func() {
if ran, ok := amf.FindRadioByConn(conn); ok {
amf.RemoveRadio(ran)
}
}()
CVE-2026-33907: crashing the core with a bad auth response
NAS (Non-Access Stratum) is the signaling protocol between the phone and the AMF. During 5G-AKA authentication, the phone sends either an Authentication Response (with RES*) or an Authentication Failure (with AUTS for resync). The handlers assumed these fields would always be present:
// handle_authentication_response.go
resStar := msg.GetRES()
p1 := resStar[:] // PANIC if AuthenticationResponseParameter is nil
// handle_authentication_failure.go (SynchFailure case)
auts := msg.GetAuthenticationFailureParameter()
hex.EncodeToString(auts[:]) // PANIC if nil
No nil checks. A crafted NAS message with the expected information element missing crashes the entire process. This happens during the authentication procedure — before the subscriber is authenticated. A rogue device or software-defined radio can send these messages and kill the core.
The fix: nil checks that return errors instead of panicking.
CVE-2026-33903: NGAP message panics
Same class of vulnerability, different protocol layer. NGAP handles signaling between the radio and the AMF. Three handlers had nil dereferences:
- LocationReport: accessed
AreaOfInterestList.Listwithout checking ifAreaOfInterestListwas nil - NG Reset: missing
continueafter failing to find a UE — fell through toranUe.Remove()on a nil pointer - UE Context Release Complete: missing
continueafter SmContext lookup failure
Each one is a single crafted NGAP message away from crashing the core. No authentication at the SCTP/NGAP layer.
what this means
Private 5G is growing fast. Factories, warehouses, stadiums, mines — environments where cellular connectivity is critical infrastructure. When the 5G core crashes, it's not just "the internet is slow." It's forklifts losing their safety coordination, security cameras going offline, emergency communication failing.
The vulnerabilities here aren't exotic. A deadlock from holding a mutex while calling a function that acquires the same mutex. Nil pointer dereferences on optional protocol fields. An RBAC role with permissions it shouldn't have. These are the kind of bugs that exist because 5G core software is complex and the attack surface — raw SCTP from radio equipment — is unusual enough that standard web security review doesn't catch it.
All four fixed in Ella Core v1.7.0.
This research was conducted for responsible disclosure purposes. CVE-2026-33903, CVE-2026-33904, CVE-2026-33906, CVE-2026-33907.