LimeSDR学习笔记(3) ASK信号收发,分析与攻击

在这篇文章里我将讲解基本的收发ASK信号的要点,和怎样利用现有的工具针对ASK信号进行攻击。

什么是ASK信号

ASK(Amplitude Shift Keyring)即幅移键控信号,是很多简单的无线通信设备常用的调制方式。它的调制方式决定了它成本很低,但是相对地范围比较近,传输带宽也不高,所以一般常用在遥控器,简单的传感器之类的东西上。最常见的应用是汽车钥匙,大门遥控,无线门铃等等。同时,因为这些设备非常简单,对于传输的数据的校验也并不复杂,所以针对ASK信号的攻击相对容易。

ASK的种类和调制方法

最常见的ASK调制方法是ASK2,大部分钥匙,诸如汽车钥匙,遥控等等都是使用的这种调制方式。ASK2调制是直接将二进制信号调制在载波上,二进制信号一位表示0或者1两种状态,所以被称为ASK2。具体的调制方法如下图:

最上面是要传输的二进制信号,第二个是载波信号。因为是幅度调制,所以直接做乘法就可以获得调制后的信号,即第三个。第三个也被称为OOK(On-Off Keyring)。但是现实中,几乎不可能完全消除信号中幅度低的部分。而且即使能够完全消除,也会导致接收器在测量频率的时候随机地发生变化(因为中间部分信号完全消失即频率是0,如果采样率不一致或者采样点有相位差很容易获得奇怪的频率),所以实际上更常用的是第四种BASK(Binary ASK),最高幅度和最低幅度之间的差别足够大,可以被接收器分辨出来。

ASK4是一种相对少见一些的调制方式。它基本和ASK2一样,不同的是调制的原始信号是4种状态,即00,01,10,11。这样就可以将传输带宽翻倍。

ASK信号的攻击手段

与其他无线信号一样,ASK信号的攻击方法也无外乎几种:录制解码,伪造信号,以及重放。信号的录制和解码非常容易,因为针对不同的目标,使用的频率基本是固定的。解码也没有什么难度,甚至直接靠肉眼都可以看出来调制的信息。但是伪造信号的难度会相对大一些。

ASK信号的捕获

理论:ASK信号的解调

ASK是一种将信号调制到载波上,用幅度的变化来表示信息的调制方式。那么在接收端收到之后,就需要对其进行解调以恢复数字基带信号。对于ASK在生活中的应用,因为我们测试的时候信噪比比较高,也不需要很高的准确度,所以采用非相干解调的方式比较常见。

什么是非相干解调

通常来说解调方法分为两类,即相干解调和非相干解调。通俗地来说,相干解调需要获取载波的频率和相位信息,也叫同步检波,能够比较好的对所有线性调制进行解调。进行相干解调的时候,需要在接收端通过获取的信号,恢复出一个与载波同频、同相的相干参考信号,然后将参考信号和输入信号相乘。这样能够最大限度地恢复基带信号的信息,但是可以想到,对计算量或是硬件复杂度要求比较高。而非相干解调不需要获取载波的相位信息,也叫包络检波,恢复出来的信号质量略差,但是硬件和软件实现比较简单。非相干解调原理非常简单,硬件实现用一个二极管和低通滤波器就可以了,不过需要先保证信号全部是非负,可以加上直流分量来确保。除了使用低通滤波器,在软件层次的解码还可以利用移动平均值的方法,我在下面的例子中用的就是这种方法。

SDR实现的ASK解调

对ASK信号的解调方法非常多样,我在例子中使用的是最简单的一种。基本思路是,通过非相干解调,以某种方式去掉高频分量,只留下来低频或者说平滑的分量。之后送进比较器,用一个时钟驱动进行采样。这个时钟的来源是时钟恢复,通过运算已经经过包络的低频分量来获取它的时钟信息,用来在合适的时候进行采样,避免被边沿畸变干扰。

