Fieldwatch配对洪泛告警原理揭秘:PairingFlood如何在几秒内识破大规模蓝牙伪装广播
【免费下载链接】FieldwatchReceive-only Wi-Fi and Bluetooth LE observer for Android. MIT.项目地址: https://gitcode.com/gh_mirrors/fi/Fieldwatch
Fieldwatch 是一款运行在 Android 上的只收型 Wi-Fi 与蓝牙 LE 观察者工具,它的核心安全功能之一,就是用 PairingFlood 配对洪泛检测器,在几秒内识别出"单个设备疯狂换地址、伪造海量配对广播"的大规模蓝牙伪装行为。这篇文章带你看懂它的判定逻辑。
先搞懂威胁:什么叫"配对洪泛"?
蓝牙广播里有一类"配对请求"广告(pairing advertisement),正常场景下你在店里看到几台待售耳机、手表在喊"快来配对我",这很正常。
但攻击者可以拿一台手持设备(如 Flipper Zero,或跑着 Marauder / Bruce 的 ESP32),每个广播包换一个随机蓝牙地址,同时发出配对广播,几秒内就能在你的手机屏幕上刷出一大片"新设备"。源码注释说得很直白:
"A burst of new Bluetooth addresses in a few seconds. A handheld can do this by advertising a pairing request or a new name and changing the address every packet." ——PairingFlood.kt 注释
关键点是:广播内容本身不会自报家门("The advertisement does not name the tool"),所以 Fieldwatch 不用"查证件",而是用行为统计来抓人。
原理一:10秒滑动窗口,只数"新面孔"
PairingFlood 的核心是一个约10 秒的滑动窗口(WINDOW_MS = 10_000):
- 只数新地址:每个 MAC 地址在整个窗口里只被计一次,同一地址重复广播不算数(macs 集合去重);
- 地址出了窗口就过期:每来一个新地址或每次 tick,就把 10 秒前的记录清掉(evict);
- 双计数器: | 计数器 | 阈值 | 含义 | |---|---|---| | 配对广播(popup) |≥ 10个新地址 | 10 秒内 10 个不同地址发配对广告 → "Pairing flood" | | 纯改名(name) |≥ 15个新地址 | 随机地址 + 只带名字广播 → "Name flood" |
阈值定义在 companion object。也就是说,"识破"发生在一个 10 秒窗口内的瞬间计数,而不是等一段时间慢慢攒。
数据入口在扫描服务:每批 BLE 观测入库后,只有首次被看到的地址(hitCount == 1)才会喂给检测器,见 ScanService.kt。
原理二:六大"配对家族"识别——只有真配对才算 popup
不是所有广播都算"配对洪泛"。classify() 会解析厂商广告数据,命中以下任一"家族"才计入 popup 计数器:
| 家族 | 识别特征 |
|---|---|
| Apple 邻近配对 | 公司 ID 0x004C,Continuity TLV 类型 0x07 |
| Apple Nearby Action | 0x004C,TLV 类型 0x0F |
| Google Fast Pair | FE2C 服务数据 +3 字节型号 ID(配对模式),长载荷的账号密钥广播不算,见 FastPair.kt |
| Swift Pair | 0x0006,Nearby Sharing 场景 0x01 或特定 Swift Pair 信标 |
| Samsung Easy Setup | 0x0075,耳机或手表的固定前缀 |
| LoveSpouse | 0x00FF + 固定 8 字节前缀 |
这些家族共享一个计数器——10 个 Apple + 3 个 Fast Pair 一样触发。而 Apple 的"附近信息/查找"(0x10/0x12)、SmartTag 之类的载荷会被明确排除。单元测试覆盖了这些边界,如 PairingFloodTest.kt。
原理三:RSSI 中位数带宽,挡住"分散的群众"
商场里确实可能同时存在 15 台待售耳机——它们会触发吗?不会。因为 band() 做了一道信号强度过滤:
- 取窗口内所有候选地址的 RSSI(信号强度)中位数;
- 只保留与中位数相差±12 dBm以内的地址(RSSI_BAND_DB = 12);
- 过滤后数量仍 ≥ 10 才告警。
逻辑很朴素:一台手持设备刷出来的地址,信号强度几乎一样;而散落在店铺各处的真设备,信号强弱差异巨大,会被带宽过滤拆散。测试 spreadOutRadiosDoNotTrip 专门验证了"10 台强弱各异的设备不触发",而 aWeakPairingClusterStillOpens 验证了"再弱的聚集信号也会触发"。
触发之后:弹窗、留痕、可隐藏
跨过阈值的那一刻,PairingFlood 会:
- 弹出 Notice 对话框:标题 "Pairing flood",一行摘要如
Pairing flood · 10 new addresses · about -48 dBm(Notice.line()),正文还会列出命中的家族; - 给出两个选项:Continue(保留在 Live 视图约 15 分钟)或Hide these(把这一波burst及其后续从 Live 视图隐藏,但日志仍保留),见 body();
- 记录 FloodBurst:时间戳、数量、家族、中位 RSSI、涉及的地址全部存档(FloodBurst),之后会写进 sit 报告的 Debrief 里,形成可回溯的证据链。
姊妹机制:Wi-Fi Beacon Flood
蓝牙的思路被原样搬到了 Wi-Fi:WifiBeaconFlood 检测单次完整扫描中出现 ≥ 15 个全新网络名、信号强度相近(±6 dBm)、下一轮扫描就消失的模式——这正是 Flipper Zero 或 ESP32 刷 SSID 的典型特征。重复出现的名、mesh、信号扩展器和 guest 后缀(-5ghz / -ext 等)都会被归一化排除。
小结:行为统计胜过特征库
| 设计 | 作用 |
|---|---|
| 10 秒窗口 + 只数新地址 | 抓住"瞬时爆发",忽略常态广播 |
| 六大配对家族白名单 | 只认"真配对",排除查找类/标签类噪声 |
| RSSI 中位数 ±12 dBm 带宽 | 排除物理分散的正常设备群 |
| FloodBurst 落档 + 15 分钟策略 | 告警后可隐藏、可回溯、不刷屏 |
Fieldwatch 没有依赖任何设备特征库或云端,纯靠"新地址 × 时间 × 信号形态"三个维度,就实现了对伪装广播的秒级识别。想深入了解每个阈值的边界行为,可以通读单元测试 PairingFloodTest.kt;安装与使用说明见 Fieldwatch_User_Manual.pdf。
【免费下载链接】FieldwatchReceive-only Wi-Fi and Bluetooth LE observer for Android. MIT.项目地址: https://gitcode.com/gh_mirrors/fi/Fieldwatch
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考