从x为灵眸学习通过电磁泄漏特征检测偷拍摄像头

几个月前在b站刷到一个介绍”华为灵眸摄像头检测手持款 DF10”设备检测摄像头的视频,视频中除了普通Wi-Fi摄像头检测外还演示了检测一个笔状没有无线通信功能、电池供电的摄像头。 这就勾起了我的兴趣,他是使用什么技术做的检测,又能做到什么程度呢? 本文将从笔者所了解的几种检测方式开始,分享对此产品不完全的逆向分析,以及使用常见SDR设备复刻相似功能程序的测试效果。(PS.拖延太久,文章中部分内容有敷衍了事的迹象)

DF10介绍文档:

华为灵眸摄像头检测手持款 DF10 用户指南

(多媒体)华为灵眸DF10防偷拍使用指南

截至202606,此产品在电商平台似乎未正式开卖或者仅2b销售,咸鱼有部分展示机销售,2000元左右。

一些隐藏摄像头检测手段

粗浅见解,可能有误。

  • 红外:多数监控摄像头的夜视功能都是主动夜视,使用一些红外LED发出肉眼不可见的红外光。相机镜头组中增加一个可调的IR-CUT滤镜,白天正常启用仅可见光透过保证成像效果,夜晚关闭此滤镜,传感器接收红外光反射实现夜视。(这也是很多固定镜头组带两根线的原因,用于切换滤镜开关)。 通过不带红外滤镜的相机可以很明显的发现主动红外光源。也有检测红外光的设备。 但是显然除了监控摄像头外、不管是相机、手机还是偷拍的设备可能都不需要这种夜视功能,不需要红外LED,也就无法通过这种手段检测。

  • 镜头反射(猫眼效应?):市面上很多售卖的设备都带这个,通过一个LED发出人眼可见的红光,然后再透过红色透光玻璃/亚克力观看,有些镜头会有明显的反光痕迹。这种反光许多镜头是没有的,比如多数手机的镜头都不存在。

    • 我最初以为可能与红外滤镜有关,但拆了个摄像头的脉冲控制开关的镜头组(常拆摄像头的朋友都知道,镜头组上面带2根线的,通过脉冲信号控制开关)。测试后发现不管滤镜开/关,镜头组该有反光的还是有反光。
    • 这种光学or视觉上的识别也有其他更复杂的实现,比如利用Time-of-Flight Sensors的 LAPD 项目
    • 还有利用“猫眼效应”检测的方案。粗看相关介绍感觉与镜头反射的逻辑可能是一致的,不过相关的瞄准镜论文中都使用肉眼不可见的近红外NIR激光(750nm~1400nm),但可能纯粹是为了防止被发现。 eg: 基于空间上下文的猫眼目标激光主动探测方法研究一种基于“猫眼效应”的全天候手持式激光主动侦测装置
  • 无线电信号:这里先仅限于检测通信流量的,比如使用WiFi、蜂窝数据传输信号或控制指令的设备,自然会发射信号。缺点很明显:信号不是一定持续发射;信号强度、频率也跟现有的智能设备相似,易被干扰;纯本地或者有线传输的设备无法检测。 当然这也是偷拍窃听定位检测里面比较能引入技术的地方,有表现空间: 可调的宽灵敏度范围、指定频率的滤波与检测、初步(甚至深度)识别信号类型,高端设备实现的宽频持续监测等特性都可以让效果和使用体验显著提升。 市面上也有很多此类产品,像什么PRO-W12DX、 iProtect 1216或者类似Aaronia超宽频谱仪的高端设备。

  • 磁场: why?

  • 非线性节点探测器NLJD(non-linear junction detector): 原理上是谐波雷达,发射信号并检测二次三次谐波反射,来检测半导体器件(PN结)。常见的是2.4GHz(或S波段其他频率)附近发射,然后检测4.8GHz与7.2GHz附近的二次三次谐波反射。显然一个巨大的优点是不需要设备上电 。 很贵的设备没有玩过,但从使用教学和评测视频里不难看出一些缺陷: 如果环境不是完全可控的,很多电器、人体传感器、带充电头的墙插等都会被识别,不太好区分是否是恶意设备。全屋扫描也是很耗时的一件事情。 根据维基百科也有些知名的对抗方案:http://www.cryptomuseum.com/covert/bugs/ec/srt107/index.htm

  • 热成像:接收物体表面散发的红外辐射能量,生成可视化热图像以反映温度分布。这里要重点吐槽一下,经常能在各类视频/帖子的评论区中看到把热成像当作银弹的言论:”关了灯热成像扫一圈就出来了”等等。用热成像观测一个运行中的摄像头确实非常明显:

    p2_pizero

    但实际上热成像远远不是万能的解决方案,有些缺点是可以加钱解决的,比如分辨率太低。 但最大的缺点是热成像仪并不能像电影里一样穿透物体,如果摄像头隐藏在插座等位置其实是非常难观测到的,更别说插座、插座附近的设备本身就可能存在发热。 听到这里读者很可能觉得我在抬杠,认为这个缺点只是小小的削弱了热成像的效果。但许多人不知道的是目前主流的基于LWIR长波红外(8~14μm)的热成像仪,是不能够穿过透明的玻璃或者亚克力板的,下面用艾睿P2 Pro观察一下在摄像头前方放置一个透明亚克力的效果(视频中由于我手的温度传导到了亚克力上,在热成像中亚克力有些显眼):