频段确定

上文提到对于一定的设备,使用的频段是固定的。例如对于汽车遥控器和门的遥控器,中国的频率一般在314~316MHz,430~432MHz,433.00~434.79MHz这几个频段。根据中国法律的要求,不允许使用这一通信方式控制玩具等产品,针对这类产品的攻击我们在以后继续讨论。而欧美常用的频率落在868MHz/915MHz上,这一频段在中国几乎没有用于微距离通信的。除了靠经验来推测,如果能拿到设备本身,还可以通过直接观察内部芯片和电路的方法,或者采用示波器等测量的办法来获得所需的频率。

信号的录制

能够直接录制信号的办法很多。大部分的频谱分析工具都有录制功能(CubicSDR,GQRX,甚至安卓系统下的RF Analyzer等等),所有的无线分析工具也都有录制功能或者录制插件,比如我们这次要使用的URH。当然GNURadio也是录制和处理信号的很好的工具。

GNURadio录制原始信号

GNURadio录制ASK信号有两种思路,第一种是直接录制成一个波形文件,之后用别的工具打开波形文件分析信号。这一操作非常简单,一个LimeSDR Source,接一个Throttle(不接也没什么大问题),直接接到File Sink上就可以。当然GNURadio的能力远远不止这些,完全可以用GNURadio实现一个直接把信号转换成二进制串保存至文件的接收器,和一般的ASK接收器一样。流图如下:

下面具体介绍一下流图中的模块。可以看到从SDR接收到的信号先通过DC Blocker,这是一个直流分量滤波器,因为在AM信号中往往都会有直流分量,特别是在信号的最低值没有在0的时候,滤除直流分量之后的信号在表示0的时候基本稳定在0上,此时的信号乘以10作一个放大之后,送进RMS计算。RMS计算的是信号的方均根,也就是功率有效值。可以参考一下上面介绍的ASK调制的图样,因为无法通过无线信号发送数字信号(数字信号的带宽是正无穷,从0到无穷的频率上都有分量),所以信号必须调制到载波上。而ASK最常见的解调方法就是计算RMS,可以把一段幅度比较大的调制信号解调到数字信号1(或者别的什么状态)上。经过RMS之后的信号基本就是高低电平表示的信号了,在边沿处有畸变,不过这是无法避免的问题。经过RMS的信号被加一个常数,以将中心调至以0为对称,因为下面要进行M&M时钟恢复,而经过RMS的信号是完全非负的,也没有直流分量。因为ASK信号传输是非时钟同步传输,传输双方的时钟是没有经过同步的。只有恢复了时钟信号,才能准确地进行采样。绝大部分数字接收机都有时钟信号恢复器,而在SDR中这一过程由定时误差检测算法实现。时钟恢复是一个非常复杂的过程,如果有兴趣的话可以参考一下这几篇文章(需要一定的信号处理方面的基础知识才能看懂):

一文看懂时钟是怎么恢复的 一种改进的定时误差检测算法这不是本文中使用的算法,但是可以了解一下定时误差检测的基本思路。

时钟恢复模块输出的直接是经过调试采样的float信号值,之后送入Binary Slicer,从正负浮点数(因为进入时钟恢复模块的信号关于0对称)转换为二进制0和1。之后写入文件。所以文件记录下来的不是波形而是二进制串。

使用URH直接录制信号

URH本身能够录制一段信号用于分析。点击File->Record就可以打开录制界面,在左侧设置好参数就可以点击开始录制,录制过程中接收机收到的Scale-Time图会在右侧展示。完成录制之后URH会自动加载刚刚录制的信号用于分析。

ASK信号的分析

