查看原文
其他

动手拆解众筹明星产品安全智能锁KeyWe后,发现它不安全且无解

F-Secure 代码卫士 2022-04-06
 聚焦源代码安全,网罗国内外最新资讯!
编译:奇安信代码卫士团队
在智能设备时代,越来越多的工具“变得”智能。KeyWe Smart Lock 也不例外。为了让生活更方便,它融合了机械锁机制和其它功能,包括但不仅限于生成一次性 guest 代码以及根据距离打开房门。然而,便利性总是以牺牲安全性为代价。

设备概览

KeyWe 智能锁的重要组成部分如下:
  • 正面板:用于和锁进行交互

  • 机械锁:软件和独立锁均需使用

  • 背面板:用于提供电源并移动锁的机械部分

这两个面板(正面板和背面板)均联网,如果有人尝试断网则会触发警报。
打开锁的方法如下:
  • 通过钥匙以机械方式开锁

  • 使用应用程序(无需其它认证)开锁

  • 使用腕带开锁(NFCMifareClassic)

智能锁硬件

卸下电路板,肉眼可以清晰获知(无需识别组件)每个电路板的作用。
 

(KeyWe 的多个电路板)

(KeyWe 电路板背面)
前面的电路板仅用来处理用户输入(数字键盘和RFID 芯片)。而后面的电路板用于处理所有的应用程序逻辑,它无法被攻击者访问。
串行和 JTAG访问尝试均无果。不过组件标识表明该智能锁使用了 STM 微控制器。在其中一个端口上,似乎启用了被暴露的 SWIM(Single-Wire Interface Module,单总线接口模块,用于 STM uC 中的调试协议)。焊接到引脚并使用 ST-LINK 适配器后,可以丢弃设备固件。
从电路板所识别的组件(尽管不完整)如下:
 

调查桥接设备

桥接设备的作用是通过 WiFi 暴露经由蓝牙低功耗处理的锁。尽管外部构造相当复杂,但内部装的是基于 ESP32 的电路板。该电路板最有趣的部分在于其白板上的引脚。
 


 
通过万能表和引脚图,我们识别出了大多数引脚:
 


 
尽管 ESP 已经相当成熟,比如已经具有读取保护、加密等措施,但桥接设备尚不具备这些功能。串行和 JTAG 访问被启用而且并未应用加密。这些均可通过如下输出得到证实:
$ espefuse -p /dev/ttyACM0 summaryespefuse.py v2.5.1Connecting....Security fuses:FLASH_CRYPT_CNT Flash encryption mode counter = 0 R/W (0x0)FLASH_CRYPT_CONFIG Flash encryption config (key tweak bits) = 0 R/W (0x0)[...]JTAG_DISABLE Disable JTAG = 0 R/W (0x0)[...]Efuse fuses:WR_DIS Efuse write disable mask = 0 R/W (0x0)RD_DIS Efuse read disablemask = 0 R/W (0x0)

鉴于访问该固件非常容易,因此在分析过程中并未关注桥接设备。

蓝牙低功耗

我们再上一个台阶,转入通信和应用层。基于公开可获得的材料以及智能锁随附的包装,我们了解到 KeyWe 智能锁使用了“Bluetooth Smart”,其实就是BLE/BTLE(蓝牙低功耗)的另外一种说法。
BLE 最便捷的工具很可能是 Nordic 半导体公司生产的 Nrf Connect(当然这只是个人之见)。我们先来回顾下蓝牙低功耗的一些基本概念:
不同于我们已经知道而且可能每天都在用的技术 Bluetooth Classic,BLE在可发现性(即可发现设备)的概念上并不起作用。每台设备(即外围设备)都会向距离足够近的人群发送信息(即广告)。广告内容包含该外围设备的信息:名称、地址(用于建立连接)、特征等。这类设备公开了分组实体列表(即服务)。包含特色 (characteristics) 的设备可以包含某些值(文本、数字等)或可被读取(读取权限)、被更新(写入权限)或可通知其它联网方值已更改(通知权限)。
KeyWe 智能锁暴露了一台具有两种特色的设备:一个是读取权限,一个是通知权限。
 


我们已经可以假设这些特色用于向锁发送/接受来自锁的信息。话虽如此,但只有一种方式可以验证这一点:检查移动应用程序。个人出于自身偏好选择的是安卓应用程序。

攻破软件

