对KeyWe智能锁的一些安全研究

iso60001  291天前

22.jpg

介绍

在万物互联的时代,越来越多的家电都在“变聪明”,门锁也不例外。为了让生活更加方便,智能门锁既有机械机构,又有丰富的网络功能。它可以生成一次性密码,并在你靠近房屋时自动解锁。

然而,便利往往以安全为代价。

设备概述

锁由三个重要部分组成:

  • 前面板:用于与锁进行交互

  • 机械锁扣:既能独立使用又能和网络交互

  • 后面板:用于供电和移动锁的机械部分

两个面板紧密相连,如果有人试图断开,就会响起警报。

智能锁可以通过以下几种方式打开:

  • 使用物理钥匙

  • 使用相对的应用(不需要额外的确认)

  • 使用类似NFC的嵌入式工具

锁硬件

拆下面板,仔细检查每个组件的功能。

33.jpg

44.jpg

前端只用于处理用户的输入(数字键盘和RFID芯片)。而后端处理应用所有的逻辑,攻击者不太可能直接接触到。

串行和JTAG访问(对于后者)没有任何效果。但是,组件标识显示了一个STM微控制器。在其中一个被暴露的SWIM(单线接口模块)端口上,STM uCs中使用的调试协议似乎是启用状态。在焊接到引脚并使用ST-LINK适配器后,就有可能转储设备固件。

虽然不完整,但在面板上确定的组件清单如下:

55.png

调查bridge

bridge装置和(通过蓝牙或WiFi控制)锁有关。该装置看起来相当复杂,内部拥有一个基于ESP32的电路板。不过重点在位于白色面板上的针脚。

66.jpg

经过一段时间的摸索,我们识别出大多数的针脚:

77.jpg

尽管ESP已经相当成熟——具有读保护、加密等功能——但bridge并没有使用这些功能。串行和JTAG访问都是可用的,且无数据加密。我们可以通过下面的输出来确认:

$ espefuse -p /dev/ttyACM0 summary
espefuse.py v2.5.1
Connecting....
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)

考虑到固件轻易就被访问到,我们在bridge上就没有花费过多精力。

低功耗蓝牙(BLE)

现在让我们更深入一点,进入通信和应用层。根据公开的资料,以及锁的包装,我们知道它使用了“智能蓝牙”。

对于BLE研究最方便的工具可能是Nordic SemiconductorsnRF Connect。在我们继续之前,先来回顾一下BLE的一些基本概念:

与经典的蓝牙技术(很可能每天都在使用)相反,BLE并不会去发现周围设备,而是每台设备(被称为外围设备)向任何接近它们的人发送消息(被称为广播)。这些广播包括关于外围设备的大量信息:它的名称、地址(用于建立连接)、功能等等。这样的设备还会公开一组被称为服务的实体列表,包含某些特殊的标识(字符或数字),代表读访问、写访问或通知功能。

而KeyWe智能锁暴露了一个具有两个特征的服务:一个读功能和一个通知功能。

88.png

此时我们猜测可以向锁发送消息或接收来自锁的消息,而有一种方法可以验证这一点:检查移动应用。由于个人喜好,这里我们将讨论Android应用。

研究软件

在搜索与BLE相关的函数时,我们偶然发现了包含多个方法的DoorLockNdk类。顺便一提,NDK代表原生开发工具包,是一种将原生(已编译、非托管的)代码与Java(使用Java原生接口,JNI)关联起来的方法。

前面提到的多个方法都会返回一个字节数组。就算我们能以某种方式截获这些信息,用处也不大,因为每条消息在发送之前都用AES-128进行了加密。但是,通过访问DoorLockNdk类(特别是它的方法),我们可以在加密之前拦截这些消息,帮助我们分析通信协议。那么,我们如何拦截函数调用呢?答案很简单,使用Frida!跳过大量的技术细节(可以在这里阅读相关技术信息),总之,我们创建了转储参数和返回值的函数。具体代码可以在GitHub中找到。

基于使用Frida获得的信息,锁和移动应用之间交换的消息记录如下:

99.png

100.png

值得一提的功能还有:makeCommonKeymakeAppKeymakeDoorKey。在应用和锁中都能调用,但并不会直接发送消息。

函数makeAppNumbermakeDoorNumber用于生成两边互换的值,这就像是简单的密钥交换协议:双方生成一个值,互换,计算出密钥对。一个用来加密和解密锁的消息,另一个用来加密和解密应用的消息。而在这一切之前,消息都通过“公共密钥”进行了加密。

我们可以通过makeCommonKey找到“公共密钥”。

110.png

exec.ID是和某个设备绑定的,代表某个执行流程。

正如我们所看到的,公共密钥在执行期间不会改变,但是它会随着设备地址而改变。

因此,我们可以根据设备地址轻松地计算出“公共密钥”,最后破解出应用和锁之间的通信。

相关计算密钥的代码可以在这里找到。

而有关于这一漏洞的更详细的描述可以在这里找到。

嗅探

我们还有一个难题,如何获得锁和移动应用之间交换的数据?常规应用/适配器并没有这样的功能。幸运的是,我们有硬件和固件,可以成功得到流量。为了嗅探BLE的流量,可以使用这nRF Sniffer。而使用Waveshare BLE400或USB Armory Mk II(因为它有一个基于nrf的蓝牙SoC)之类的电路板,收集数据就像运行Wireshark一样简单,只需要安装一个插件。

厂商的响应

厂商已经确认了这个漏洞,并正在修复它。自F-Secure上报这一漏洞以来,他们一直积极参与沟通。不幸的是,由于没有固件升级功能,因此这个问题将一直存在于旧设备中。根据厂商的说法,新设备将打上安全补丁。此外,下一个版本的电子锁将有固件升级功能——尽管没有具体的日期。

本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:https://labs.f-secure.com/blog/digital-lockpicking-stealing-keys-to-the-kingdom

最新评论

昵称
邮箱
提交评论