其实ASK信号没有什么需要分析的……因为不同的硬件不同的系统虽然用的都可能是ASK调制,但是传输的东西的格式和结构可能不一样,大部分的没有什么规律,所以依靠重放攻击比较常见。但是如果需要修改信号内容就需要分析信号了,这在利用滚动码加密的系统上比较常见。除了上面介绍的利用GNURadio直接分析的方法,更常见的是利用URH分析(因为URH的一键处理比GNURadio好用……)URH的确是一键处理,没有什么需要讲解的。

ASK信号的攻击利用

判断信号模式

首先需要明确的是,你需要攻击的信号是什么类型。常见的使用ASK的遥控信号有几种:

  • 普通信号,只是在单一频率下发送固定的二进制串来遥控设备。比较便宜的例如门铃,报警器,和对安全性要求不高的例如卷闸门等系统都是这种方式。
  • 跳频/多频段信号:信号在多个中心频率之间不断切换,或者多个相近的频率同时发送信号。这种设计有几个目的,一方面无线电分析设备不能用同一个信道在多个中心频率上发射,如果跳频速度太快,SDR类的设备也一般跟不上,加大了攻击难度;第二方面针对一些特殊的攻击形式(如下文要讲到的RollJam)有一定的防护作用。
  • 滚动码加密:滚动码加密分为直接嵌入滚动码和用滚动码运算两种。滚动码是一种保护措施,在遥控器和接收器中同时保存有一段很长的滚动码,每次截取一段固定长度的用于发送,如果两方的滚动码对不上(因为考虑到实际情况,滚动码会接受当前码字后面一段的码字,而不是只有下一个,这一个范围被称为窗口),就拒绝执行指令。最常见的应用是车钥匙。
  • 双向验证机制:有时候遥控不只是发射器还是接收器,在被遥控设备接收到一个指令之后,会发送一个确认请求,遥控器收到请求进行确认,目标才会执行。这种双向运行的方式破解会难很多。

判断滚动码的应用模式

要判断设备是否使用滚动码很简单,连续按几次同样的按键,查看每一次发送的内容是否相同。如果不相同,大概率是用了滚动码。此时进一步观察信号,每次的信号不应该完全不同,最基本的帧头和帧尾应该是不变的。找到不变的部分,尝试按下一个不同的按键。如果原本不变的部分有一部分发生了改变,表示这一系统的加密方式是直接在发送码字中嵌入滚动码;否则就是整个指令部分与滚动码进行了运算。直观表示是这样:

嵌入滚动码的方式:(数据是编的,只是做一个例子)

操作 帧头 指令 滚动码 帧尾
开门 0xac 0x2d 0x12345 0xff
开门 0xac 0x2d 0x6789a 0xff
开门 0xac 0x2d 0x13579 0xff
关门 0xac 0x1c 0x2468a 0xff

可以看到连续按3次开门,帧头和指令部分是不变的。但是按下关门的时候,指令部分变了,所以可以判定大概率是嵌入滚动码的方式。当然帧不一定按照这个格式,可能存在多于一处滚动码,顺序也不一定是这样,但是基本思路不变。如果是全部加密的方式,那么每次只有帧头和帧尾不变,无论使用什么指令都是这样。

针对普通信号的重放

这一部分就不需要再多解释了,录制了什么信号再发出去就行了,无论用什么方式都可以。可以使用这个流图:

针对跳频/多频段信号的重放

这一部分稍微有一点麻烦。首先需要确定的是,信号是否真的是ASK调制方式?因为我真的见过把ASK的跳频和FSK弄混的……不要光看瀑布图,真正录制一个信号看看波形。

其次需要确定的是,信号是在几个频率间切换,每次只有一个中心频率在发射,还是多个中心频率一起发射?这个录制一段瀑布图放大了仔细看就行。注意确保录制的时候采样率高一些。

如果是切换频率,那么有一种最简单的解决方法:把发射的能量调大,可以使用射频放大器,取消最后的滤波,努力让发射的信号在几个接受频段上都能收到。因为几个中心频率不会离得太原,一般最多几十到几百kHz,自己做一个放大器是可以覆盖到这个范围的。虽然理论上法律允许一个设备同时在相隔很远的频段上工作(例如同时在315和433频段上),但是我还没有见过谁这么干……