搜索 BLE相关函数后,我们看到了DoorLockNdk 类,它包含多个方法。NDK 即原生开发包,是桥接原生(编译、未管理)代码和 Java (通过 Java Native Interface, JNI)的一种方法。
此前提到的方法中,每种都返回一个字节数组,这说明我们找到了一座金矿。更具体地说,如果我们能通过某种方式拦截了这些信息,那么它将毫无用处;每条信息在发送前都通过 AES-128 进行了加密。然而,我们可以通过访问 DoorLockNdk 类(具体而言是指它的方法)在加密前拦截信息。也就是说可以分析通信协议。但是我们该如何拦截函数调用呢?答案很简单,通过 Frida 即可。跳过此处的技术知识,我们创建的函数转储参数并返回值。该代码的 GitHub 地址为:https://github.com/FSecureLABS/keywe-tooling
该智能锁和移动应用程序之间交换的信息(基于通过 Frida 获取的信息)日志如下:
 

这里值得一提的函数是 makeCommonKey、makeAppKey 和 makeDoorKey。这些函数或者在应用程序内或者在智能锁上被调用,但不会直接生成所发送的信息。
尽管我们将跳过确切的思考过程,但应该指出的是,函数 makeAppNumber 和 makeDoorNumber 用于生成供两方交换的值。它就是一种简单的“密钥交换”协议:每方均生成一个值,将其发送给另一方,而且一旦收到另外一个“数字”,就可以计算密钥对。其中一个密钥用于加密/解密来自智能锁的信息 (makeDoorKey),而另外一个密钥用于移动设备 (makeAppKey)。所有的这些数字在发送前都通过共用密钥进行加密。
下表是一些示例性makeCommonKey 调用结果(共用密钥值)列表:


(“执行ID”是指既定设备的执行状态如第一次执行、第二次执行等)
可见,共用密钥并不会在执行期间发生改变,但确实会随着设备地址的变化而变化。
这是一个严重错误!由于使用内部密钥交换(仅涉及两个值)来解密所有的通信,我们只需要拦截传输即可。之后可以基于设备地址轻松计算出共有密钥。
之前提到的仓库中也涵盖了计算这些密钥的代码。
至此,我们找到了打开王国的钥匙!
该漏洞的相关技术公告已发布:
https://labs.f-secure.com/advisories/keywe-smart-lock-unauthorized-access-traffic-interception

嗅探流量

在破解过程中还有一个未解之谜:我们如何才能真正获取智能锁和移动应用之间交换的信息呢?常规的应用程序/适配器并不具备这个功能。好在我们还可使用硬件和固件。为了嗅探BLE流量,我们可以使用Nrf Sniffer。通过 Waveshare BLE400 或 USB Armory Mk II 等电路板,我们就可以收集 LE 数据,只需安装一个插件运行 Wireshark 就可办到。

厂商回应

KeyWe已证实该问题存在并且正在着手修复。F-Secure 发布该问题后,厂商就积极地进行沟通。遗憾的是,目前尚未涵盖固件更新功能,因此只有替换该设备才能修复问题。厂商指出将在新设备中包含安全修复方案。此外,KeyWe 智能锁的下一个版本将具备智能更新功能,尽管发布日期尚不明朗。

结论

我们不能因此认为KeyWe 智能锁未将安全问题考虑进去。它所使用的 AES 算法实际上是事实上的加密标准。但是所使用的协议可被称为内部加密,而且正如该行业多年所证明的那样,它无法善终。另外,该厂商似乎对于威胁模型的理解很模糊。如果开发人员/架构师能够注意到设备地址可被暴露给智能锁附近的人员,则不会出现这种问题。
智能物联网设备厂商应该从中得到的经验教训是:
  • 理解自己的威胁模型。

  • 不要开发或衍生内部加密。

  • 了解(并测试)你的工具,从而节省大量时间。

  • 深入分析看似安全的设备,以便最终学会查看数据模式。



推荐阅读

确认过眼神,遇到免费易用的固件安全检测工具

Intel 警告:BMC 固件存在严重漏洞,影响大量机器

热门WiFi 芯片固件 ThreadX 中被曝多个漏洞



原文链接
https://labs.f-secure.com/blog/digital-lockpicking-stealing-keys-to-the-kingdom



题图:Pixabay License

文内图:F-Secure


本文由奇安信代码卫士编译,不代表奇安信观点,转载请注明“转自奇安信代码卫士 www.codesafe.cn”



奇安信代码卫士 (codesafe)

国内首个专注于软件开发安全的产品线。



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存