在下文中还会再提到的一篇 综述文章 中作者画了一个比较炫酷的图来展示现有的一些摄像头检测方案 (可能缺少NLJD这类的?) :

Fig4_in_11343822

x力西五合一检测仪原理分析

型号MDK3003,据宣传和说明书描述有: 1. 1MHz-6.5Ghz,5厘米-10米宽频无线信号探测; 2. 磁场设备探测; 3. 红光(620-625nm)摄像头探测; 4. 振动报警检测; 5. 应急照明

mdk3003

拆开可以看到内部主要芯片有两个,一个是来自ADI的丝印为 J 5A 的AD8314射频检测器芯片。另一个是TSSOP20封装的主控,丝印被磨掉了。从部分引脚上推断可能是PY32F002B系列的,但是没有成功挂上SWD。

根据 AD8314的Data Sheet,其工作范围是100 MHz to 2.7 GHz。 使用信号源实测在3GHz时灵敏度下降不多,在5GHz时基本就无法进行有效检测了,紧贴发射天线,tinySA显示-30dBm时此探测器最高灵敏度也无法触发。 与宣传的1MHz-6.5GHz差距明显,5G WiFi信号也无法有效检测。

除了AD8314外还有:

  • X160 震动感应开关用来实现振动监测。
  • HAL248G全极性低功耗霍尔开关 用来实现所谓的”磁场检测”,这种霍尔开关只能近距离检测到磁场,并且是0/1输出。 实际效果还不如现代手机IMU都带的磁力计好。
  • 红光LED+一个红色亚力克片,用于实现前面提到的镜头反光检测,实测效果只能说一般般。

想办法学他一手

虽然我对这个DF10的好奇心非常强,但2000块买个这东西我还是干不出来。没有设备的情况下只能看看能不能搞到固件分析分析。

幸运的是通过逆向App Store中的”华为灵眸”(com.huawei.iguard)应用可以分析出手机与设备的蓝牙交互协议,以及获取app/firmware更新信息的url:
https://soho-cn1.qiankun-saas.huawei.com/public/dist/app/iguard/app_iguard/version

eKitEngineDF10_V600R025C01SPC100.cc 是设备固件。令我没想到的是固件包中除了有bootloader、main_app外还有一个应该是fpga bitstream的东西。根据字符串等信息推断mcu应该是泰凌微的B92-C1T266A20或相近型号, 而FPGA部分则是来自pango紫光同创

FPGA部分搜了下也没有现成的逆向方案,而且没有实际设备即使告知我内部逻辑也不一定能知道他在做什么。 于是将重心放在B92的固件上,最初我想可能是存在主动探测的机制,像NLJD一样,但是没有找到证据,同时CMIIT ID 26J440HW5258的核准也显示只有蓝牙频段的发射。

最终结合AI逆向得出的分析结论(不一定对)大致是:

MCU通过FPGA控制射频前端扫描792MHz~945MHz中三个频率附近的信号局部峰,并且按频点与偏移统计合并,达到分数则认为是可疑目标。分组都是24MHz或27MHz间隔,根据地区和扫描模式变动具体频率。

区域组合:

区域值 UI区域 group0 group4
0 亚太/非洲/南美 792, 816, 840 810, 837, 864
1 欧洲/中东 840, 864, 888 837, 864, 891
2 北美 888, 912, 936 891, 918, 945

叠加检测模式后:

  • 增强/标准:扫 group0 + group4
  • 快速:只扫 group4

从设备与APP的蓝牙交互协议和APP本身的代码看目前版本应该是没有检测具体摄像头种类/品牌的能力,仅仅展示可疑目标和信号强度。