如果实在无法覆盖,或者在几个频段上同时发射不同的信号(同时发射同样的信号不叫多频段,一般只是射频部分没调好),就需要多通道同时发射了。我用的LimeSDR是非耦合双通道全双工,允许两个发射通道两个接收通道完全独立工作,这表示它能够同时在两个中心频率发射信号。或者如果你买了多个更便宜的设备(比如两个HackRF或者Yard Stick One),也是一样可以用的。我记得USRP是4通道全双工,所以也没问题。

针对非滚动码的爆破攻击

首先声明,这一部分的理论我没有测试过(很大一部分原因是我没有理论中描述的系统),资料来自360独角兽的《无线电安全攻防大揭秘》,可能稍微有一点过时。以下的内容是对该书3.3章节的不完全引用以及转述:

针对最常见的8-12位车库门遥控,经过测试发现它使用12位密钥,按下一次按键,相同的信号会发射5次,每个bit用时2ms,每个bit和下一个间隔2ms。那么每次发射需要的时间是

\[12\times (2+2)\times 5=240 ms\]

而破解一个8~12位密钥最多需要发送:

\[\sum_{n=8}^{12} 2^n \times n=88576 bit\]

那么最长需要的时间是:

\[88576\times (2+2)\times 5=1171520 ms\]

毫秒,约等于29分钟。但是因为遥控器发送5次是为了确保能够正确接收,如果发射功率比较大,干扰比较小或者距离比较近的情况下可以不用发射5次,那么传输时间变成了:

\[88576\times (2+2)=354304 ms\]

约等于6分钟。而Samy Kamkar(就是那个Samy Kamkar,无线安全方面的大佬,也涉及硬件,近源和其他方向)在自己的测试中发现,如果取消每一bit之间的2ms等待,接收机依然可以完成。其实这里我并不明白为什么去掉等待时间依然可以执行,我没有找到Samy Kamkar原始的实验记录,唯一一种合理的解释就是接收机的采样率其实比较高,在时钟恢复阶段(实验中的设备采用ASK调制PWM的形式,不是传统的OOK)使用的恢复方法并不一定恢复成固定频率的时钟,而是可以变成原来的两倍,相当于传输加快了两倍;或者内部对于等待时间不作判定,只检测跳变沿而且检测很敏感,才允许去掉等待时间。这种方法应该不是对于全部设备都适用。此时时间变成了:

\[88576\times 2=117152 ms\]

约等于3分钟。但是这还不是最低。低成本的系统中,因为每一次完整接收一个帧,判定是否是需要的帧,决定是否丢弃,再检测指令这样常规的帧传输方式成本比较高,而采用了更简单的办法,即纯数字电路实现。接收到的信号经过常规的硬件非相干解调和二进制检测,被送进移位寄存器,而移位寄存器和比较器连接。当所有的比较器输出全部为真时,确定开门。那么这样的实现方式允许攻击者不每次发送一个完整的帧,而是通过特殊的编码形式,对发送的数据进行编码,遍历所有的可能。将所有的可能制成有向连接图,那么图的汉密尔顿路径就是我们需要的序列。这一序列由De Bruijn发现并提出,所以称为De Bruijn序列(德布鲁因序列)。它的特点是,所有长度为n的序列都是它的子序列,而且互不重复(每个这样的子序列只在De Bruijn序列中出现一次)。这一序列的构建涉及组合数学和图论的知识,比较复杂,不在此详述(其实是因为我忘的差不多了)。它有一个性质就是,针对n阶的De Bruijn序列长度为\(k^n\),其中k是字符表内的个数。在二进制序列中,k是2。那么发送量被降低到:

\[2^12+11=4107 bits\]

所以发送时间减少到:

