攻破物理隔离网的无线方法 (4)– 使用USB传输线发射射频信号

  这个工作是Guri的USBee项目,通过控制传输在USB线上的数据来刺激USB数据线发出指定频率的电磁泄漏,可以通过SDR设备接收,在Guri的演示里,用到的是一个RTL-SDR在GNU Radio平台上进行的测试(在演示视频里我看到的好像是SDRSharp软件?)。根据这个工作文章里的说明,这种调制方式发送数据的速率可以在20到80bps。亮点是无需任何硬件上的改动,任何支持USB2.0协议的设备都可以通过软件的形式来调制。
Guri的演示视频

USB背景

  USB(Universal Serial Bus)全称通用串口总线。USB协议版本有USB1.0、USB1.1、USB2.0、USB3.1等,USB2.0目前比较常用。USB的内部构造非常简单,只有4根总线:

上图为USB接口的结构,包括VBUS、D+、D-和GND四根线。VBUS是电源线,使用红或者橘色线;GND是接地线,使用黑或者蓝色线。D+和D-是用来传输数据的,通过差分数据的方式进行传输。USB协议对传输数据使用NRZI编码方式进行编码,简单地说可以认为,对于二进制数据,遇到一个‘1’时,电压状态不变;遇到一个‘0’时,电压状态反转。(在NRZI编码中,只有正负电平两种状态)
另外,在USB协议中,使用J和K来标识高低电平。
J状态(高电平):D+ 高,D- 低
K状态(低电平):D+低,D- 高
由于USB协议没有同步机制,因此当出现连续的‘1’时,对采样的控制容易出现误差,因此USB协议设置了位填充机制来保证发送的数据流有足够多的电平变化。填充的对象是输入数据,即先填充再编码 。
数据流中每6个连续的“1”,就要插入1个“0”,从而保证编码数据出现电平变化。
接收方赋值解码NRZI码流,然后识别出填充位,并丢弃它们。这个知识点对下面估计一个数据包的传输时间有用。

USB协议版本之间的传输速率不同:

• USB1.0(以及USB1.1)1.5Mbits/s ~ 12Mbits/s
• USB2.0 480Mbits/s
• USB3.0 5Gbits/s
在USB2.0协议下,传输一个数据包的总时长估算公式:

T = (55 * 8 * 2.083) + (2.083 * floor(3.16 + BitstuffTime(DataLengh))) + HostDelay

其中,DataLength是数据的字节长度。BitstuffTime是一个函数,用来计算当传输DataLength字节的数据时,最坏情况下需要的时间,它的返回结果为当传输数据全为‘1’时的时长乘上7/6。HostDelay是USB固件处理事务所需要的时间。
当数据在USB数据线上传输时,不同的数据会对数据线的工作状态产生不同的影响。其影响的方式主要是依赖于电压变化,这里再次搬出静态能量消耗和动态能量消耗的概念:

0 -> 0 静态
0 -> 1 静态+动态
1 -> 0 静态+动态
1 -> 1 静态

控制流动在USB总线上的数据发射频信号

  Guri的调制方式是通过传输特定序列的‘0’,来控制USB上D+和D-总线发生电压反转,从而产生影响较大的动态能量消耗,进而控制了USB总线发射出指定频率的电磁泄漏,与周围2-8米内的接收设备进行隐蔽通信。在Guri给出的伪代码中,通过填充一个缓冲区,然后将缓冲区的数据写入在通过USB接口连接的设备里,可以是U盘、移动硬盘等等。

上图是Guri给出的伪代码。该算法能够生成使得USB接口发出指定频率电磁泄露的定制二进制数据。其中,buf为数据缓冲区,用来记录生成的二进制数据。size为设置的缓冲区长度,可以设置生成的数据长度。freq为要刺激出的电磁泄露的频率,单位是kHz。
我在复现的时候是通过上面的伪代码生成要填充的数据,即设定要发送的电磁泄漏频率,然后在移动硬盘里fopen一个文件,将缓冲区数据写入移动硬盘的文件里。通过不断地生成写入过程,最终做到控制USB总线发出指定的电磁泄漏。不过在复现的时候观测到的不清楚是否是对应的电磁泄漏,因此对这个方式不是十分确定。(有机会的话想用高级的设备测试测试…)
按照理论推理,我认为这种方式打出的电磁泄漏,频率范围应该是小于480MHz。有机会做一次极限频率的测试。

接收信号

  Guri采用的BFSK调制,通过编码两个频率作为映射‘0’和‘1’的信号来编码信息。按照发送速率对接收信号进行采样并解析。对于采样速率,Guri给出了估计抽样间隔的估计算法:

SR*TOB/4 = FFTsize

其中,SR为采样率,TOB是发送一个bit数据的时间,可以通过前面的传输数据包总时长公式进行估计。FFTsize是对时域信号进行FFT计算的块大小,每一个块对应一个信号。
对拿到的每一块时域信号做FFT分析,计算这段数据对应的编码是0还是1,从而恢复出数据。

上图为Guri给出的测试,发送01110011,0和1对应频谱上两个选定的信道。在接收方接收到了0x73这个数据。

Add a Comment

电子邮件地址不会被公开。 必填项已用*标注