一些蓝牙相关的内容:

  • app scans names containing lower-case huawei-df

    • service 0000FFF8-0000-1000-8000-00805F9B34FB

    • write 0000FFF6-0000-1000-8000-00805F9B34FB

    • notify 0000FFF7-0000-1000-8000-00805F9B34FB

    • frame: u16be cmd | u16be payload_len | payload

1
2
3
4
5
6
7
0x0001 ack, 0x0002 periodicReport, 0x0003 keepAlive, 0x0004 generalRequest,
0x0005 generalResponse, 0x0006 queryLogAndAlarm, 0x0007 upgradeStart,
0x0008 upgradeTransmission, 0x0009 upgradeFinish, 0x000A deviceOperation,
0x0100 version, 0x0101 esn, 0x0102 timeSync, 0x0103 nameConfig,
0x0104 status, 0x0105 battery, 0x0106 detectionHistory, 0x0107 detectionReport,
0x0108 detectionProgress, 0x0109 queryLog, 0x010A emtOperation,
0x010B cameraConfig, 0x010C collectData

AI产出的固件下载、解包、ble脚本: DF10_scripts

通过晶振谐波电磁泄露检测摄像头

从上面可以看出设备大概率是一个纯被动的射频信号探测器, 通过探测配置好的三个一组频点周围的局部信号峰来检测摄像头,频率间隔都为24MHz/27MHz。 比如792.03MHz、816.03MHz、840.03MHz都存在局部信号峰,并且满足一定要求,则认为存在可疑设备,且会生成并显示信号强度来帮助用户判断距离。

根据24/27 MHz间隔这个特征,可以看出很有可能是跟晶振频率有关,据此搜索了下相关论文,发现几篇相当符合的研究:

其中CamRadar是我找到的最早针对摄像头中晶振产生的时钟信号可能耦合到线缆或其他信号中,导致意外的泄露出部分信息(这里是摄像头存在这个事情), 同时论文也分析了不同fps下、开关/闪烁灯光、AM解调、相机传感器电压等变化时此类电磁泄漏的变化情况。 主要的测试设备为USRP B210+FST-RFAMP01低噪放+3dbi全向天线,频率范围在200MHz-800MHz, 测试了19个摄像头。很专业和完善的测试,推荐阅读。

随后CamDetector中将泄露聚焦在晶振时钟信号耦合到CSI排线上的行为,并且展示了不同视频参数的情况下带来信号的变化。主要测试的频率范围是100MHz–500MHz

Eye of Sauron 则是另外检测了的内存带来的泄露,并且宣称通过灯光刺激加内存泄露信号检测能达到20m距离,且有极好的检测准确度。

CamFirm则提出一个通过有线耳机当作天线,用手机内置(or 外置)FM模块在FM广播所用的频率上,以低成本非专用设备检测摄像头的方案。

在最近的一篇综述中,作者比较系统的讲了下网络流量、光学/热成像、EMR电磁辐射检测摄像头的方法,以及通过机器学习以及多种方式结合进一步增强效果的展望。 Hidden Camera Detection in Smart Environments: A Comprehensive Survey of Current Methods, Challenges, and Future Perspectives

复刻与测试

首先掏出Airspy mini+一个20db的LNA+一根拉杆天线。 直接观测几个摄像头在上电状态下在刚才分析的24MHz、27MHz高次谐波频率附近是否存在泄露的信号峰。

找的手边第一个摄像头就发现了明显的信号峰:

cam_on_sdrsharp

拔电源后几秒的样子:

cam_off_sdrsharp

并且在相关间隔频率也能找到对应的泄露信号。 确认了思路可行后vibe一套可以通过配置设定几乎所有参数(扫描频率组、fft参数、跳频扫描参数、达标分数阈值等)的工具(链接在结尾)

我使用airspy检测24MHz与27MHz间隔组泄露的示例配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
name = "best_high_airspy"
offset_model = "ppm"
min_hits = 3
min_score = 20.0
max_offset_spread_hz = 1200.0

[[groups]]
name = "24mhz"
freqs_mhz = [792.0, 816.0, 840.0, 864.0]

[[groups]]
name = "27mhz"
freqs_mhz = [810.0, 864.0, 918.0, 945.0]

[scan]
peak_search_window_hz = 250000.0
min_peak_snr_db = 4.0
max_peaks_per_freq = 12
record_spectrum_bins = 128
record_band_decimation = 1
output = "tui"

[device]
backend = "airspy"

[device.airspy]
device_index = 0
sample_rate_hz = 3000000
dwell_ms = 300
fft_size = 65536
dc_notch_hz = 2000.0
settle_ms = 40