\[4107\times 2=8214 ms\]

只有8秒左右的时间。这已经是可能的最低的用时了。

针对滚动码的攻击

在两种滚动码之中,无需物理接触遥控器就可能攻击成功的只有嵌入滚动码的形式。对于全部加密的信号,最常见的是将滚动码与指令部分直接异或,一方面容易解码,另一方面对硬件的要求也比较低。但是此时因为我们不知道滚动码,就完全无法分析,也无法修改指令。此时只能从硬件上下手,通过逆向硬件的方式来获取滚动码和指令码。而对于嵌入滚动码的信号,最通用的攻击手段是Samy Kamkar发明的RollJam方案。

关于这个方案还有一个有趣的事,就是我有一次在分析对称加密和非对称加密的中间人攻击的时候,想到了这个方法,还利用LimeSDR成功进行了一次攻击。但是我的方法需要我手动查看捕获的信号,手动发射。在尝试利用流图把整个过程自动化的时候遇到了障碍,上网一搜才知道Samy Kamkar已经实现了一样的方法,而且是用CC1101模块自动实现的。下面介绍RollJam的基本方法,如果以后有时间并且我也没鸽的话,我可以写一个基于CC1101和WHID Injector的项目,移植这一功能,因为WHID Injector有SIM和WiFi模块,还能直接接电池,能够有更多样的控制方法。

RollJam的思路其实很简单,想象一个司机在停车场下车准备锁车的场景。如果此时我用一台设备干扰他的锁车信号,并且用另外一台设备记录这一信号,那么我将获得一个信号A,此时信号A汽车没有收到,滚动码依然有效,而车也没有锁上;此时司机发现车没有锁上,很自然的举动将是再按一次,尝试锁车,此时我继续干扰这个信号,并且记录下来,获得信号B。但这次不同的是,我同时发送信号A,车会收到A而锁上,司机认为锁车成功会离开,而信号B内滚动码依然有效。此时可以修改B内的指令,让车再解锁。

RollJam技术细节实现

上文讲的RollJam,在我的实际测试中有一些技术细节需要注意。

首先是如何在干扰信号的同时接收并记录信号。Samy Kamkar的思路是,将干扰信号设定在稍微不同于真实信号的频率上,但是落在汽车接收器的Filter范围内。这样对于汽车仍然能起到干扰作用。而自己在接收的时候用更窄的Filter,避开干扰信号的频率范围。而我自己一开始使用的思路略微不同,因为我用的是LimeSDR发射干扰信号,所以我选择让接收到的信号针对噪声做一个滤波,因为噪声的参数是已知的,就可以顺利去除,分离出真实信号。

其次是如何在司机发射B信号的时候,一方面干扰B信号,另一方面发射A信号,还要记录B信号。我没有查到Samy Kamkar是怎么实现的,但我采用的方案是错开时间,在信号B结束之后立刻停止干扰,同时立刻发射A信号。这一过程时间极短,一般情况下察觉不到。因为干扰信号的功率比较大,不止很大地降低了汽车接收的信噪比,还过载了汽车的射频前端,就像用强光照射摄像头,摄像头的感光元件达到阈值,无论其他条件再怎么改变都不会正常工作,所以必须停止干扰信号才能让汽车接收到。

还有如何修改信号。这一部分根据不同型号的设备而定,一般是通过反复实验找到规律,网上有不少这方面的实战教程,可以参考。

针对双向验证信号的攻击

很遗憾,这种信号目前没有可行的攻击手段。可以理解为在一个加密系统中,需要双向认证,密钥分发已经完成,此时中间人攻击对系统基本没有影响。而在RollJam中之所以能够成功,是因为设计者没有完全用分发的密钥加密全部信息,否则就和全加密滚动码一样,基本没有办法。而对于双向验证的信号,除非系统有明显设计漏洞(比如汽车发送的东西始终不变),否则目前没有有效攻击手段。