(U) Sniffing Proprietary 2.4GHz Signals

使用HackRF或者RTL-SDR加变频器,那是极好的,但是我最终需要把所有东西都打包到一个小空间里面。

可参考另一个页面:Travis Goodspeed, 作者不仅嗅探了类似的键盘(Microsoft Comfort Desktop 5000), 还演示了怎么样用他的一个叫GoodFET的设备和python的脚本goodfet.nrf让 nRF24L01+ 芯片嗅探 2.4GHz 的数据.

GoodFET and nRF24L01+

Travis发现嗅探该设备存在多个难点,不仅现在需要指定频道(频率),而且还需要指定MAC地址。nRF芯片只提供发送到指定MAC地址的数据包。此外,nRF芯片不会发送MAC地址数据,因为你已经指定了 (在RX_ADDR_P[0-5]6个管道中的一个)。

Travis发现在指定MAC长度的时候,在手册中为SETUP_AW,当设置为‘0’的时候被认为是非法的, 

'00' - Illegal 
'01' - 3 bytes
'10' - 4 bytes 
'11' – 5 bytes

但是实际设置MAC地址为两个字节,并且把MAC设置在preamble的位置(0x00AA or 0x0055, in binary 0000000010101010 or 0000000001010101), 就能欺骗设备在数据部分首先提供完整的MAC地址给我们,请参考这篇碉堡了的文章学习具体细节。

Microsoft USB Dongle


(U) Increasing Speed and Portability

    虽然现在我们可以使用GoodFET,电脑加nRF24L01+来做嗅探测试,但是最终我们还是希望能够用一套便宜的嵌入式设备来实现此功能。我们可以使用Travis的研究成果,使用在微控制器+嵌入式C程序来实现所有功能。

另外,我们做了一些改进。 Goodfet.nrf 告诉我们怎样扫描我们想要监听的设备:

  • 频率从 2400MHz开始
  • 设置数据速率为 1Mbps 以及MAC为0x00AA,监听10秒钟
  • 设置数据速率为 2Mbps 以及MAC为0x00AA,监听10秒钟
  • 设置数据速率为 1Mbps 以及MAC为0x0055,监听10秒钟
  • 设置数据速率为 2Mbps 以及MAC为0x0055,监听10秒钟
  • 逐步增加频率值,直到2528MHz再返回从2400MHz开始循环 (128个频率值)
  • 要找到一个潜在的键盘设备,我们需要至少四个包,以满足阈值确保是个合法的数据包,防止误报。

    这意味着扫描一个完整的频率范围需要大约85分钟,(and at least several keystrokes must be pressed while we're sniffing within the correct 10 second period. ) 在仔细学习了Travis的研究,KeyKeriki 的项目,以及测试了我的键盘,我们可以做一些改进:

  • 查阅 FCC,键盘只需要用到 2403 - 2480MHz的范围,直接从128个频率减少到了78个频率 (节省40%)
  • 所有键盘使用2Mbps,又减少一半时间。
  • 在检查了很多键盘之后,我发现所有的微软键盘的MAC地址都是以0xCD开始的,因此我们的preamble永远是0xAA (10101010) , after inspecting more keyboards, I found that all Microsoft keyboards begin with 0xCD as the MAC, which tells us that our preamble will always be 0xAA (10101010) 因为0xAA后面永远跟的是1 (0xCD 二进制 11001101)以保持比特位交替,这样又加快了一倍的搜索速度。
  • 因为我们知道MAC地址的第一位 (0xCD), 我们也知道需要什么样的数据包, 我们只需要检查某个确认的数据包,就能知道这是一个我们要找的键盘设备。
  • 我们把每个频率扫描时间降低到500毫秒,从而把整个扫描一轮的时间降低到40秒。

(U) Decrypting Keystrokes

    Thorsten Schröder 和 Max Moser 设计了一个碉堡了的东东 KeyKeriki, 能够监听微软键盘,完全逆向了解密的过程并且做了个设备能够完全实现这些。然而,他们的设备需要两个无线电和一个高端微处理器,来捕获和解析以2Mbps通信的键盘设备产生的数据。Travis的项目虽然牛逼,但是需要一台电脑主机,而且对于我们秘密执行任务,这套设备还是太大了,因此我们改进了设计,现在只需要一个廉价无线电和一个微处理器,功耗低而且体积小,不再需要电脑和其他无线电设备。

    Thorsten 和 Max 发现这个击键只是使用ECB模式简单的和MAC地址异或加密 , 我们可以使用Travis的方法利用nRF24L01+来嗅探和获取MAC地址,这种加密方法相当于只是把扑克牌切了一次。

经过进一步调查发现,我们现在知道所有微软键盘的MAC地址都是以0xCD开始的,实际按键(下图橙色部分)恰好与MAC地址第一个字节对齐,这就是说即使我们不知道完整的MAC地址,我们依然能够解密按键消息,因为这个对齐是不会变的,MAC地址开头一个字节0xCD也是不变的。

由于数据包加密部分的长度是11个字节,而MAC地址占5个字节,CRC校验是每个字节做,异或(加密前),你会发现一些有意思的事情,由于MAC地址被异或了两次,我们能够在不需要知道完整MAC地址的情况下计算校验值,这是因为MAC被异或两次,就相当于什么都没做,而第11个字节又是MAC地址的第一个字节,我们知道是0xCD。根据这个特性我们可以进行一些其他的攻击,比如更改按键和CRC校验,同样不需要知道MAC地址,这将会在我以后的项目做相关演示。

 KeyKeriki 项目中的一页演示了解密过程:

http://samy.pl/keysweeper/decrypt.png

  • Device type 0x0A = keyboard, 0x08 = mouse
  • Packet type 0x78 = keystroke, 0x38 = idle (key is held down)
  • Model type 0x06 = keyboard? This is the same HID code for a keyboard
  • HID code 0x05 = letter 'b' (described in section 7 here)

KeySweeper的解密部分代码:

// decrypt those keyboard packets! 
void decrypt(uint8_t* pkt)
{
    // our encryption key is the 5-byte MAC address and
    // starts 4 bytes in (4-byte header is unencrypted)
     for (int i = 4; i < 15; i++)
        pkt[i] ^= mac >> (((i - 4) % 5) * 8) & 0xFF;
}
原文:KeySweeper