[device.airspy.gain]
mode = "manual"
preset = 18
lna = 15
mixer = 15
vga = 2
lna_agc = false
mixer_agc = false

cargo run -- scan --profile profiles/best_high_airspy.toml 启动下图的界面:

camfinder

图里+21ppm的疑似目标是我环境中某个一直存在的干扰。 -25ppm的是一个天地伟业的poe监控摄像头,也就是下文的CAM1(这里也能看出来频率的漂移,这个摄像头在运行一段时间后基本会稳定在-30ppm左右)。

后续对手边的一些摄像头进行了测试,泄露最严重的能在3m开外检测到,而有部分设备的有效检测距离只有不到30cm。当然我的两个测试环境都无法屏蔽外界射频信号,能明显感受到其他通信信号的干扰。环境a中837MHz附近基本不可用,有大量信号,而在环境b中则非常干净,是很好的泄露检测频段。

过程中观测到同设备同间隔组(比如27Mhz)上的泄露频率波动其实很频繁,也就是偏移频率会不断变动。不同频段的偏移也不完全一致且不断波动,距离、位置、朝向都会有明显变化。 中间推测可能用ppm会好一些,加入了ppm而不是hz的聚类模式,但最终观测下来未发现明显优于hz的表现。

主要测试的几个摄像头:

7cam_1

7cam_2

以及一个懒得拍照的TP-Link家用摄像头,称为7。下面是测试过程中的表现记录(仅供参考,许多变数):

  • CAM1 -30ppm(27M) 1m时100分
  • CAM2 +67ppm(24M/27M) 24M时0.5m190分 27M只有60
  • CAM3 +10ppm(27M/24M) 24M表现好1m80分,27M>50cm丢一个泄露频点
  • CAM4 -27ppm(24M) 激活后才有,取消激活不会消失 1M 100多。 另外有+10ppm,激活后有,偏弱。 激活后再取消激活后还会多出-27ppm(27M)
  • CAM5 这个是25M晶振 25M的泄露,启动后从-6慢慢漂移到-12左右稳定。 0.4m 130左右score。
  • CAM6 +14ppm(24M) 0.5m 80分
  • CAM7 -16ppm(27MHz) 靠近10cm左右才有

这里有两个比较特殊的目标,一个是cam4 一个usb的摄像头,并不独立运作,测试中发现使用主机激活摄像头后才开始出现电磁泄漏,但是关闭并不会消失,而且有多个泄露。

cam5是一个pizero用的摄像头,最初使用检测其他摄像头的24MHz/27MHz间隔组没有成功检测到,查看镜头组附近的晶振发现是25MHz的,遂切换25MHz的间隔组,成功检测到泄露, 这也证明了24/27MHz显然不能覆盖所有常见摄像头种类。

25mhz

另外还测试了三个设备:

other3

Pocket4 用当前的方案检测不到,但是其实不是完全没有泄露,人工搜寻可以发现: 918.525MHz存在较强泄露 40cm可侦测 854.013也有。 但是可以看到这两个频率本身就不太有相关性,更没有以固定间隔组的形式出现。

Nikon Z6微单与SONY的ICD-PX470录音笔都没有观测到可辨识的泄露信号峰。

尝试使用了:做EMC检测的近场探头、指向性强的对数周期天线、有源小环天线,没有发现距离和信号强度优势,个人认为主要决定检测距离和检测效果的还是摄像头自身的泄露情况。

结尾

整个分析与复现过程我都没有接触过实际的DF10设备,所以对具体电路+FPGA+射频前端部分一无所知,对真实设备的效果不做任何预估。

复刻的过程中可以发现通过晶振谐波电磁泄漏检测是有效果的,但绝对不是Silver Bullet。 能否检测与许多内容强依赖,设备也有比较简单的方法来避免发生电磁泄漏:

  • 目标本身的构造,比如是否具有屏蔽罩,使用的晶振频率,外壳材质,内部走线方式,供电的电源等 (最主要)
  • 目标和检测设备/天线的位置、朝向、距离等
  • 非摄像头也可能存在此类电磁泄露

我使用的设备是airspy mini + 20db LNA(Zenkoo的ZK06-BM/研新电子的20dB) + 几种天线 。 其中LNA可以认为是必须的,测试单独使用b210/Airspy mini都不能有效的捕获泄露信号。

此方案有许多可能的优化空间本次没有探索,比如前文引用论文中提到的: 灯光闪烁引起泄露变化FM/AM调制后分析DDR内存读写泄露以及优化射频前端等等。

工具链接: https://github.com/leommxj/camfinder 。 实际效果主要看profile内的配置。目前支持airspy/soapy两种backend。