趣幕网

某款大*无人机ID和飞行状态无线基带信号破解提取和伪造方法初步研究

小编

研究背景:

   在读一篇《Drone Security and the Mysterious Case of DJI’s DroneID》的文章时,作者通过了逆向firmware和软件无线电SDR捕捉大*若干款无人机的通信信号来找到了如何破解和逆向出无人机的通信ID和飞行数据等信息。 所以本人就在想如果能既然能逆向提取出这些信息,那么是不是可以采用正向工程,将这些信息通过SDR等设备再发出去,用SDR的发射信号来伪造一个飞行状态中的无人机呢。

  要达到这个目的,需要对于原作者的方案进行逆向思考才行。下面逐步展开我这边的思路和实施方式。


研究基础:如果手里已经有了SDR采集到的无人机发射的信号文件一份,那么信号的基本处理方式如下:

1000007610.png

到这里已经是可以解码出经过信道编码的bit流了,再通过如下的Turbo解码操作,就可以恢复最原始的无人机ID等信息payload。 基本流程图如下:

1000007611.png

对于Turbo解码,是仿照LTE的Turbo解码算法做的,也就是说大*此系列无人机的不少编码特性是照搬了3GPP LTE规范的,而3GPP LTE规范是公开的,理论上来说就可以实现任意信息的伪造了。

但是由于Turbo编码这一块儿目前我还没有完全参透,故而完成一款完全从最顶层到最底层的设计还有些难度。 故而本次实验仅采用一种特定的伪造,就是分身的方式进行伪造的研究。基本的思路就是将蓝色的流程图部分倒过来。思路如下:

1000007612.png

具体实践要点:

    挑战1: 如何得到原始的Turbo编码码流

根据外文文献提供的线索需要对于,一个基本的有效信息帧由如下几个部分构成, 10个slot,10ms,和LTE的帧结构类似,其中9个slot有信息,最后一个是保护间隔slot,其中第4和第6个slot是ZC序列的同步slot。

1000007613.png

那么在提取的时候就要通过第4和6slot的已知信息来进行各种同步和频率相位校正。 我们最终的目标就是经过一系列的信号处理,能最终得到QPSK 的调制信息,从而得到Demodulate Bitstream。

1000007614.png

具体实践如下,如下是一份某款无人机采样数据信息:

采样文件,时域波形, 采样率50Msps

1000007615.png

功率谱如下,红圈中圈起的是疑似有用信息帧的位置

1000007616.png

为了分析逐个帧的,需要对这三个帧进行逐个分析,那么首先就要进行粗略切割:对信号进行短时傅里叶变换,以得到不同时刻的信号频谱变动情况,执行如下函数:signal.stft(input_sig, sample_rate, nfft=64, nperseg=64) 结果写入 2.after_stft_time_vs_freq.xlsx画图分析:可以看到不同频率分量在不同时间点上的功率分布总的趋势相同,但是局部还是不同的。

1000007617.png

下面求取不同时间点上最大能量所在的频率分量和时间的关系,蓝色为频率,橘色为对应最大能量值

1000007618.png

看上去毛刺很多,下面我们设定一个特定的Noise Level , 把能量低于noiseLevel的部分都设值为零。生成数据4.engery_above_level.xlsx过滤后的图和数据如下:

1000007619.png

根据数据帧的时间长度转换为对应的采样点数,得到一个范围,需要在这个采样值范围内的能量都要大于noiseLevel。采用 signal.find_peaks,来寻找满足这个条件的一系列的点:

peaks, properties = signal.find_peaks(above_level, width=[signal_length_min_samples, signal_length_max_samples],wlen=100*signal_length_max_samples)

1000007620.png

然后采用left_bases 和 right_bases 前后各加入一个start_offset和 end_offset进行粗略切割。切割后的三段数据分别为:

6.packets_data_after_peak_slicing_0.csv6. packets_data_after_peak_slicing_1.csv6.packets_data_after_peak_slicing_2.csv对应的频谱分别如下:

1000007621.png

可以看出3段切出的频谱左右都留出了足够余量,没有损失信息。这为后续继续其他分析奠定了基础。下面来逐个对这三段信号进行精细化处理,在此我只对其中最后一组包含了droneID数据的信号进行细致分析。下面执行 signal.welch 来对信号进行功率谱密度PSD分析,用于进行有用信号开始位置的粗略估计。

nfft_welch = 2048signal.welch(  y, Fs, nfft=nfft_welch, return_onesided=False)再执行fftshift将负频率移动到左边,让f=0在中间,以便于分析   

Pxx_den = np.fft.fftshift(Pxx_den)    f = np.fft.fftshift(f) 生成 7.packets_data_after_peak_slicing_2_1_after_welch.xlsx

1000007622.png

添加一个假的中间直流DC载波(从2048//2-10 = 1014 到 1034, 共20个采样点) 设置为1.1倍的功率均值,模拟DC上载波泄露干扰能量),  

  # add a fake DC carrier    Pxx_den[nfft_welch//2-2:nfft_welch//2+2] = 1.1*Pxx_den.mean()  #采用添加4个采样点也是OK的如下所示: 7.packets_data_after_peak_slicing_2_3_after_add_fakeDC

1000007623.png

在这里假设有用信号的带宽是10MHz(从上图可以看出,信号宽度大概是10MHz)  , fft 是2048, SCS =15kHz , 有用带宽2048*15kHz = 30.72Mhz, 半带宽是15.36MHz,这是20MHz带宽LTE的典型采样参数。 本文件是50MHz采样频率,故而50/15.36 约等于4个采样点。,将来重采样15.36Ms之后,就可以大概等于1个点了(一个子载波)。  找出超出平均值并且宽度足够宽的部分,也就是上图中的有用信号部分,得到她的偏移量candIDAte_bands = consecutive(np.where(Pxx_den > Pxx_den.mean())[0]) 得到数据:6. packets_data_after_peak_slicing_2_5_offset_caluclation_band_0

1000007624.png